问题描述
很抱歉,如果这是一个愚蠢的问题。我试图自学一些编程,但是这里有些混乱。代码:
#include <stdio.h>
void main()
{
int i;
char *array[5]={"Apples","mangoes","grapes","bananas","oranges"};
printf("THIS IS FROM THE ARRAY:\n");
for(i = 0; i < 5; i++)
{
printf("String=%s | ",array[i]);
printf("Address of string literal = %i",array[i]);
printf(" | Size = %u\n",sizeof(array[i]));
}
}
产生输出: Output Image
THIS IS FROM THE ARRAY:
String=Apples | Address of string literal = 4210688 | Size = 8
String=mangoes | Address of string literal = 4210695 | Size = 8
String=grapes | Address of string literal = 4210703 | Size = 8
String=bananas | Address of string literal = 4210710 | Size = 8
String=oranges | Address of string literal = 4210718 | Size = 8
尽管输出的sizeof表示大小为8,为什么地址之间的差异不是始终为8?
4210688 4210695(差异为7) 4210695 4210703(差异为8) 4210703 4210710(差异为7) 4210710 4210718(差异为8)
如果我的猜想是正确的(这些不是字符串在内存中的地址,而是指针的地址或其他东西),我将如何更改代码以列出实际字符串所在的地址记忆? 我在使用Code Blocks IDE,GNU GCC编译器的Windows 64位系统上。如果您需要更多相关信息,我们将很乐意为您提供。
解决方法
首先,在打印地址时,应使用%p
格式说明符并将参数转换为void *
。
也就是说,要打印的地址 是存储字符串的地址。如果仔细查看每个指针的地址之间的差异,您会发现这些差异与每个字符串的大小完全匹配。字符串文字通常存储在只读数据段中,在这种情况下,您的每个字符串在内存中都是连续的。
如果要打印每个数组元素的地址(每个数组元素都是一个指针),则每个数组元素之间的差值为8。
, sizeof(array[i])
为您提供char *
的大小,而不是字符串的长度。使用strlen()+1
作为字符串中的字节数。
对于6个字母的单词(+终止的NUL字符),7的差异非常有意义。
此外,正如chux所说,您应该使用%p
打印指针值(并且更正确的是,参数应强制转换为(void *)
)。
如果您打印char*
而不是strlen(array[i])
,则可以发现sizeof(array[i])
的数组是连续存在的。
main()
应该返回int。 void main()
不是标准。
您应该为数组声明const char*
,而不是char*
。它不可修改。
#include <stdio.h>
#include <string.h>
int main()
{
int i;
const char* array[5] = { "Apples","mangoes","grapes","bananas","oranges" };
printf("THIS IS FROM THE ARRAY:\n");
for (i = 0; i < 5; i++)
{
printf("String=%s | ",array[i]);
printf("Address of string literal = %i",array[i]);
printf(" | Size = %u\n",strlen(array[i]));
}
return 0;
}