はじめてのC
char caArray[10][256] = {{ 0, }}; ...; iSetStrArray( (char **)caArray ); int iSetStrArray( char **ppcaArray ) { char (*pcaLocalStr)[256] = { 0, }; pcaLocalStr = ( char(*)[256] )ppcaArray; ...; }
Makefile.am: bin_PROGRAMS=hello hello_SOURCES=sample.c CFLAGS=-I../Include LDADD= testlib.o testlib2.o LDFLAGS=-L../Lib LDLIBS=-lm [EOF]
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])
.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 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;
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; }
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; }
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); }
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; }
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,
//こんな関数を定義 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;
#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) !!!
めんどーだな。いろいろと
たぶん、使い方について
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));
HANDLE h_sem; h_sem = CreateSemaphore(NULL, 1, 1, "semaphore_name"); WaitForSingleObject(h_sem, INFINITE); ... ... ReleaseSemaphore(h_sem, 1, NULL); CloseHandle(h_sem);
mutexは遅い. mutexを使うよりもバイナリセマフォの方が早いかもしれない なぜなら、ミューテックスとセマフォの所有権のセマンティックがかなり異なるため 両者を交換可能なものとして使うことはできない。 CriticalSectionが早い。←ただし、プロセス間同期には使えない。
volatile int *pon
int volatile *pon