1

我正在学习 C 为 Linux 开发,我正在尝试从作为函数参数的数组中获取sizeof() 。sizeof总是返回 8(即指针的大小)所以问题是,在 C 中所有参数都是指针吗?如果不是这段代码有什么问题?

#include <stdio.h>
#include <stdlib.h>

int println(char text[]);

int main()
{
        char text[] = "Helloabc";
        int x = println(text);
        x = x + 48;
        char y[] = { (char)x };
        printf("%s\n", y);
        return 0;
}

int println(char text[])
{
        int size = sizeof(text) / sizeof(text[0]);
        int size1 = sizeof(text);
        int size2 = sizeof(text[0]);
        printf("%i\n", size1);
        printf("%i\n", size2);
        return size;
}

这段代码产生了这个返回:

8
1
8Helloabc

这也是出于某种奇怪的原因打印“Helloabc”。

4

3 回答 3

3

通常,数组与指针不同。但是,当作为参数传递时,数组将转换为指针。如果要获取数组的大小,则应将其作为另一个参数传递,或者在数组中设置一个哨兵并手动计算大小。

至于为什么要打印“Helloabc”,那是因为你的字符串char y[]没有\0结尾。因此,当您将printfy 作为字符串(通过%s)时,它会继续运行,直到找到\0.

那时会发生什么?注意x、y和text都在栈上,栈是从高内存到低内存的。所以你的堆栈现在看起来像这样: 堆

(我放了一个错误的例子,发现不是这样,对不起。现在我修好了。)

所以,printf首先输出0x38('8'). 然后继续“Helloabc”,最后找到'\0'.

这就是你得到“8Helloabc”的原因。

于 2013-07-12T05:25:09.693 回答
2

1) 首先,在 C 中,并非每个参数都是指针。

2) sizeof 以字节为单位返回数据类型的大小。

3) 这里,size1 是指向字符数组的指针的大小。请参阅评论部分中 Aaron 的回复。我的错。我需要复习一下我的C。

4) size2 是字符数组中字符的大小。由于一个字符占用 1 个字节,因此 size2 = 1。

5) 打印 y 时得到“8Helloabc”的原因是因为在 C 中,字符串必须以空值结尾。也就是说,字符串必须以字符 '\0' 结尾。否则,printf 函数将不知道何时“停止”读取和打印字符。

该行char text[] = "Helloabc";隐含地在数组末尾添加了一个空字符“\0”。但是您的代码char y[] = { (char)x };没有。

碰巧“Helloabc”字符串存储在内存中y的值“之后”,因此printf读取了“8”的值并继续打印,直到它到达“helloabc”末尾的空字符。有时您可能没有那么幸运,并且当 printf 尝试读取的内存未正确填充时,打印 y 可能会给您带来垃圾或分段错误。

只需将您的代码更改为:char y[] = {(char) x, '\0'};让它只打印出 x 的值。

于 2013-07-12T05:40:37.343 回答
1

当数组的名称作为函数参数出现时,编译器会将其隐式转换为指向数组第一个元素的指针。因此,函数的对应参数始终是指向与数组元素类型相同的对象类型的指针。

int size1 = sizeof(text);表达式sizeof(text)返回指针的大小,这个大小取决于平台,32 位(4 字节)和 64 位(8 字节)。

int size2 = sizeof(text[0]);变量 size2 接收 type 中数组的第一个元素的char大小,其大小为 1 字节。

char text[] = "Helloabc";必须为空终止才能正确打印。

于 2013-07-12T05:42:49.817 回答