#include<stdio.h> //int main() //{ // int a[5] = { 1,2,3,4,5 }; // int* ptr = (int*)(&a + 1);//数组指针(&a+1)跳过整个数组,5后面的地址,(int*)()强制类型转换 // printf("%d\n", *(a + 1), *(ptr - 1));//打印结果为2,5 // //*(ptr-1)是跳过整个数组并-1,是5 // //*(a+1)为2 // return 0; //} //结构体大小是20,假设p的地址是0x100000 //指针+1,加的实际是多少,取决于指针的类型,结构体指针+1,加的是结构体大小,整形指针+1,加的是4 //字符指针,+1加的是1 整形+1,加的就是1 //struct test //{ // int Num; // char* pcName; // short sDate; // char cha[2]; // short sBa[4]; //}*p; //int main() //{ // printf("%p\n", p + 0x1);//指针名是首元素地址 // //0x100000+20(结构体类型是20)=0x100014(20转化为16进制为0x100014) // printf("%p\n", (unsigned long)p+0x1);//整形+1,加的是4,即0x10001 // printf("%p\n", (unsigned int*)p + 0x1);//int型,+4,即0x10004 // return 0; //} //ptr被强制转换成int型,+1就是+1 %x是十六进制 //int main()//假设小端存储:为01000000 02000000 03000000 04000000(地位放在低地址,高位放在高地址) //{ // int a[4] = { 1,2,3,4 };//int型,如1就需要占4个字节 // int* ptr1 = (int*)(&a + 1);//&a+1跳过整个数组,(int*)是强制类型转换为int* // int* ptr2 = (int*)((int)a + 1);//数组名是首元素地址,a就是地址,(inta)+1就是+1 // //此时+1就只是+1个字节(int1的四分之一),此时指向的是00000002--->ptr2 // //(int*)表示将a强制类型转换为int*,并将其存储在ptr2中 // printf("%x,%x", ptr1[-1], *ptr2);//打印结果为4 20000000 // //%x是16进制,ptr1[-1]是*(ptr1+(-1)),即向左移动1个整形(int), // // 4个字节是一个整型,指向04000000--->ptr1 // //打印时,倒着打印,为00000004 和20000000 //} //int main() //{ // int a[3][2] = { (0,1),(2,3),(4,5) };//(0,1)逗号表达式,可理解为1,3,5, // //二维数组为 1 3(第一行) 5 0(第二行) 0 0(第三行) // int* p; // p = a[0];//数组名是首元素地址,吧首元素地址传给指针p,p指向1 // printf("%d\n", p[0]);//p[0]->*(p+0),是1 // return 0; //} //int main() //{ // int a[5][5];//二维数组,5行5列 // int(*p)[4];//int(*)[4] // p = a;//a是int(*)[5],p是int(*)[4],,,将a放入p中,p仍指向首元素的地址 // printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); // //打印结果为11111111111111111111111111111100,,,-4 // //&p[4][2]->*(*(p+4)+2),即4行2列 // //但是p是[4],p每次只前进4个字节,而a是5个字节,所以&p[4][2]只是a[3][2] // //&a[4][2]就是&a[4][2],小地址-大地址=-4, -4的原码为10000000000000000000000000000100 // // 反码11111111111111111111111111111011 // // 补码11111111111111111111111111111100 // //在地址,直接打印%p为11111111111111111111111111111100,%d时需要吧补码再次改为原码仍为-1 // return 0; //} //int main() //{ // int aa[2][5] = { 1,2,3,4,5,6,7,8,8,10 }; // int* ptr1 = (int*)(&aa + 1);//&aa+1,跳过整个数组,此时是数组,被(int*)强制类型转换 // int* ptr2 = (int*)(*(aa + 1));//数组名是首元素地址,aa+1第一行地址+1,是跳过二维数组的第一行 // //进入第二行,是指向6,*(aa+1)->aa[1],即第二行的数组名,首元素6的地址,此时就是int的6 // printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10 5 // return 0; //} //int main() //{ // char* a[] = { "work","at","alibaba" }; // //a是指针数组,每个元素是指针,每个元素分别是(char*,char*,char*),分别存放,work,at,alibaba // char** pa = a;//将a的三个指针的地址传给pa,二级指针,指向第一个char*的首元素地址 // pa++;//此时是第二个char* // printf("%s\n", *pa);//at // //%s打印字符串,解引用pa(此时是第二个char*) // return 0; //} int main()//指针是连续存放的 { char* c[] = { "ENTER","NEW","POINT","FIRST" };//将这些元素依次存放在c指针中, //c的指针分别用char*,char*char*,char*接收 char** cp[] = { c + 3,c + 2,c + 1,c };//c表示首元素地址,与*c的c对应 //把c的char*,char*char*,char*分别存放在c,c+1,c+2,c+3中(注意顺序) char*** cpp = cp;//把cp放在指针ccp中,顺序是c,c+1,c+2,c+3 printf("%s\n", **++cpp);//POINT printf("%s\n", *-- * ++cpp + 3);//ER //优先级决定先算++cpp,刚刚的cpp指向c+2,++之后变为指向c+1,解引用变为c+1, //c+1进行--,变为c,解引用是char*,char*指向的ENTER的E,再+3,变为E printf("%s\n", *cpp[-2] + 3);//ST //*cpp[-2]+3->**(cpp-2)+3,即为上一个打印时的c+1为cpp, //-2变为c+3,两次解引用指向FINRST,+3后指向ST printf("%s\n", cpp[-1][-1] + 1);//EW // cpp[-1][-1] + 1-->*(*(cpp-1)-1)+1,cpp此时为c+1,-1变为c+2,解引用变为point的char*, //-1变为new的char*,解引用变成new,+1为ew return 0; }