episode 3
--storage structure. ampersand operate with asterisk
--library function
episode 4
--generic function 泛型函数
swap(void* pa,void*pb,int size);
-----ampersand and asterisk
the original types does not matter much, the pointer does.
when a pointer is operated with a intergral, just remember to transit the intergral into the same type length with the pointer.
--big endian, little endian(most linux)
-----array
int array[10];
array = &arry[0];
array+k = &array[k]; //k 进行指针运算,要扩展成array同类型长度
*array = array[0];
*(array+k)=array[k];
*(array-4)=8;
array[-4] = 8;//there is no bond check in C, so it will put 8 at the corresponding address.This is not good //code, the result is unsure, it may crush.
-------liabrary function
..........strdup("adm"); //as it shows itself, only valid to string type.
memcpy function,return an adress pointed at heap which store"adm"(with string end sign).
.........strcpy(pAim, "4021");
"4021" is copied into the memory started at address pAim.
...........memcpy(void*to,void*from,int size)
copy designated size to the memory.
..........memcmy(void *a, void *b, int size)
copare two storage, if equal,return to 0,otherwise, get a positive or negative value.
------void swap(void* pa,void*pb,int size);
void swap(void* pa,void*pb,int size) { char temp[size]; memcpy(temp,pa,size); memcpy(pa,pb,size); memcpy(pb,temp,size); }
-----void * lsearch(void *key, void *base, int n, int elemSize)
//a generic function of search, but not available for pointer type, as memcmp is used.
void * lsearch(void *key, void *base, int n, int elemSize) { int i; for(i = 0; i < n; i++) { void * elemAddr = (char*)base + i*elemSize; //void * type not allowed to do operation.
//intergral operated with pointer here manually adjusted if( memcmp( elemAddr,key,elemSize) == 0 ) return elemAddr; } return NULL; }
-----void * lsearch(void *key, void *base, int n, int elemSize,int(*memCmpa)(void *, void *) )
//*memCmpa , the * is not necessary,explictly show function pointer
void * lsearch(const void *key,const void *base, int n, int elemSize,int(*memCmpa)(void *,void *) )
{ int i; for(i = 0; i < n; i++) { void * elemAddr = (uchar*)base + i*elemSize; if( memCmpa( elemAddr,key) == 0 ) return elemAddr; } return NULL; }
applied in array search
uchar *array[] = {"one","two","three","four","five"}; uchar *aim="two"; uchar **k; k = lsearch(&aim,array,5,sizeof(uchar*), myStrCmp); // the first parameter add & to get the same depth with the second if(k == NULL) return -1; printf("%s,",*k);
int strCmp(const void *a,const void *b) { uchar *a1 = *(uchar**)a; uchar *b1 = *(uchar**)b; return strcmp(a1,b1); }
bSearch 针对已经排列好的有序数列
#define NULL (void *)0 //generic binary search function void *bsearchMy(const void *key, const void *base,int n, int elemSize, int (*memCmpa)(const void *,const void *) ) { int left,right; int mid; void *elemAddr; int compare; left = 0; right = n - 1; while(left <= right) { mid = (left + right)/2; elemAddr = (char *)base + mid * elemSize; compare = memCmpa(key,elemAddr); if(0 == compare) { return elemAddr; } else if(compare < 0) { right = mid - 1; } else if(compare > 0) { left = mid + 1; } } return NULL; } //__I1__ int compareInt(const void *d1,const void *d2) { int t1,t2; t1 = *(int *)d1; t2 = *(int *)d2; if(t1 > t2) return 1; else if(t1 < t2) return -1; else return 0; }
//__I2__ int compareStr(const void *d1,const void *d2) { char *t1, *t2; t1 = *(char **)d1; t2 = *(char **)d2; return strcmp(t1,t2); }
__I1__compareint, not return v1-v2, c程序实践中写到,if v2 is large and positive and v1 is large and negative or vice versa, the resulting overflow would produce an incorrct answer. Direct comparison is longer but safer.
__I2__the address of each entry in the array,&str[i](of type char**),not str[i] is passed to the function parameter. two steps to access the value.
int main() { char *a[] = {"hello","miss","rabbit","you"}; char *key = "rabbit"; //key[] wrong char **result; int n; n = sizeof(a)/sizeof(a[0]); result = (char **)bsearchMy(&key,a,n,sizeof(a[0]),compareStr); if(result == NULL) printf("key not found"); else printf("%s",*result); }