1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
// 指针地址和指针的值都可以设置为常量 #include <stdio.h> int main(int argc, char const *argv[]) { // 将常量或者非常量的数据的地址赋值给常量指针是合法的 double rates[5] = {11.11, 22.22, 33.33, 44.44, 55.55}; const double locked[4] = {0.1, 0.2, 0.3, 0.4, 0.5}; const double *pc = rates; //合法 pc = locked; //合法 pc = &rates[3]; //合法 // 只有非常量数据的地址才能赋值给普通指针 double rates[5] = {11.11, 22.22, 33.33, 44.44, 55.55}; const double locked[4] = {0.1, 0.2, 0.3, 0.4, 0.5}; double *pnc = rates; //合法 pnc = locked; //非法 pnc = &rates[3]; //合法 // 以上做法是合理的,否则可以使用指针来修改常量值了 如*pnc=13 // const放在*后面表示指针地址是常量、而不是指针的值是常量 double rates[5] = {11.11, 22.22, 33.33, 44.44, 55.55}; double * const pc = rates; //pc指向数组的开始处 pc = &rates[2]; //不允许修改指针地址 *pc = 22.22; //但是允许修改它的值 // 将指针地址和指针的值都设置常量 const double * const pc = rates; return 0; } // 二维数组与指针(多维数组同理) #include <stdio.h> int main(int argc, char const *argv[]) { int zippo[4][2] = { {2, 4}, {6, 7}, {1, 3}, {5, 7} }; printf("zippo=%p zippo+1=%p zippo[0]+2=%p\n", zippo, zippo + 1, zippo[0]+2); printf("zippo[0]=%p zippo[0]+1=%p\n", zippo[0], zippo[0] + 1); printf("*zippo=%p *zippo+1=%p\n", *zippo, *zippo + 1); printf("zippo[0][0]=%d\n", zippo[0][0]); printf("*zippo[0]=%d\n", *zippo[0]); printf("**zippo=%d\n", **zippo); printf("zippo[2][1]=%d\n", zippo[2][1]); printf("*(*(zippo+2)+1)=%d\n", *(*(zippo + 2) + 1)); /* 输出如下 zippo=0028FF20 zippo+1=0028FF28 zippo[0]+2=0028FF28 //zippo和zippo[0]的指针地址相同,但+1后不同,因为步进不同 zippo[0]=0028FF20 zippo[0]+1=0028FF24 //因为第2维的数组长度是2,所以zippo+1和zippo[0]+2的地址相同 *zippo=0028FF20 *zippo+1=0028FF24 //对zippo取值其实就是zippo[0]的地址 所以*zippo+1和zippo[0]+1的地址相同 zippo[0][0]=2 //同理zippo[0][0]==*zippo[0]==**zippo==2 *zippo[0]=2 **zippo=2 zippo[2][1]=3 //同理zippo[2][1]==*(*(zippo+2)+1)==3 *(*(zippo+2)+1)=3 */ getchar(); return 0; } // 数组指针与指针数组 #include <stdio.h> int main(int argc, char const *argv[]) { //pz是指向一个包含2个int值的数组的指针 一定要用小括号 //因为int * pz[2]表示2个int型指针的数组 "[]"的优先级更高 int (*pz)[2]; return 0; } // 数组的指针 #include <stdio.h> int main(int argc, char const *argv[]) { int zippo[4][2] = { {2, 4}, {6, 7}, {1, 3}, {5, 7} }; int (*pz)[2]; pz = zippo; printf("pz=%p pz+1=%p\n", pz, pz + 1); printf("pz[0]=%p pz[0]+1=%p\n", pz[0], pz[0] + 1); printf("*pz=%p *pz+1=%p\n", *pz, *pz + 1); printf("pz[0][0]=%d\n", pz[0][0]); printf("*pz[0]=%d\n", *pz[0]); printf("**pz=%d\n", **pz); printf("pz[2][1]=%d\n", pz[2][1]); printf("*(*(pz+2)+1)=%d\n", *(*(pz + 2) + 1)); getchar(); /* 输出如下 pz=0028FF1C pz+1=0028FF24 pz[0]=0028FF1C pz[0]+1=0028FF20 *pz=0028FF1C *pz+1=0028FF20 pz[0][0]=2 *pz[0]=2 **pz=2 pz[2][1]=3 *(*(pz+2)+1)=3 */ return 0; } // 指针赋值比数值赋值更严格 #include <stdio.h> int main(int argc, char const *argv[]) { int n = 5; double x; int *pi = &n; double *pd = &x; x = n; //会隐性类型转换 pd = pi; //编译报错 int *pt; int (*pa)[3]; int ar1[2][3]; int ar2[3][2]; int **p2; //指向指针的指针 pt = &ar1[0][0]; //合法 指向int pt = ar1[0]; //合法 指向int pt = ar1; //非法 pa = ar1; //合法 指向int[3] pa = ar2; //非法 p2 = &pt; //合法 指向int的指针 *p2 = ar2[0]; //合法 指向int p2 = ar2; //非法 return 0; } // 两层间接以上,非const不允许赋值给const #include <stdio.h> int main(int argc, char const *argv[]) { int * p1; const int * p2; const int ** pp2; p1 = p2; //非法,const赋值给非const p2 = p1; //合法,非const赋值给const pp2 = &p1; //非法,两层间接后,非const不允许赋值给const //原因如下 const int **pp2; int *p1; const int n = 13; pp2 = &p1; //不允许,我们假设其是合法的 *pp2 = &n; //合法,都是const,但同时会使p1指向n *p1 = 10; //合法,但这样会改变const n的值 return 0; } |