首先:
要明白 sizeof( ) 是个运算符,用来计算 计算一个类型或变量所占空间的大小 单位是:字节
strlen( )是个函数,用来计算字符串的长度 参数是一个指针(地址)
所以只需知道 sizeof( )注重 类型 strlen( )注重 地址
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a)); //a是在sizeof 内部,所以计算的是整个数组的大小,4*4=16
printf("%d\n",sizeof(a+0)); //a+0虽然和a的意义一样但它不是单独在sizeof内部,所以这里的a+0是首元素的地址,而地址的大小是 4/8
printf("%d\n",sizeof(*a)); //a是首元素地址,*a就是首元素 1 它的大小是 4
printf("%d\n",sizeof(a+1)); //a+1是第二个元素的地址,地址的大小是 4/8
printf("%d\n",sizeof(a[1])); //a[1]是第二个元素 2 它的大小是 4
printf("%d\n",sizeof(&a)); //&a是整个数组的地址,地址的大小是 4/8
printf("%d\n",sizeof(*&a)); //*直接和&抵消 sizeof(a)里就只剩个a,那不就和第一个一样了 16
printf("%d\n",sizeof(&a+1)); //&a+1还是地址 4/8
printf("%d\n",sizeof(&a[0])); //&a[0]是第一个元素的地址 4/8
printf("%d\n",sizeof(&a[0]+1)); //&a[0]+1是第二个元素的地址 4/8
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr)); //sizeof里直接是数组名,就直接算整个数组的大小 1*6=6
printf("%d\n", sizeof(arr+0)); //a+0虽然和a的意义一样但它不是单独在sizeof内部,所以这里的a+0是首元素的地址,而地址的大小是 4/8
printf("%d\n", sizeof(*arr)); //*arr是第一个字符 a 根据它是char 类型 它的大小是 1
printf("%d\n", sizeof(arr[1])); //arr[1]是第二个字符,它的大小是 1
printf("%d\n", sizeof(&arr)); //&arr是整个数组的地址,它还是地址啊 4/8
printf("%d\n", sizeof(&arr+1)); //&arr+1是跳过整个数组的地址 4/8
printf("%d\n", sizeof(&arr[0]+1)); //&a[0]+1是第二个元素的地址 4/8
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr)); //arr是首元素地址,所以从第一个元素访问,到 /0 停止,但此时可以看到,这种初始化方式你并不知道 /0 在哪,所以可能在后面的某处,因此它的值为随机值
printf("%d\n", strlen(arr+0)); //arr+0还是首元素地址,往后找 /0 ,值是随机值
printf("%d\n", strlen(*arr)); //*arr是首元素'a',它的ASCII码值为97,此时就是那97作为初始地址向后访问 /0 ,此时属于非法访问了,所以程序错误
printf("%d\n", strlen(arr[1])); //arr[1]是第二个元素'b',和上条性质一样,程序错误
printf("%d\n", strlen(&arr)); //&arr是整个数组的地址,向后找/0 是 随机值
printf("%d\n", strlen(&arr+1)); //&arr+1是跳过整个数组的地址,向后找/0 随机值
printf("%d\n", strlen(&arr[0]+1)); //&arr[0]+1是第二个元素的地址,向后找/0 随机值
char arr[] = "abcdef"; a b c d e f /0
printf("%d\n", sizeof(arr)); //arr是在sizeof 内部,所以计算的是整个数组的大小,而'/0'也是个字符,所以它的大小为 1*7=7
printf("%d\n", sizeof(arr+0)); //arr+0是第一个元素的地址,是地址 4/8
printf("%d\n", sizeof(*arr)); //*arr是第一个元素, char类型 1
printf("%d\n", sizeof(arr[1])); //arr[1]是第二个元素,1
printf("%d\n", sizeof(&arr)); //&arr是整个元素的地址,它还是地址啊 4/8
printf("%d\n", sizeof(&arr+1)); //&arr+1是跳过整个数组的地址 4/8
printf("%d\n", sizeof(&arr[0]+1)); //&a[0]+1是第二个元素的地址 4/8
char arr[] = "abcdef"; a b c d e f /0
printf("%d\n", strlen(arr)); //arr是首元素地址,从此处向后找 /0 长度为6
printf("%d\n", strlen(arr+0)); //arr+0还是首元素地址,和上面一样 6
printf("%d\n", strlen(*arr)); //*arr是第一个元素 'a',它的ASCII码值为97,此时就是那97作为初始地址向后访问 /0 ,此时属于非法访问了,所以程序错误
printf("%d\n", strlen(arr[1])); //arr[1]是第二个元素'b',和上条性质一样,程序错误
printf("%d\n", strlen(&arr)); //&arr是整个数组的地址,从此处找 /0 6
printf("%d\n", strlen(&arr+1));//&arr+1是跳过整个数组的地址,从此处找 /0 只可能开后面哪个位置了 随机值
printf("%d\n", strlen(&arr[0]+1)); //&arr[0]+1是第二个元素的地址,从此处向后找 /0 5
char *p = "abcdef";
printf("%d\n", sizeof(p)); //右边其实是常量字符串,p里存的是它的首元素a的地址,它是地址 4/8
printf("%d\n", sizeof(p+1)); //p+1是第二个元素的地址 4/8
printf("%d\n", sizeof(*p)); //*p是第一个元素 a 它的大小是 1
printf("%d\n", sizeof(p[0])); //p[0]是相当于*(p+0) 就是第一个元素 a 1
printf("%d\n", sizeof(&p)); //&p 是这个变量p的地址 是地址 4/8
printf("%d\n", sizeof(&p+1)); //&p+1 是p的地址向后走一个字节的地址 4/8
printf("%d\n", sizeof(&p[0]+1));p[0]是相当于*(p+0) , 加个& 与* 抵消 所以最后剩个p+1 和第二个一样 4/8
char *p = "abcdef"; a b c d e f /0
printf("%d\n", strlen(p)); //p里存的是a的地址,从此处向后找 /0,长度为6
printf("%d\n", strlen(p+1)); //p+1是第二个元素b的地址,从此处向后找 /0,长度为5
printf("%d\n", strlen(*p)); //*p是第一个元素 a,它的ASCII码值为97,此时就是那97作为初始地址向后访问 /0 ,此时属于非法访问了,所以程序错误
printf("%d\n", strlen(p[0])); //p[0]相当于 *(p+0) 就是*p,和上一个一样,程序错误
printf("%d\n", strlen(&p)); //相当于从p的地址处,向后找 /0 随机值
printf("%d\n", strlen(&p+1));//&p+1 是p的地址向后走一个字节的地址 随机值
printf("%d\n", strlen(&p[0]+1));//;p[0]是相当于*(p+0) , 加个& 与* 抵消 所以最后剩个p+1 和第二个一样 5
int a[3][4] = {0}; 二维数组可以看作是一维数组的数组
printf("%d\n",sizeof(a)); //a是在sizeof 内部,所以计算的是整个数组的大小, 3*4*4=48
printf("%d\n",sizeof(a[0][0])); //a[0][0]是第一行第一个元素, 4
printf("%d\n",sizeof(a[0])); //a[0]是第一行的数组名,数组名放sizeof内部就是计算整个第一行这个一维数组的大小 4*4=16
printf("%d\n",sizeof(a[0]+1)); //a[0]+1 a[0]是第一行数组名,它此时是第一行首元素的地址,它+1就是第一行第二个元素的地址,是地址, 4/8
printf("%d\n",sizeof(*(a[0]+1))); //a[0]+1是一行第二个元素的地址,解引用后就是第二个元素 4
printf("%d\n",sizeof(a+1)); //a是二维数组数组名,也就是首元素的地址,而把二维数组看作一维数组时,它的首元素地址就是第一行的地址,是地址 4/8
printf("%d\n",sizeof(*(a+1))); //a+1是第一行的地址,解引用后就是第一行(一维数组)的元素 16
printf("%d\n",sizeof(&a[0]+1)); //a[0]是第一行这个一维数组的数组名,就是第一行首元素的地址,&a[0]相当于取整个一维数组的地址,+1跳过第一行这个一维数组的地址,也就是第二行的地址,是地址 4/8
printf("%d\n",sizeof(*(&a[0]+1))); //解引用第二行的地址,就是第二行这个一维数组的全部元素 16
printf("%d\n",sizeof(*a)); //a是二维数组的首元素地址,相当于第一行的地址, 16
printf("%d\n",sizeof(a[3])); //a[3]看起来是数组越界了,但无关紧要,我sizeof()只看是啥类型啊,a[3] -> int [4] 这个数组类型的,所以就是 4*4=16