目录
讨论数组名
sizeof & strlen
int a[] = {1, 2, 3, 4}
sizeof(a)
sizeof(a + 0)
sizeof(*a)
sizeof(a + 1)
sizeof(a[1])
sizeof(&a)
sizeof(*&a)
sizeof(&a + 1)
sizeof(&a[0])
sizeof(&a[0] + 1)
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'}
sizeof(arr)
sizeof(arr + 0)
sizeof(*arr)
sizeof(arr[1])
sizeof(&arr)
sizeof(&arr + 1)
sizeof(&arr[0] + 1)
♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥
strlen(arr)
strlen(arr + 0)
strlen(*arr)
strlen(arr[1])
strlen(&arr)
strlen(&arr + 1)
strlen(&arr[0] + 1)
char arr[] = "abcdef"
sizeof(arr)
sizeof(arr + 0)
sizeof(*arr)
sizeof(arr[1])
sizeof(&arr)
sizeof(&arr + 1)
sizeof(&arr[0] + 1)
♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥
strlen(arr)
strlen(arr + 0)
strlen(*arr)
strlen(arr[1])
strlen(&arr)
strlen(&arr + 1)
strlen(&arr[0] + 1)
char *p = "abcdef"
sizeof(p)
sizeof(p + 1)
sizeof(*p)
sizeof(p[0])
sizeof(&p)
sizeof(&p + 1)
sizeof(&p[0] + 1)
♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥
strlen(p)
strlen(p + 1)
strlen(*p)
strlen(p[0])
strlen(&p)
strlen(&p + 1)
strlen(&p[0] + 1)
int a[3][4] = {0}
sizeof(a)
sizeof(a[0][0])
sizeof(a[0])
sizeof(a[0] + 1)
sizeof(*(a[0] + 1))
sizeof(a + 1)
sizeof(*(a + 1))
sizeof(&a[0] + 1)
sizeof(*(&a[0] + 1))
sizeof(*a)
sizeof(a[3])
数组名通常表示的都是数组首元素的地址
但是有2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2. &数组名,这里的数组名表示的依然是整个数组,所以&数组名取出的是整个数组的地址
sizeof(数组名), 数组名表示整个数组,计算的是整个数组的大小,单位是字节
printf("%d\n", sizeof(a)); // 16
a不是单独放在sizeof内部,也没有取地址,所以a就是数组首元素的地址,指针地址的大小是4/8个字节,当前是64位,即8
printf("%d\n", sizeof(a + 0)); // 8
a代表数组首元素地址,解引用得到第一个int值,int是 4 个字节
printf("%d\n", sizeof(*a)); // 4
a代表数组首元素地址,a+1,是第二个元素的地址,sizeof(a+1)就是地址的大小,4/8,当前64位,即8
printf("%d\n", sizeof(a + 1)); // 8
a[1] ——> *(a+1),也就是第二个int值的大小,同样是 4 个字节
printf("%d\n", sizeof(a[1])); // 4
&a 等同于 a+0,同样是指针地址的大小,即4/8个字节,当前是64位,即8,(如果去掉&,大小就是16)
printf("%d\n", sizeof(&a)); // 8
*和& 可以看做同时抵消,只剩a,那么就是整个数组的大小(&a-->int(*)[4],&a拿到的是数组名的地址,类型是int(*)[4],是一种数组指针,数组指针解引用找到的是数组,*&a-->a)
printf("%d\n", sizeof(*&a)); // 16
&a取出是数组的地址,&a+1 跳过了整个数组的字节(16)所指向的地址,但同样是指针的大小,即4/8个字节,当前是64位,即8
printf("%d\n", sizeof(&a + 1)); // 8
第一个元素的地址大小.同样是指针地址的大小,即4/8个字节,当前是64位,即8
printf("%d\n", sizeof(&a[0])); // 8
第二个元素的地址大小,同样是指针地址的大小,即4/8个字节,当前是64位,即8
sizeof(&a[0] + 1)
printf("%d\n", sizeof(arr)); // 6
printf("%d\n", sizeof(arr + 0)); // 8 首元素地址大小,4/8
printf("%d\n", sizeof(*arr)); // 1 首元素地址解引用,a的字节大小
printf("%d\n", sizeof(arr[1])); // 1 第2个元素大小
printf("%d\n", sizeof(&arr)); // 8 取数组的地址,地址就是地址,4/8
printf("%d\n", sizeof(&arr + 1)); // 8 跳过整个数组的地址,4/8
printf("%d\n", sizeof(&arr[0] + 1)); // 8 第2个元素的地址,4/8
printf("%d\n", strlen(arr)); // 随机值,找到 \0 才停止
printf("%d\n", strlen(arr + 0)); // 随机值,arr首元素地址+0还是首元素地址,等同于上式
报错, strlen接收字符指针作为参数,而 strlen(*arr) -- strlen('a') -- strlen(97),而97相当于是个野指针,并不属于a
printf("%d\n", strlen(*arr)); // error
报错,相当于 strlen('b') -- strlen(61) 同上也是野指针
printf("%d\n", strlen(arr[1])); // error
printf("%d\n", strlen(&arr)); // 随机值,取数组地址,本质也是首元素地址
printf("%d\n", strlen(&arr + 1)); // 随机值 - 6,&arr跳过整个数组取地址
rintf("%d\n", strlen(&arr[0] + 1)); // 随机值 - 1, &arr[0] 第一个元素地址
printf("%d\n", sizeof(arr)); // 7 这里默认补 \0
printf("%d\n", sizeof(arr + 0)); // 8 a的地址+0,还是a的地址,4/8
printf("%d\n", sizeof(*arr)); // 1 *arr就是元素a
printf("%d\n", sizeof(arr[1])); // 1 元素b
printf("%d\n", sizeof(&arr)); // 8,数组地址,4/8
printf("%d\n", sizeof(&arr + 1)); // 8,第一个元素a的地址 4/8
printf("%d\n", sizeof(&arr[0] + 1)); // 8 元素a的地址
/* 6 截取\0之前的字符个数 */
printf("%d\n", strlen(arr));
/* 6 同上 */
printf("%d\n", strlen(arr + 0));
/* 报错,同上上上上上 */
printf("%d\n", strlen(*arr));
/* 报错,同上上上上上 */
printf("%d\n", strlen(arr[1]));
/* 6 */
printf("%d\n", strlen(&arr));
/* 随机值 跳过整个数组,\0也会跳过,它不知道所指向的下个字符数组的地址个数有几个元素 */
printf("%d\n", strlen(&arr + 1));
/* 5 */
printf("%d\n", strlen(&arr[0] + 1));
/* 8 这里是指针变量的大小 */
printf("%d\n", sizeof(p));
/* 8 b的地址 */
printf("%d\n", sizeof(p + 1));
/* 1 */
printf("%d\n", sizeof(*p));
/* 1 p[0] == *(p + 0) */
printf("%d\n", sizeof(p[0]));
/* 8 指针变量大小 */
printf("%d\n", sizeof(&p));
/* 8 */
printf("%d\n", sizeof(&p + 1));
/* 8 */
printf("%d\n", sizeof(&p[0] + 1));
/* 6 */
printf("%d\n", strlen(p));
/* 5 */
printf("%d\n", strlen(p + 1));
/* 报错,*p == 96 */
printf("%d\n", strlen(*p));
/* 6 */
printf("%d\n", strlen(p[0]));
/* 随机值,p本身就是地址,再取地址,相当于取指针变量p的地址,两个地址之间毫无关系 */
printf("%d\n", strlen(&p));
/* 随机值 */
printf("%d\n", strlen(&p + 1));
/* 5 p[0] == 元素a,&a+1即5 */
printf("%d\n", strlen(&p[0] + 1));
/* 48 */
printf("%d\n", sizeof(a));
/* 4 */
printf("%d\n", sizeof(a[0][0]));
a[0]相当于第一个数组,只有一个数组名,计算当前数组的大小
printf("%d\n", sizeof(a[0])); // 16
arr[0]是表示首元素的地址,本质是数组名(又等于第一行数组首元素的地址),等同于第一个数组的arr+1。也就是第一行第二个元素的地址
printf("%d\n", sizeof(a[0] + 1)); // 8
第一行第二个元素的大小
printf("%d\n", sizeof(*(a[0] + 1))); // 4
a虽然是二维数组的地址,但是并没有单独放在sizeof内部,也没取地址,a表示首元素的地址,二维数组的首元素是它的第一行,a就是第一行的地址,+1跳过一行的数组,表示第二行的地址
printf("%d\n", sizeof(a + 1)); // 8
第二行数组地址的解引用,拿到了整个第二行,sizeof内只有数组名,求整个第二行数组的大小
printf("%d\n", sizeof(*(a + 1))); // 16
&a[0]对第一行的数组名取地址,拿出的是第一行的地址,&a[0]+1 得到的是第二行的地址
printf("%d\n", sizeof(&a[0] + 1)); // 8
第二行的地址解引用,得到第二行的数组名arr,sizeof内部只有arr,即计算整个第二行数组的大小
printf("%d\n", sizeof(*(&a[0] + 1))); // 16
解引用整个二维数组的地址,即解引用二维数组首元素第一行数组的地址,再解引用第一行的地址得到arr,只有arr,计算整个第一行数组大小
printf("%d\n", sizeof(*a)); // 16
超界不会真正访问第四行的,其会根据int类型,就可以推算到,等同于a[0]
printf("%d\n", sizeof(a[3])); // 16