题目7——指针数组:
- int main()
- {
- char* a[] = { "work","at","alibaba" };
- char** pa = a;
- pa++;
- printf("%s\n", *pa);
- return 0;
- }
解析:
题目6——二维数组:
- int main()
- {
- int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
- //12345 678910
- int* ptr1 = (int*)(&aa + 1);
- //&aa + 1:指向10右边一位的地址
- int* ptr2 = (int*)(*aa + 1);
- //*aa + 1:首元素地址解引用+1=第一行第二个元素
- int* ptr3 = (int*)(*(aa + 1));
- //aa + 1:首元素地址+1
- //*(aa + 1)=*aa[1]=下一行元素
- printf("%d,%d,%d\n", *(ptr1 - 1), *(ptr2 - 1), *(ptr3 - 1));
- //*(ptr1-1)=ptr1[-1]=10
- //ptr2 - 1:指向第二个元素的指针-1再解引用=首元素=1
- // *(ptr3 - 1)=ptr3[-1]=指向元素6的指针向左移动一位=5
- return 0;
- }
题目5——逗号表达式:
- int main()
- {
- int a[3][2] = { (0,1),(2,3),(4,5) };
- //逗号表达式!!!
- //10 30 50
- int* p = a[0];
- //a[0]:首行第一个元素
- printf("%d\n", p[0]);
- return 0;
- }
题目4——指针+1:
- struct MyStruct
- {
- int num;
- char* pcname;
- short sdate;
- char cha[2];
- short sba[4];
- }*p;
- //结构体大小为32字节
- //p=0x100000
- int main()
- {
- p = 0x100000;
- printf("%p\n", p + 0x1);
- //p:结构体指针,+1=下一个结构体指针,所以 p + 1 的地址比 p 高32字节
- //p+1=p+结构体大小=p+32(10进制)=0010 0000+0000 0020=0010 0020
- printf("%p\n", (unsigned long)p + 0x1);
- //0x10 0000(16进制)=1048576(10进制)
- //加1会增加地址的值,而不是指向下一个结构体
- //1048576+0x1(16进制)=1048576+1(10进制)=1048577=0010 0001(16进制)
- printf("%p\n", (unsigned int*)p + 0x1);
- //unsigned int*:整型指针类型,指针+1=下一个指针
- // 尽管平台是64位的,但是 unsigned int 的大小在几乎所有平台上都是4字节(32位),而不是8字节(64位)
- //p+1=p+4(64平台)=0010 0000+4(16进制)=0010 0000+8(10进制)=0010 0004
- return 0;
- }
题目3——指针相减:
- int main()
- {
- int a[5][5];
- // 00000 00000 00000 00000 00000
- // a[0] a[1] a[2] a[3] a[4]
- int(*p)[4];
- //p:{0}{0}{0}{0}
- p = a;
- // 0000 0 000 00 00 000 0 0000 00000
- // p[0] p[1] p[2] p[3]
- printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
- // a[0] a[1] a[2] a[3] a[4]
- // 0000 0 000 00 00 000 0 0000 00000
- // p[0] p[1] p[2] p[3] p[4]
- //指针相减=两个指针之间的元素个数=-4
- // 原码 1000 0100
- // 反码 1111 1011
- // 补码 1111 1100
- //十六进制 fc
- return 0;
- }
解析:
题目2——指针在内存中所指的地址:
- int main()
- {
- char* c[] = { "enter","new","point","first" };
- char** cp[] = { c + 3,c + 2,c + 1,c };
- char*** cpp = cp;
- printf("%s\n", **++cpp);//++优先级高于*
- printf("%s\n", * *++cpp + 3);//++优先级高于*,*优先级高于+
- printf("%s\n", *cpp[-2] + 3);
- printf("%s\n", cpp[-1][-1] + 1);
- return 0;
- }
解析:
题目1——指针在内存中所指的地址:
- int main()
- {
- int a[4] = { 1,2,3,4 };
- int* ptr1 = (int*)(&a + 1);
- //&a + 1:指向元素4右边的地址
- //(int*)(&a + 1):强制转换为int*类型
- int* ptr2 = (int*)((int)a + 1);
- //(int)a:数组首元素
- printf("%x,%x\n", ptr1[-1], *ptr2);
- //ptr1[-1]=*(ptr1+(-1))=*(ptr1-1)=指向元素4右边的地址向左边移动一位=4
- return 0;
- }
解析: