(一)常量,函数
1.1 const修饰的变量具有只读的特性,限制紧跟随它的标识符
1.2 const int * const *q,限制了*q和**q的指向;
const int const **q,限制了**q的指向。
1.3 函数是一种解封装的方法,遵从“一个函数仅实现一个功能”的原则。
1.4 func(int a[ ], int n) 和 func(int *a, int n)等价。
函数不存在传递(拷贝)整个数组的情况,当用数组名做实参时,传递的实际上是数组的第一个元素的地址。因此,形参是一个指 向数组元素类型的指针。
1.5 函数名在表达式中可以解读成“指向该函数的指针”。
函数指针
double x,y,result; double (*func_table[4])(double,double)={add,sub,mul,divi}; printf("请输入两个数:"); scanf("%1f %1f",&x,&y); printf("对这两个数进行加减乘除后的结果:"); for(i=0;i<4;i++) { result=(*func_table[i])(x,y); printf("%.2f",result); } putchar('\n');
(二)指针与数组
指针:指的是内存的地址;且指针变量只能存放地址,是一个左值。
数组名:其实是一个地址信息,是地址常量(不是左值)。
用一个指针指向数组
int a[num]; char *p; p=a; // p=&a[0]都可以;指针指向数组首地址
2.1 str[3] 用指针法表示为 *(str+3)
2.2 str[20] 可以写成 20[str]
访问数组中元素时,数组名被解释为数组中第一个元素的地址,str[20]==*(str+20)==*(20+str)==[20]str。
2.3 数组的下标法和指针法访问是等价的,所以b[-2]与*(b-2)等价
2.4
int array[10]={0,1,2,3,4,5,6,7,8,9};
int *p=(int *)(&array+1);
printf("%d", *(p-6));
array和&array的值虽然相同,但它们不一样。array表示数组第一个元素的位置,而&array表示的是整个数组的位置。(array+1指向数组第二个元素)
&array+1指向的是整个数组最后的位置(即第二个array数组的起始位置),然后(int *)将其强制转化成一个整型地址(指针),所以指针变量p初始化后,指向的地址应该是array[10](第11个元素),所以*(p-6)==array[10-6]==array[4]==4。
*(array+i) == array[i]
*(*(array+i)+j) == array[i][j]
*(*(*(array+i)+j)+k) == array[i][j][k]
2.5
int (*p) [10]=&array
*(*(p+1)-6)==array[11-6]==array[5]
指针p 指向数组array的地址,p+1指向整个数组最后的位置,于是*(p+1)便指向下个数组array的起始位置,即&array[11]; *(*(p+1)-6)可写成*(*(p+1)[-6])
2.6 NULL宏定义: #define NULL ((void *)0)
2.7 若有int a[10],则&a和&a[0]有什么不同?
a是一个数组,在&a这个表达式中,数组类型做左值,&a表示取整个数组的首地址,类型是int(*)[0],
&a[0]则表示数组a的第一个元素的首地址,虽然两个地址的数值相同,但后者的类型是int *。
参考链接:小甲鱼《带你学C带你飞》整理