1

我有一个关于编译器如何存储 C 字符串的问题?这里有一些代码:

#define STRING_MACRO   "macro"
const char * string_const = "w";

int main(void){
    printf("%u\n", sizeof(STRING_MACRO));
    printf("%u\n", sizeof(string_const));

    return 0;
}

输出:

6

4 -- 我的系统是x86,所以是4

所以我对编译器如何存储c字符串感到困惑?宏样式和值样式之间是否相同?

我认为大多数人误解了我的问题。所以我自己尝试了另一个代码。

#define TEST "a"

int main(void)
{
    char hello[] = "aa";
    char (*a)[10] = &hello;

    printf("%u\n", sizeof(TEST));
    printf("%u\n", sizeof(hello));
    printf("%u\n", sizeof(*a));

    return 0;
}

输出:

2
3
10

所以我得出一个结论,编译器将宏样式的 c 字符串存储在 char[] 类型中,而不是 char * 类型中。

4

5 回答 5

3
sizeof(STRING_MACRO);

编译器将其视为:

sizeof("macro");

这为您提供了字符串文字“宏”的大小,字符串文字存储在实现定义的只读区域中。


const char * string_const = "w";

string_cost是指向字符串文字“w”的指针。

所以,

sizeof(string_const);

给出指针的大小,即const char *4您的系统上很明显。

于 2013-03-29T09:48:40.797 回答
2

该字符串"macro"在您的代码中定义为宏,而不是变量。

如果你用你构建你的代码,gcc -E你会得到一个前驱代码。在这段代码中你会发现

printf("%u\n", sizeof(STRING_MACRO);

被替换为

printf("%u\n", sizeof("macro"));

预处理器代码是编译器在编译之前生成的代码。在此代码中,编译器将原始代码中的宏替换为宏的内容。

而 for"w"是文字字符串,string_const是指向该文字字符串的指针。32 位系统的指针大小为 4,64 位系统的指针大小为 8。

于 2013-03-29T09:47:15.733 回答
2

sizeof() 返回对象的内存大小。

#define STRING_MACRO   "macro"

这是 6,因为编译器为 'macro' (5) + (1) 为字符串终止符分配了 6 个字节

const char * string_const = "w";

这是 4,因为它是一个指针,并且您在 32 位平台上工作,因此指向 char 的指针需要 4 个字节。

于 2013-03-29T09:49:33.677 回答
0

编译器不存储任何东西。它在解析期间评估常量的大小。Size ofSTRING_MACRO被评估为字符串的长度 + 终止符 ( \0)。大小string_const被评估为指针的大小(因为它就是这样),在您的系统上,指针大小为 4 个字节(对应于 32 位系统)。

于 2013-03-29T09:49:04.220 回答
0

在您的第二个代码中,

  • TEST只不过是一段代码的名称a,即文字. 此名称在预处理器阶段扩展为实际代码。
  • 所有字符串文字都以 NULL 结尾。这就是为什么,

sizeof("a") =   1   // the size of the character 'a'
              + 1   // size of the '\0' character 
             -----
              = 2

  • “a”和“aa”存储在内存的只读部分(实现定义)。
  • hello存储在堆栈中,它指向存储“aa”的内存的只读部分。
  • 由于hello被声明为字符数组(其大小隐式为 3,因为没有显式指定大小),sizeof(hello)= 数组长度 = 长度(“aa\0”)= 3。
  • a是一个指向长度为 10 的字符数组的指针。
  • sizeof(a)将是 4(在您的 x86 系统中),因为a它是一个指针。
  • sizeof(*a)= 10 因为*a是长度为 10 的字符数组的基指针。
于 2013-03-29T11:24:00.307 回答