目录
练习
一维数组
1、整形数组
int main()
{
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a)); 16
sizeof(a + 0); 4
sizeof(*a); 4
sizeof(a + 1); 4
sizeof(a[1]); 4
sizeof(&a); 4
sizeof(*&a); 16
sizeof(&a + 1); 4
sizeof(&a[0]); 4
sizeof(&a[0] + 1); 4
return 0;
}
11、int类型的数组,4个元素,每个元素大小是4个字节。sizeof (数组名),计算的是整个数组总大小,单位是字节,16个字节。
22、对于数组名的使用:
sizeof(数组名)
&数组名
只有这两个数组名代表整个数组,其他都是首元素地址。所以是4/8个字节。
33、对a解引用,拿到的是首元素地址,所以是4
44、a + 1,也就是第二个元素,所以还是4/8个字节
55、a[1]不必多写
66、&a, 取出的是数组的地址,地址大小就是4/8个字节,看平台。
77、*&a。拿出a的地址,然后解引用,其实也就是求整个数组的大小,和第一个一样,16
88、&a + 1,数组的地址+1,也就是从起始位置越过一整个数组,但实际上还是个地址,所以就是4/8个字节。
剩下两个,取出第一个元素的地址,和+1,都一样,4/8。
2、字符数组
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n", sizeof(arr)); 6
sizeof(arr + 0); 4
sizeof(*arr); 1
sizeof(arr[1]); 1
sizeof(&arr); 4
sizeof(&arr + 1); 4
sizeof(&arr[0] + 1); 4
return 0;
}
参考上面即可。
现在换一下,把sizeof换成strlen
int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n", strlen(arr));
strlen(arr + 0);
strlen(*arr);
strlen(arr[1]);
strlen(&arr);
strlen(&arr + 1);
strlen(&arr[0] + 1);
return 0;
}
11、随机值。strlen需要找到\0才会停止,所以求出的字符串长度也就是随机值。strlen(arr),arr表示的是首元素地址,从头开始往后找0。
22、+0还是一样,所以还是首元素地址。
33、非法访问地址。strlen需要的是一个地址,而*arr是解引用首元素地址,得到首元素,也就是'a'。a的ANSCII码值是97,也就是strlen会把97当作一个地址,往后访问,也就造成了非法访问地址。这样的代码不可写,程序会崩溃,访问97在内存中的地址时会发生访问冲突。
44、把'b'传了过去。也是崩溃
剩下三个,&arr也就是首元素地址,还是随机值。&arr + 1,从'f'之后开始找0,也是随机值,不过能知道的是,这两个差值是整个字符数组。&arr[0] + 1,是从'a'开始的,&arr是从'a'之前开始的,所以也能知道随机值之间的差值。
3、常量字符串
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); 7
sizeof(arr + 0); 4/8
sizeof(*arr); 1
sizeof(arr[1]); 1
sizeof(&arr); 4
sizeof(&arr + 1); 4
sizeof(&arr[0] + 1); 4
return 0;
}
11、arr里面放着一个字符串,sizeof读取,知道\0为止,所以为7
22、arr在里面是首元素地址,所以还是地址的大小,4/8
33、*arr,arr首元素地址,解引用后找到首元素,就是1了
44、arr[1]
55、&arr,是地址,所以4/8
66、&arr + 1,一样,还是地址,所以4/8
77、&arr[0] + 1,指向的是b,还是地址。4/8
现在换成strlen
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen(arr)); 6
strlen(arr + 0); 6
strlen(*arr); err
strlen(arr[1]); err
strlen(&arr); 6
strlen(&arr + 1); 随机值
strlen(&arr[0] + 1); 5
return 0;
}
33、*arr 是首元素a的地址,所以97还是被strlen当成了地址,所以越界访问
44、一样,第二个元素
55、&arr,数组的地址。如果把他放到一个数组指针,那就是char (*p) [7] = &arr。所以类型就是char (*) [7]。但是这个strlen函数的类型不同,不兼容,所以会有警告。不过强行这么也可以,把&arr就当成一个地址看。所以是6。
66、&arr + 1,随机值
77、 &arr[0] + 1,从b开始数,所以是5。
如果换成*p,sizeof
int main()
{
const char *p = "abcdef";
printf("%d\n", sizeof(p)); 4
sizeof(p + 1); 4
sizeof(*p); 1
sizeof(p[0]); 1
sizeof(&p); 4
sizeof(&p + 1); 4
sizeof(&p[0] + 1); 4
return 0;
}
*p存储的是a的地址,然后通过a指向整个字符串。
11、p也就是一个地址,所以是4/8
22、p + 1计算的是字符b,所以还是4/8
33、 *p就是字符串第一个字符,就是a,所以是1
44、访问数组某个元素时,arr[0], 也可以写作*arr,*(arr + 0),所以p[0]也就是*(p + 0),所以还是首元素地址,所以还是1。
55、取出p的地址,所以是4/8
66、&p+1,从p起始位置开始+1,也就是越过了一整个p所占据的空间,但最后还是地址,所以4/8
77、也是地址
换成strlen
int main()
{
const char *p = "abcdef";
printf("%d\n", strlen(p)); 6
strlen(p + 1); 5
strlen(*p); err报错
strlen(p[0]); err
strlen(&p); 随机值
strlen(&p + 1); 随机值
strlen(&p[0] + 1); 5
return 0;
}
&p,取出的是首元素地址,去计算,p的地址不同编译器有不同的地址,看地址:0x0043ff11,在内存中存储时就是11 ff 43 00,所以一个个字符读,读完前三个,遇到0,所以最终数值是3,所以这是个不定的数值。
&p + 1也一样随机值
&p[0] + 1,拿出首元素+1,也就是从b开始数,所以是5。
下一篇写二维数组
结束。