#include <stdio.h> #include <string.h> int main() { //指针和数组笔试题解析 int a[] = { 1,2,3,4 }; printf("%d\n", sizeof(a));//16 a==&a[0] //sizeof(数组名),计算的是整个数组的大小单位是字节 printf("%d\n", sizeof(a+0));//4/8 a+0==&a[0]+0 //这里a表示数组首元素地址,a并没有单独放在sizeof内部,也没有取地址, //所以a就是首元素地址,a+0还是首元素地址 printf("%d\n", sizeof(*a));//4 *a==*&a[0] //*a中的a是数组首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素 //首元素的大小就是4个字节 printf("%d\n", sizeof(a+1));//4 a+1==&a[0]+1 //这里的a是数组的首元素地址,a+1是第二个元素的地址 printf("%d\n", sizeof(a[1]));//4 //计算的是第二个元素的大小 printf("%d\n", sizeof(&a));//4/8 //&a取出的是数组的地址,数组的地址,也就是个地址 printf("%d\n", sizeof(*&a));//16 //&a---->int(*)[4] //&a拿到的是数组名的地址,类型是int(*)[4],是一种数组指针 //*&a----->a //也就是可以理解成:&和*相互抵消了,所以只有a了,就代表整个数组的大小了 printf("%d\n", sizeof(&a+1));//4/8 //&a取出的是数组的地址 //&a---->int(*)[4] //&a+1是从数组a的地址向后跳过了一个(4个整形元素的)数组的大小 //&a+1 还是地址,是地址就是4/8字节 printf("%d\n", sizeof(&a[0]));//4/8 //&a[0]就是第一个元素的地址 //计算的是地址的大小 printf("%d\n", sizeof(&a[0]+1)); //&a[0]就是第二个元素的地址 //大小是4/8个字节 //&a[0]+1---->&a[1] // char ass[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(ass));//6 //sizeof(数组名) printf("%d\n", sizeof(ass+0));//4/8 //ass+0 是数组首元素地址 printf("%d\n", sizeof(*ass));//1 //*ass就是数组的首元素,大小是1字节 //*ass --> ass[0] //*(ass+0) --> ass[0] printf("%d\n", sizeof(ass[1]));//1 printf("%d\n", sizeof(&ass));//4/8 //&ass是数组的地址,地址就是4/8个字节 printf("%d\n", sizeof(&ass+1));///4/8 //&ass+1是数组后的地址,跳过了整个数组 printf("%d\n", sizeof(&ass[0]+1));//4/8,&ass[0]会发生整型提升 //&ass[0]+1是第二个元素的地址 printf("%d", strlen(ass));//随机值 ///我们的数组中结尾并没有'\0',所以无法具体测量长度 printf("%d", strlen(ass+0));//随机值,与上述相同的原因 //printf("%d", strlen(*ass));//--> strlen('a')--strlen(97);//野指针问题 //printf("%d", strlen(ass[1]));//-->strlen('b')-->strlen(98) //printf("%d", strlen(&ass));//&ass取出数组地址,依旧随机值 //printf("%d", strlen(&ass+1));//随机值-6 //printf("%d", strlen(&ass[0]+1));//随机值 char arr1[] = "abcdef"; printf("%d\n", sizeof(arr1));//7 //a b c d e f \0 printf("%d\n", sizeof(arr1+0));//4/8 printf("%d\n", sizeof(*arr1));//1 printf("%d\n", sizeof(arr1[1]));//1 printf("%d\n", sizeof(&arr1));//4/8 printf("%d\n", sizeof(&arr1+1));//4/8 printf("%d\n", sizeof(&arr1[0]+1));//4/8 //strlen 是求字符串长度的,关注的是字符串中的\0,计算的是\0之前出现的字符的个数 //strlen是库函数,只针对字符串 //sizeof只关注占用内存空间的大小,不在乎内存中放的是什么 //sizeof是操作符 printf("%d\n", strlen(arr1));//6 printf("%d\n", strlen(arr1 + 0));//6 //printf("%d\n", strlen(*arr1));//err //printf("%d\n", strlen(arr1[1]));//err //printf("%d\n", strlen(&arr1));//6 //printf("%d\n", strlen(&arr1 + 1));//随机值 //printf("%d\n", strlen(&arr1[0] + 1));//5 const char* p = "abcdef"; printf("%d\n", sizeof(p));//4/8 printf("%d\n", sizeof(p+1));//4/8 printf("%d\n", sizeof(*p));//1 printf("%d\n", sizeof(p[0]));//1 printf("%d\n", sizeof(&p));//4/8 printf("%d\n", sizeof(&p+1));//4/8 printf("%d\n", sizeof(&p[0]+1));//4/8 printf("%d\n", strlen(p));//6 printf("%d\n", strlen(p+1));//5 //printf("%d\n", strlen(*p));//err //printf("%d\n", strlen(p[0]));//err //printf("%d\n", strlen(&p));//随机值 //printf("%d\n", strlen(&p+1));//随机值-5 printf("%d\n", strlen(&p[0]+1));//5 //二维数组 int a[3][4] = { 0 }; printf("%d\n", sizeof(a));//48 printf("%d\n", sizeof(a[0][0]));//4 printf("%d\n", sizeof(a[0]));//16 //a[0]是第一行这个一维数组的数组名,单独放在sizeof颞部,a[0]表示第一个整个这个一维数组 //sizeof(a[0])计算的就是第一行的大小 printf("%d\n", sizeof(a[0]+1));//4 --a[0][0]+1 //a[0]并没有单独放在sizeof内部,也没取地址,a[0]就是首元素的地址 //就是第一行这个一维数组的第一个元素的地址,a[0]+1就是第一行第二个元素的地址 printf("%d\n", sizeof(*(a[0]+1));//4 //a[0] + 1就是第一行第二个元素的地址 //*(a[0] + 1)就是第一行第二个元素 printf("%d\n", sizeof(a+1));//4/8 //a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址 //a表示首元素地址,二维数组的首元素是他的第一行,a就是第一行地址 //a+1就是跳过第一行,表示第二行的地址 printf("%d\n", sizeof(*(a+1));//16 //*(a+1)是对第二行地址的解引用拿到的是第二行的大小 //*(a+1)-->a[1] printf("%d\n", sizeof(&a[0]+1));//4/8 //&a[0]是第一行的数组名,拿出的是第一行的地址 //&a[0]+1得到的是第二行的地址 printf("%d\n", sizeof(*(a[0]+1));//16 printf("%d\n", sizeof(*a));//16 //a表示首元素的地址,就是第一行的地址 //*a就是第一行地址的解引用,拿到的就是第一行 printf("%d\n", sizeof(a[3]));//16 printf("%d\n", sizeof(a[0]));//16 一个道理 //数组名的意义 /* 1.sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小 2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址 3.除此之外所有的数组名都表示首元素的地址 */ return 0; }
#include <stdio.h> void test1() { int a[5] = { 1,2,3,4,5 }; int* ptr = (int*)(&a + 1);//&a是数组的地址-->int(*)[5] //&a+1跳过了整个数组, printf("%d %d\n", *(a + 1), *(ptr - 1));//2 5 } struct Test {//这里告知结构体的大小是20个字节 int Num; char* pcName; short sDate; char cha[2]; short sBa[4]; }*p = (struct Test*)0x100000; //假设p的值为0x100000。test2中表达式的值分别是多少, //已知,结构体Tset类型的变量大小是20个字节 //x86环境 void test2() { printf("%p\n", p + 0x1);//16进制表示20-->14 //0x100000+20-->0x100014 printf("%p\n", (unsigned long)p + 0x1); //(unsigned long)p-->1048576+0x1-->1048576+1->1048577-->0x100001 printf("%p\n", (unsigned int*)p + 0x1); //0x100000+4-->0x100004 } void test3() { int a[4] = { 1,2,3,4 }; int* ptr1 = (int*)(&a + 1); int* ptr2 = (int*)((int)a + 1);//%x,打印16进制 //假设a=0x00012ff40 //a+1-->0x0012ff44 //(int)a+1-->0x12ff41,处于1-2之间 printf("%x,%x", ptr1[-1], *ptr2);//4 2000000 //低-----------------------------------高 //10 (00 00 00 02) 00 00 00 03 00 00 00 04 00 00 00 //ptr2-->00 00 00 02 //小端 //ptr1[-1]-->*(ptr1+(-1))-->*(ptr1-1) } void test4() { int a[3][2] = { (0,1),(2,3),(4,5) };//实际-->{ 1, 3, 5 ,0 , 0, 0} int* p; p = a[0]; printf("%d", p[0]);//1 p[0]-->*(p+0) } //void test5() {//x86 // int a[5][5]; // int (*p)[4]; // p = a; // //-4 // //补码:11111111111111111111111111111100 // //16进制:FF FF FF FC // printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);// -4 // /* // p[4][2]-->*((p+4)+2) |&p[4][2] // [][][][][][][][][][][][][][][][][][][][][][][][][] // 0 1 2 3 4 |&a[4][2] // |p |p+1 |p+2 |p+3 |p+4 // */ // } void test6() { int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 }; int* ptr1 = (int*)(&aa + 1); int* ptr2 = (int*)(*(aa + 1)); printf("%d %d\n", *(ptr1 - 1), *(ptr2 - 1));//10 5 } void test7() { const char* a[] = { "work","at","alibaba" }; const char** pa = a; pa++; printf("%s\n", *pa);//at } void test8() { const char* c[] = { "ENTER","NEW","POINT","FIRST" }; const char** cp[] = { c + 3,c + 2,c + 1,c }; const char*** cpp = cp; printf("%s\n", **++cpp);//POINT printf("%s\n", *-- * ++cpp + 3);//ER printf("%s\n", *cpp[-2] + 3);//ST printf("%s\n", cpp[-1][-1] + 1);//EW } int main() { /*test1(); test2(); test3(); test4(); test5(); test6(); test7();*/ test8(); return 0; }