
void foo(int *arr) { printf("%d\n", sizeof arr); // 4 } int main(){ int arr[] = {1, 2, 3, 4, 5}; printf("%d\n", sizeof arr); // 20 foo(arr); } 对于上述代码的sizeof计算数组字节结果有些不太明白,arr很显然和arr[0]是等效的,为什么在主函数中计算arr的大小等于4?
1 ho121 2021-07-14 15:55:45 +08:00 via Android 数组传参后都是指针,指针大小在 32 位环境下是 4,64 位环境下是 8 |
3 qieqie 2021-07-14 15:59:15 +08:00 一个是指针一个是数组,第一个 arr 等效的是&arr[0] |
4 ipwx 2021-07-14 16:16:34 +08:00 首先,指针和数组不等效。。。楼主你想当然地信仰了一个错误观点。 sizeof(int*) == 4 sizeof(int[5]) == 20 |
5 3dwelcome 2021-07-14 16:17:29 +08:00 @JQiue “但是为什么 sizeof 在主函数中却是计算数组的所有元素大小” 因为 C/C++是类型推导语言,但是函数参数传递中,会丢失原来的类型。 你在两个函数里,分别用 typeid(arr).name()打一下类型名称就知道了,两者不一样。 |
6 thinkIn 2021-07-14 16:37:42 +08:00 via iPhone sizeof 一般是用 define 定义的,你可以看下原理,很简练 |
7 wudicgi 2021-07-14 16:45:13 +08:00 "arr 很显然和 arr[0]是等效的" 当然不是等效的,否则 sizeof(arr) / sizeof(arr[0]) 这种计算元素数量的方法还怎么工作 |
8 hanssx 2021-07-14 16:49:03 +08:00 |
9 lesismal 2021-07-14 17:04:26 +08:00 《 C 陷阱与缺陷》《 C 专家编程》《 C 和指针》了解一下 |
10 rshun 2021-07-14 17:06:12 +08:00 函数参数那个*arr 表示的是数组第一个元素,即 arr[0],所以你在函数内做 sizeof 的时候就是 4 你在 main 里面的做 sizeof,是数组的所有元素,所以是 4*5=20 |
11 echoechoin 2021-07-14 17:08:40 +08:00 数组传递到函数中会被转换为指针!!! 所以 sizeof (数组) != sizeof(指针) |
12 ho121 2021-07-14 17:10:22 +08:00 via Android @JQiue 主函数中,arr 依然是数组,所以 sizeof 的结果是数组大小。另一方面 arr 也可以作为表达式,它代表的是 arr 数组的首地址。 函数调用 foo(arr)中的 arr 是作为表达式出现的,所以是指针。sizeof arr 中的 arr 代表数组本身。 |
13 lesismal 2021-07-14 17:13:14 +08:00 国人写的印象中《 C 语言深度解剖》还不错,太久了,记不清了。还有本《狂人 C:程序员入门必备》我没看过,但是当初作者在论坛跟大家 PK 各种 C 问题,很多老伙计一块给提了不少勘误和意见,内容应该能靠谱些吧 刚还搜到一本日本人的《征服 C 指针》,也没读过,但是以前读过的一些日本作者的技术书籍,感觉都挺不错的 |
14 lesismal 2021-07-14 17:16:02 +08:00 多读几本好书就理解清楚了,C 的细节还挺多呢,这么零散着问,很难系统吸收知识点,建议猛读一下我推荐的那几本书 |
15 OliverDD 2021-07-14 17:52:14 +08:00 |
17 lakehylia 2021-07-14 18:21:09 +08:00 #include <cstdio> void f1(int a[5]) { printf("f1 sizeof %zu\n", sizeof(a)); } void f2(int a[]) { printf("f2 sizeof %zu\n", sizeof(a)); } void f3(int* a) { printf("f3 sizeof %zu\n", sizeof(a)); } int main() { int a[5]; f1(a); f2(a); f3(a); return 0; } //======== 运行结果 f1 sizeof 8 f2 sizeof 8 f3 sizeof 8 |
18 lakehylia 2021-07-14 18:29:20 +08:00 C 中数组不能按值传递的规则。 但是 c++里面,引用有奇效 void f4(int(&a)[5]) { printf("f4 sizeof %zu\n", sizeof(a)); // f4 sizeof 20 } |
19 agagega 2021-07-14 19:16:08 +08:00 via iPhone C 的数组不是指针,只是某些时候可以相互转换 |
20 LnTrx 2021-07-14 19:29:59 +08:00 在函数里无论是写成数组还是指针,实际上都是指针,数组大小的信息已经丢失了 https://www.geeksforgeeks.org/why-c-treats-array-parameters-as-pointers/ |
21 wwbfred 2021-07-14 20:00:10 +08:00 所以不喜欢用 C 数组,只是考题倒是很喜欢考。 你说它是个类型吧,它又不能传递;你说它不是类型吧,他还有自己的大小。 这种不一致的表现,放到别的地方,就叫做坑。 |
22 lonewolfakela 2021-07-15 09:34:22 +08:00 @thinkIn 啥,哪家编译器的 sizeof 是用 define 定义的? |
23 7075 2021-07-15 09:44:52 +08:00 C/C++数组传参,是传指针。在定义处,编译器有保留数组类型及数组长度的信息,所以可以用 sizeof 求长度。传参后参数类型转为指针,你 sizeof 求的是指针的 size 。 |
24 thinkIn 2021-07-15 10:14:25 +08:00 via iPhone @lonewolfakela 我表述有误,不过可以看看用宏定义的 sizeof,虽然有限制,但是对理解指针很有好处。可以参看这个讨论 https://stackoverflow.com/questions/14171117/implementation-of-sizeof-operator |