关于数组名 | ||
数组名是数组首元素的地址 | ||
但是有2个例外: | ||
1. sizeof(数组名) - 数组名表示整个数组,计算的是整个数组的大小,单位是字节 | ||
2. &数组名 - 数组名也表示整个数组,取出的是整个数组的地址 | ||
除了这个2个例外,你见到的所有的数组名都表示首元素的地址 |
//
一维数组
int
a
[]
=
{
1
,
2
,
3
,
4
};
printf
(
"%d\n"
,
sizeof
(
a
));
//a单独放在sizeof内部表示整个数组,所以是4*4=
16
个字节
printf
(
"%d\n"
,
sizeof
(
a
+
0
));
//a代表数组首元素地址,加0仍指向数组首元素,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
*
a
));
//a代表数组首元素地址,*a是第一个整数,所以是
4
个字节
printf
(
"%d\n"
,
sizeof
(
a
+
1
));
//a代表数组首元素地址,a+1代表第二个元素的地址,所以是
4/8
个 字节
printf
(
"%d\n"
,
sizeof
(
a
[
1
]));
//a[1]是第二个元素,是整形元素,所以是
4
个字节
printf
(
"%d\n"
,
sizeof
(
&
a
));
//&a是整个数组的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
*&
a
));
//*&a即为a,a单独放在sizeof内部表示整个数组,所以是4*4=
16
个字 节
printf
(
"%d\n"
,
sizeof
(
&
a
+
1
));
//&a是整个数组的地址,&a+1即跳过整个数组,但仍是地址,所以 是
4/8
个字节
![](https://i-blog.csdnimg.cn/blog_migrate/8d483b50b0fa92f11de268ef1cd9714c.png)
printf
(
"%d\n"
,
sizeof
(
&
a
[
0
]));
//a[0]是首元素,&a[0]是首元素的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
a
[
0
]
+
1
));
//a[0]是首元素,&a[0]是首元素的地址,&a[0]+1是第二个元素的地 址,所以是
4/8
个字节
sizeof 是计算对象或者类型创建的对象所占内存空间的大小,单位是字节 | ||
sizeof 是操作符,不是函数 | ||
strlen 求字符串长度的,计算的是字符串中\0之前出现的字符的个数 | ||
/统计到\0为止,如果没有看到\0,会继续往后找 | ||
strlen 是库函数 | ||
stelen的()里放的必须是地址,如果是一个数则会将那个数的ASCII码值当成了地址 | ||
//
字符数组
char
arr
[]
=
{
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
//数组中只有6个元素无’\0‘
printf
(
"%d\n"
,
sizeof
(
arr
));
//arr单独放在sizeof内部表示整个数组,所以是1*6=
6
个字节
printf
(
"%d\n"
,
sizeof
(
arr
+
0
));
//arr代表数组首元素地址,加0仍指向数组首元素,所以是
4/8
个字 节
printf
(
"%d\n"
,
sizeof
(
*
arr
));
//arr代表数组首元素地址,*arr是第一个元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
arr
[
1
]));
//arr[1]是第二个元素,是char型元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
));
//&arr是整个数组的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
+
1
));
//&arr是整个数组的地址,&arr+1即跳过整个数组,但仍是地址, 所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
[
0
]
+
1
));
//arr[0]是首元素,&arr[0]是首元素的地址,&arr[0]+1是第二个元 素的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
strlen
(
arr
));
//arr是数组名表示数组首元素地址,strlen计算的是字符串中\0之 前出现的字符的个数,数组中,没有\0所以是
随机值
printf
(
"%d\n"
,
strlen
(
arr
+
0
));
//arr+0也是数组名表示数组首元素地址,strlen计算的是字符串中\0 之前出现的字符的个数,数组中,没有\0所以是
随机值
printf
(
"%d\n"
,
strlen
(
*
arr
));
//arr是数组名表示数组首元素地址,*arr是第一个元素即'a',a的 ASCII码值 97被 当成了地址,会非法访问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
arr
[
1
]));
//
arr是第二个元素即'b',b的ASCII码值 98被 当成了地址,会非法访 问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
&
arr
));
//&arr是整个数组的地址,但strlen计算的是字符串中\0之 前出现的字符的个数,数组中,没有\0所以是
随机值
printf
(
"%d\n"
,
strlen
(
&
arr
+
1
));
//&arr是整个数组的地址,&arr+1即跳过整个数组,但仍是地址, 数组中,没有\0所以是
随机值
printf
(
"%d\n"
,
strlen
(
&
arr
[
0
]
+
1
));
//arr[0]是首元素,&arr[0]是首元素的地址,&arr[0]+1是第二个元 素的地址,所以是
随机值
char
arr
[]
=
"abcdef"
;
//数组中包含’\0'
printf
(
"%d\n"
,
sizeof
(
arr
));
//arr单独放在sizeof内部表示整个数组,所以是1*7=
7
个字节
printf
(
"%d\n"
,
sizeof
(
arr
+
0
));
//arr代表数组首元素地址,加0仍指向数组首元素,所以是
4/8
个字 节
printf
(
"%d\n"
,
sizeof
(
*
arr
));
//arr代表数组首元素地址,*arr是第一个元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
arr
[
1
]));
//arr[1]是第二个元素,是char型元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
));
//&arr是整个数组的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
+
1
));
//&arr是整个数组的地址,&arr+1即跳过整个数组,但仍是地址, 所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
arr
[
0
]
+
1
));
//arr[0]是首元素,&arr[0]是首元素的地址,&arr[0]+1是第二个元 素的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
strlen
(
arr
));
//arr表示数组首元素地址,共6个字符类型元素,所以
6
是个字节
printf
(
"%d\n"
,
strlen
(
arr
+
0
));
//arr+0表示数组首元素地址,共6个字符类型元素,所以
6
是个字节
printf
(
"%d\n"
,
strlen
(
*
arr
));
//arr是数组名表示数组首元素地址,*arr是第一个元素即'a',a的 ASCII码值 97被 当成了地址,会非法访问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
arr
[
1
]));
//
arr是第二个元素即'b',b的ASCII码值 98被 当成了地址,会非法访 问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
&
arr
));
//&arr是整个数组的地址,strlen计算的是字符串中\0之前出现的字 符的个数,所以是6个字节
printf
(
"%d\n"
,
strlen
(
&
arr
+
1
));
//&arr是整个数组的地址,&arr+1即跳过整个数组,但 数组中仍然没有\0所以是
随机值
printf
(
"%d\n"
,
strlen
(
&
arr
[
0
]
+
1
));
//arr[0]是首元素,&arr[0]是首元素的地址,&arr[0]+1是第二个元 素的地址,所以是
5
个字节
char *
p
=
"abcdef"
;
printf
(
"%d\n"
,
sizeof
(
p
));
//p是指针变量,存放的是首元素的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
p
+
1
));
//p+1表示第二个元素的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
*
p
));
//*p即第一个元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
p
[
0
]));
//p[0]=*(p+0)=*p,也是第一个元素,所以是
1
个字节
printf
(
"%d\n"
,
sizeof
(
&
p
));
//char* *pp=&p,是p的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
p
+
1
));
//&p+1还是地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
&
p
[
0
]
+
1
));
//p[0]是首元素,&p[0]是首元素地址&p[0]+1是第二个元素的地址, 所以是
4/8
个字节
printf
(
"%d\n"
,
strlen
(
p
));
//p表示数组首元素地址,共6个字符类型元素,所以
6
是个字节
printf
(
"%d\n"
,
strlen
(
p
+
1
));
//p+1表示数组第二个元素地址,共5个字符类型元素,所以
5
是个字节
printf
(
"%d\n"
,
strlen
(
*
p
));
//p是数组名表示数组首元素地址,*是p第一个元素即'a',a的 ASCII码值 97被 当成了地址,会非法访问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
p
[
0
]));
//p[0]=*(p+0)=*p,也是第一个元素,a的ASCII码值 97被 当成了地址, 会非法访问,所以会报错,
err
printf
(
"%d\n"
,
strlen
(
&
p
));
//char* *pp=&p,是p的地址,是
随机值
printf
(
"%d\n"
,
strlen
(
&
p
+
1
));
//&p+1是p后面的地址,所以是
随机值
printf
(
"%d\n"
,
strlen
(
&
p
[
0
]
+
1
));
//p[0]是首元素,&p[0]是首元素地址&p[0]+1是第二个元素的地址, 所以是
5
个字节
//
二维数组
int
a
[
3
][
4
]
=
{
0
};
printf
(
"%d\n"
,
sizeof
(
a
));
//数组名单独放在sizeof内表示整个数组的地址,即4*3*4=
48
个字符
printf
(
"%d\n"
,
sizeof
(
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]作为第一行的数组名并非表示整个第一行这个数组时a[0]就是 第一行首元素的地址,a[0]+1,跳过一个int,是a[0][1]的地址
4/8
字节
printf
(
"%d\n"
,
sizeof
(
*
(
a
[
0
]
+
1
)));
//a[0]+1==a[0][1]的地址,*(a[0]+1)即a[0][1],所以是
4
个字节
printf
(
"%d\n"
,
sizeof
(
a
+
1
)); /
/a是二维数组的数组名,没单独放在sizeof内部,也没有&,所以 a就是数组首元素的地址,二维数组在内存中是一行,所以我们 把二维数组想象成一维数组,第一行就是首元素,a+1是第二行 的地址,所以是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
*
(
a
+
1
)));
//a+是第二行的地址,*(a+1)就是第二行所有元素,所有是 4*4=
16
个字节
printf
(
"%d\n"
,
sizeof
(
&
a
[
0
]
+
1
));
//&a[0]是第一行的地址,&a[0]+1就是第二行的地址, sizeof(&a[0] + 1)计算的第二行地址大小,是
4/8
个字节
printf
(
"%d\n"
,
sizeof
(
*
(
&
a
[
0
]
+
1
)));
//&a[0]是第一行的地址,&a[0]+1就是第二行的地址,*(&a[0]+1) 就是第二行所有元素,是4*4=
16
个字节
printf
(
"%d\n"
,
sizeof
(
*
a
));
//a表示首元素的地址,就是第一行的地址。*a 拿到的就是第一行 大小就是
16
个字节
printf
(
"%d\n"
,
sizeof
(
a
[
3
]));
//a[3]是二维数组的第4行,虽然没有第四行,但是类型能够确定, 是
16
个字节