我正在学习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”。
答案 0 :(得分:3)
通常,数组与指针不同。但是,作为参数传递时,数组将转换为指针。如果你想获得数组的大小,你应该将它作为另一个参数传递,或者在数组中设置一个sentinel并手动计算大小。
至于为什么要打印“Helloabc”,这是因为你的char y[]
没有\0
作为字符串的结尾。因此,当您printf
y为字符串(通过%s
)时,它会一直运行,直到找到\0
。
接下来会发生什么?请注意,x,y和文本都在堆栈中,堆栈是从高内存到低内存。所以你的堆栈现在看起来像这样:
(我举了一个错误的例子,发现它不是那样的,抱歉。现在我修好了。)
因此,printf
首先输出0x38('8')
。然后继续“Helloabc”,最后找到'\0'
。
这就是你得到“8Helloabc”的原因。
答案 1 :(得分: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尝试读取的内容没有正确填充时,打印可能会给你垃圾或分段错误。
只需将您的代码更改为:char y[] = {(char) x, '\0'};
只打印出x的值。
答案 2 :(得分:1)
当数组的名称显示为函数参数时,编译器会将其隐式转换为指向数组第一个元素的指针。因此,函数的相应参数始终是指向与数组元素类型相同的对象类型的指针。
int size1 = sizeof(text);
表达式sizeof(text)
返回指针的大小,这个大小取决于平台,32位是(4字节),64位是(8字节)。
int size2 = sizeof(text[0]);
变量size2接收类型char
中数组的第一个元素的大小,其大小为1个字节。
char text[] = "Helloabc";
必须为空终止才能正确打印。