以前的记录都在电子笔记里,倒不如拿出来,有错的地方和大家交流。
1.指针操作:
如下例,设a内存地址为OX00
int a =10;
int *p = &a;
*a 编译错误
a表示10
*p表示10
p表示OX00
&p表示0X04
2.hex转换成ASCII
1 #include <stdio.h> 2 int main(int argc, const char *argv[]) 3 { 4 char hexBuff[128]; 5 sprintf(hexBuff, "%x%x",0x32,0x4d); 6 printf("%s\n",hexBuff); 7 printf("%c\n",hexBuff[0]); 8 printf("%c\n",hexBuff[1]); 9 printf("%c\n",hexBuff[2]); 10 printf("%c\n",hexBuff[3]); 11 printf("%x\n",henBuff[0]); 12 return 0; 13 }
3.有一个字符串,每7为表示一个ASCII,将字符串转换成对应的ASCII码,如果连续出现7个0表示结束。
1 #include <stdio.h> 2 #include <string.h> 3 int fun(char * str){ 4 char tmp[8]; 5 int index = 0; 6 while( * str){ 7 tmp[index++] = * str++; 8 if(index == 7){ 9 printf("%s\n", tmp); 10 if(strncmp(tmp, "0000000", 7) == 0){ 11 printf("game over....\n"); 12 } 13 memset(tmp,0,8); 14 index = 0; 15 } 16 } 17 return 1; 18 } 19 int main(int argc, const char *argv[]) 20 { 21 char str[] = "1234567234567800000001234568"; 22 fun(str); 23 return 0; 24 }
4.将字符串中最长的那个相同的字符串提取出来。
1 int fun(char * str){ 2 char tmp; 3 char array[10]; 4 int count = 0; 5 int index = 0; 6 while( * str){ 7 tmp = *str++; 8 array[count] = tmp; 9 if(*str == tmp){ 10 array[++count] = *str; 11 }else { 12 count = 0; 13 printf("%s\n", array); 14 memset(array, 0, 10); 15 tmp = 0; 16 } 17 } 18 return 1; 19 }
5.有双向循环链表结点定义为:
struct node
{ int data;
struct node *front,*next;
};
有两个双向循环链表 A,B,知道其头指针为:pHeadA,pHeadB,请写一函数将两链表中 data 值相同的结点删除
1 BOOL DeteleNode(Node *pHeader, DataType Value) 2 { 3 if (pHeader == NULL) return; 4 BOOL bRet = FALSE; 5 Node *pNode = pHead; 6 while (pNode != NULL) 7 { 8 if (pNode->data == Value) 9 { 10 if (pNode->front == NULL) 11 { 12 pHeader = pNode->next; 13 pHeader->front = NULL; 14 } 15 else 16 { 17 if (pNode->next != NULL) 18 { 19 pNode->next->front = pNode->front; 20 } 21 pNode->front->next = pNode->next; 22 } 23 Node *pNextNode = pNode->next; 24 delete pNode; 25 pNode = pNextNode; 26 bRet = TRUE; 27 //不要 break 或 return, 删除所有 28 } 29 else 30 { 31 pNode = pNode->next; 32 } 33 } 34 return bRet; 35 } 36 37 void DE(Node *pHeadA, Node *pHeadB) 38 { 39 if (pHeadA == NULL || pHeadB == NULL) 40 { 41 return; 42 } 43 Node *pNode = pHeadA; 44 while (pNode != NULL) 45 { 46 if (DeteleNode(pHeadB, pNode->data)) //在B中将A中的data删除掉 47 { 48 if (pNode->front == NULL) //同时删除A中的data 49 { 50 pHeadA = pNode->next; 51 pHeadA->front = NULL; 52 } 53 else 54 { 55 pNode->front->next = pNode->next; 56 if (pNode->next != NULL) 57 { 58 pNode->next->front = pNode->front; 59 } 60 } 61 Node *pNextNode = pNode->next; 62 delete pNode; 63 pNode = pNextNode; 64 } 65 else 66 { 67 pNode = pNode->next; 68 } 69 } 70 }
6.不定参数函数的实现
1 int sum(int num, ...) 2 { 3 int *p = &num + 1; 4 int ret = 0; 5 while(num--) 6 { 7 printf("%d\n", num); 8 ret += *p++; 9 } 10 return ret; 11 } 12 int main(int argc, char* argv[]) 13 { 14 printf("%d\n", sum(3, 5, 7, 9)); 15 return 0; 16 }
所谓不定长参数,就是函数的形参数量不定,类型也可能是不定的。我们把像上面的函数sum中如“int num”这样的参数叫做“有名参数”,后面用“…”代表的都是“匿名参数”,有名参数是可以在函数中通过变量名直接访问的,匿名函数则无法通过变量名直接访问,只能是通过相对有名参数的位置(地址)来访问了。
关键在于:
(1)匿名参数的个数和类型必须通过有名参数传递给被调函数
如printf中的第一个参数“const char *fomat”,在format中不仅告诉了printf参数的个数,还必须指定正确的类型,二者缺一不可。
(2)被调函数本身有办法直接或间接定位参数的个数和类型
即描述参数个数和类型的参数的位置应该是固定的,函数有办法定位它们,而不是如匿名参数那般不确定的。像C语言的标准调用方式,即从右至左压栈且调用方清理栈的方式是比较合适的,尤其是前者,如果在第一个参数中指定各参数的个数和格式,则根据栈的规律可以知道,返回地址上方即是第一个参数(即ebp+8),以后的匿名参数则可依次确定了。
7.sizeof和strlen的区别
1 int main(int argc, const char *argv[]) 2 { 3 char *p = "abc"; 4 char p1[] = "wan"; 5 printf("p = %u p1 = %u\n", strlen(p), strlen(p1)); 6 printf("sizeof(int) = %d\n", sizeof(int)); 7 return 0; 8 }
答案:p = 3, p1 = 3; sizeof(int) = 4.