&size(24){&color(tomato){はじめての''C''};}; #contents #br * メモ [#u31ddc87] -重要なのは、標準APIを使用すること、または、ときどきは調査して覚えること -- ↓って標準APIなの? -- ちがうよ char caArray[10][256] = {{ 0, }}; ...; iSetStrArray( (char **)caArray ); int iSetStrArray( char **ppcaArray ) { char (*pcaLocalStr)[256] = { 0, }; pcaLocalStr = ( char(*)[256] )ppcaArray; ...; } * Visual C++ (Visual Stadio) [#wa4011fa] - Ctrl + Shift + N : New : 新規project - Ctrl + Shift + A : Add : source追加 - F7 : build - Alt + F7 : 環境設定 - Alt + 7 : コールスタック(call tree) - F9 : ブレイクポイント設定 - F5 : 実行 ⇔ Shift + F5 : 終了 - F10 : Step over (1行実行) - F11 : Step in (実行func内へ) ⇔ Shift + F11 : Step out (funcから出る) -- ウォッチ : 30, hr : エラーコード30 の意味がわかる * automake [#dd2a70be] - aptitude install automake ** steps [#r667b528] - Makefile.am Makefile.am: bin_PROGRAMS=hello hello_SOURCES=sample.c CFLAGS=-I../Include LDADD= testlib.o testlib2.o LDFLAGS=-L../Lib LDLIBS=-lm [EOF] - autoscan - mv configure.scan configure.ac -- configure.ac 編集 AC_PREREQ(2.61) AC_INIT(hellow, 1.00, BUG-REPORT-ADDRESS) <- ここ編集 AM_INIT_AUTOMAKE([foreign]) <- ここ追加 AC_CONFIG_SRCDIR([xxxxx.c]) AC_CONFIG_HEADER([xxxxx.h]) - automake --add-missing - autoheader - autoconf - aclocal - ./configure - make * Tips [#ydfb673a] *** Makefile [#e9923ee7] .SUFFIXES : .c .o CC = gcc CFLAGS = -g -Wall LIB = -lm BINDIR=bin TRAGET = ${BINDIR}/sample_test OBJS = sample_test.o sample_1.o HEDD = inc/sample.h all : $(TRAGET) $(TRAGET) : $(OBJS) ${CC} -o $(TRAGET) $^ ${LIB} ${OBJS} : ${HEDD} #$(USRDIR)/%.o : $(USRDIR)/%.c $(HEDD) # $(CC) $(CFRAGS) -c $< .c.o: ${CC} $(CFRAGS) -c $< clean : rm -f $(TRAGET)* $(OBJS) *** typedef [#d76f2916] typedef unsigned long uint64; /* 64-bit cpu only */ typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; typedef struct t_ip4h { UB ver; /* Version, Internal Header Length */ UB tos; /* Type of Service */ UH tl; /* Total Length */ UH id; /* Identification */ UH fo; /* Flags, Fragment Offset */ UB ttl; /* Time to Live */ UB prot; /* Protocol Number */ UH hc; /* Header Checksum */ UB sa[4]; /* Source IP Address */ UB da[4]; /* Destination IP Address */ UB rsv[256-20]; // Reserved } T_IP4H; ***main [#x1107cdf] void cp_buf(int *src, int *dst, int len){ int idx; for(idx=0;idx<len;idx++) dst[idx] = src[idx]; } int main(int argc, char *argv[]) { int *pt_a; int a[10] = {10,12,34,56,78,90,71,82,93,101}; pt_a = &a[0]; return 0; } *** 非ゼロのビットを数える(8ビット版) [#w618f81c] int bitcount_uint8(uint8_t x) { x = (x & 0x55) + (x >> 1 & 0x55); x = (x & 0x33) + (x >> 2 & 0x33); x = (x & 0x0F) + (x >> 4 & 0x0F); return x; } *** 非ゼロのビットを数える(32ビット版) [#ce38ebbd] int bitcount_uint32(uint32_t x) { x = (x & 0x55555555) + (x >> 1 & 0x55555555); x = (x & 0x33333333) + (x >> 2 & 0x33333333); x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f); x = (x & 0x00ff00ff) + (x >> 8 & 0x00ff00ff); return (x & 0x0000ffff) + (x >>16 & 0x0000ffff); } *** 非ゼロのビットを数える(32ビット版)改 [#pe2224e6] int bitcount_uint32(uint32_t x) { x = (x & 0x55555555) + (x >> 1 & 0x55555555); x = (x & 0x33333333) + (x >> 2 & 0x33333333); x = (((x >> 4) + x) & 0x0f0f0f0f; x += x >> 8; return (x + (x >> 16)) & 0xff; } *** 右シフト [#fead8f1a] - signedを指定すると算術シフト - unsignedは論理シフト *** ビットシフト演算 [#xfea154a] uint32 length; uint32 num; for(length=0; length<34; length++){ num = 1<<length; printf("0x%x, %d, \n", num, length) } で、ラストで 1<<32 をしてくれるんだと、期待したけど 結果は、 0x1, 32 0x2, 33 だった。そうなのか・・・。0になるんだと思ってた -つ #include <stdio.h> #include <stdint.h> int main() { uint32_t length; uint32_t num; for (length = 0; length < 34; length++) { num = (uint64_t)1 << length; printf("0x%x, %d, \n", num, length); } } % ./a.out 0x1, 0, 0x2, 1, <snip> 0x40000000, 30, 0x80000000, 31, 0x0, 32, 0x0, 33, *関数のポインタ [#decc8dd1] //こんな関数を定義 int Function(int iValue) { return 2 * iValue; } //この関数を指すポインタは、次のように定義できます。 int (*pFunction)(int) = Function; //実はFunction という記述は、関数のアドレスを示すのですが、 //前に & をつけても同じ値となります。つまり上記は次のように書いても同じ事 int (*pFunction)(int) = &Function; //宣言タイプ int (*pFunction)(int); // 関数へのポインタの定義 int Function(int); // 関数のプロトタイプ宣言 //最初の関数へのポインタの定義の仕方 int (*pFunction)(int) という書き方のほかに //次のようにこのポインタ型を typedef にすることもできる typedef int (*PFUNCTION)(int); //次のように、通常の変数のような形で、関数へのポインタを定義することが可能。 PFUNCTION pfunction = Fucntion; - たぶん、↑を知っているか、いないかで話がだいぶ変わるなぁ。めんどくさっ。 **これは?! [#jbb94988] #include <stdio.h> typedef void (*wrapper_point)( int a ); static void wrapper( int a ) { printf("Hello World(%d) !!!\n",a); } void wrapper_init( wrapper_point pointer[1] ) { pointer[0] = wrapper; } //MAIN int main(int argv, char **argc) { wrapper_point p[1]; wrapper_init( p ); p[0]( 123 ); return 0; } で、この出力は? $ cat test.c #include <stdio.h> typedef void (*wrapper_point)(int a); static void wrapper0(int a) { printf("Hello World (%d) !!!\n", a); } static void wrapper1(int a) { printf("Bye World (%d) !!!\n", a); } void wrapper_init(wrapper_point pointer[2]) { pointer[0] = wrapper0; pointer[1] = wrapper1; } int main(int argv, char **argc) { wrapper_point p[2]; wrapper_init(p); int i; for (i = 0; i < 2; ++i) { p[i](123); } return 0; } $ ./a.out Hello World (123) !!! Bye World (123) !!! めんどーだな。いろいろと * NET [#r997f29c] ** select [#y085bd18] たぶん、使い方について fd_set fdset; FD_ZERO(&fdset); FD_SET( portnum, &fdset); ret=select(); ret2 = FD_ISSET() if(ret2){ } こんな感じ 例 INT32 waitReceive(INT32 sock, UINT32 sec){ INT32 ret; struct timeval timeout; fd_set target; timeout.tv_sec = sec; timeout.tv_usec = 0; FD_ZERO(&target); FD_SET(sock, &target); ret = select(sock+1, &target, NULL, NULL, &timeout); if( ret<=0 ) return 0; if( FD_ISSET(sock, &target) ){ return 1; } FD_CLR(&traget); return 0; } uint32_t iface_idx; iface_idx = if_nametoindex(IPV6_MCAST_INTERFACE); ret = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char*)&iface_idx, sizeof(iface_idx)); * Cast:キャスト [#t0a008ab] -[[Cast:http://www.s34.co.jp/cpptechdoc/article/newcast/]] * スレッド [#v5b01344] -[[スレッド:http://d.hatena.ne.jp/hiroakiuno/20070316/p1]] ** 同期 [#u536125d] -- CriticalSecttion -- mutex -- semaphore --- 特殊なもの: binary semaphore(最大リソースに1を設定) HANDLE h_sem; h_sem = CreateSemaphore(NULL, 1, 1, "semaphore_name"); WaitForSingleObject(h_sem, INFINITE); ... ... ReleaseSemaphore(h_sem, 1, NULL); CloseHandle(h_sem); -- event mutexは遅い. mutexを使うよりもバイナリセマフォの方が早いかもしれない なぜなら、ミューテックスとセマフォの所有権のセマンティックがかなり異なるため 両者を交換可能なものとして使うことはできない。 CriticalSectionが早い。←ただし、プロセス間同期には使えない。 - プロセス -- イメージとしては、別々のプログラム同士で共有リソースを使用する場合 --- たとえば、ハードウェアが1つしかなく、それぞれのプログラムでそれを使用する場合は、排他処理が必要となる。 *** volatile [#ke096bfd] - ポインタの参照先が volatile int *pon - ポインタ自体が int volatile *pon *LINKS [#o8c3d3ce] //#urlbookmark(below) -[[C言語編 トップページ:http://www.geocities.jp/ky_webid/c/index.html]] -- SIZE(10){2010-03-12 (金) 15:29:40} -[[(ポインタと配列) - C言語のメモ日記:http://d.hatena.ne.jp/computermonkey/searchdiary?word=%2A%5B%A5%DD%A5%A4%A5%F3%A5%BF%A4%C8%C7%DB%CE%F3%5D]] -- SIZE(10){2010-02-18 (木) 11:19:17} -[[INT07-C. 数値には符号の有無を明示した文字型のみを使用する:http://www.jpcert.or.jp/sc-rules/c-int07-c.html]] -- SIZE(10){2010-02-17 (水) 11:42:53} -[[標準ライブラリ関数:http://www9.plala.or.jp/sgwr-t/c/sec07.html]] -- SIZE(10){2010-02-17 (水) 11:42:47} -[[va_start、va_end、va_arg:http://www.paw.hi-ho.ne.jp/takadayouhei/technic/17.html]] -- SIZE(10){2010-02-17 (水) 11:05:07}