1
msg7086 2016-05-24 11:01:38 +08:00 1
sizeof 并没有计算数组的数量。
sizeof 是关键字,取的是源代码中预先给定的大小。 比如 int a[10]的大小是 40 ,因此 sizeof(a) 就是 40 。 也就是说, int size = sizeof(a); 经过编译以后会变成 int size = 40; 。 |
2
lsmgeb89 2016-05-24 11:11:29 +08:00
一句题外话,好像记得编译器会把数组元素的个数存在数组首地址前的 4 bytes 里。
|
3
wohenyingyu01 OP @msg7086 确实,突然发现原来声明数组的时候长度不能用变量表示……高级语言看多了,容易惯性思维哈哈。
|
4
msg7086 2016-05-24 11:25:42 +08:00
@wohenyingyu01
https://zh.wikipedia.org/wiki/C 语言#C99 支持不定长的数组,即数组长度可以在运行时决定,比如利用变量作为数组长度。声明时使用 int a[var] 的形式。 |
5
jonah 2016-05-24 11:25:43 +08:00 1
sizeof 是编译期行为。
|
6
am241 2016-05-24 11:31:29 +08:00 via Android 1
编译期间会保存,编译结束后就丢了。所以 sizeof 是语句而不是函数。
有个东西叫 countof ,是一个宏,可以了解一下。 |
7
stackpop 2016-05-24 11:32:24 +08:00
@wohenyingyu01
静态数组可以这么算,但是动态数组不行。 int* a = new int[100]; 并不能通过 a 推断出数组长度,另外函数接口通常的做法也是类似下面这样 int f(int * arr, int len) 需要同时提供地址和长度 并非一定不能用变量, int n = 10; int p[n]; 这样的语法是符合 C99 标准的,但是在 C++中似乎不合法, G++需要使用扩展-pedantic 才支持。具体你可以自己测试。 |
8
gamexg 2016-05-24 12:37:51 +08:00 via Android
最烦的就是每次传递一个数组,需要另行传递长度。
|
9
hitmanx 2016-05-24 13:04:18 +08:00 1
如果是分配在栈里的 fix 大小的数组,编译器在编译时就能知道大小,会直接替换为对应分配的代码。即使是动态数组,长度是在运行时才能确定的, heap manager 也会在申请时记录它的大小,要不然删除时(delete[])如果不知道当初分配了多大,怎么能知道要释放多少呢?至于它实现方式可以是多样的,可以像 2 楼说的,在返回的地址前额外分配一个 size_t 的大小来保存数组的长度,或者直接拿个表来存应该也可以
|
10
hitmanx 2016-05-24 13:10:23 +08:00
@hitmanx 好像跑题了。就 sizeof 来说,首先它是编译期的计算,其次编译器不光要知道长度,还需要用到它在内存中的排列方式,因为可能会有对齐存在,最后编译器还要帮我们在栈里预留这么大的空间,如果这些编译器都能帮我们搞定,你为啥觉得它会连大小都算不出来
|
11
wohenyingyu01 OP @stackpop 我那种申请方式数组储存在栈中,你用 new 数组就是在堆中了,这么一说来我就有点理解了,栈内存不能在运行时分配大小也符合逻辑。
这和动态静态数组没关系吧,比如 char string[]="USA"和 char *string2="USA", string 可以用 sizeof 判断而 string2 不可以,应该是数组类型和指针类型的差距。 int n = 10; int p[n]; 这个写法在 ANSI C 里面是不合法的,但是可以这样: const int n = 10; int p[n]; |
12
wohenyingyu01 OP @hitmanx 嗯嗯,但是貌似我看的好多 c 语言的书都没有提到它是如何记录长度的,大多只是告诉你就是这样用的,所以会隐约感到逻辑不对。
|
13
stackpop 2016-05-24 14:01:50 +08:00
|
14
but0n 2016-05-24 15:43:16 +08:00 via iPhone
当数组作为参数传递时会发生退化,所以数组长度需要另外传值
数组和指针的关系至今没弄懂 有人说,数组是不是指针的指针 |
15
hitmanx 2016-05-24 15:59:35 +08:00
@wohenyingyu01 有时间的话可以看看斯坦福的公开课<编程范式>,当初对我帮助巨大,尤其是假如你像我当初一样之前没有系统地学过编译原理、操作系统的话。你的这些疑问,里面都会讲到。
地址在这儿: http://open.163.com/special/opencourse/paradigms.html |
16
abutter 2016-05-24 16:03:31 +08:00
标准(或者说传统) C 中,数组的大小是编译时确定的,因为长度是确定的,类型长度也是确定的,所以遇到 sizeof 就是直接替换成其编译时确定的值。
|