C“字符串” init - 哪个更好?

发布于 2024-12-11 17:43:20 字数 104 浏览 0 评论 0原文

这两个初始化有什么区别?

char a[] = "string literal";

char *p  = "string literal";

What is the difference between these two initializations?

char a[] = "string literal";

char *p  = "string literal";

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

成熟稳重的好男人 2024-12-18 17:43:20

尽管两者看起来相似并且经常互换使用,但它们确实意味着不同的事情。第一行:

char a[] = "string literal"; 

... 创建一个足够大的数组来容纳字符串文字,包括其 NUL 终止符。它使用您指定的字符串文字初始化该数组。此版本的优点之一是可以稍后修改数组。此外,即使在编译时,数组的大小也是已知的,因此您可以使用 sizeof 运算符来确定其大小。例如:

printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size 
                                    // including the NUL terminator

第二行:

char *p  = "string literal"; 

... 只是设置一个指向字符串文字的指针。这比第一个版本更快,但有一个缺点,即不应更改文字,因为它可能驻留在标记为只读的页面中。您还有一个缺点,要知道字符串的长度,您需要使用 strlen() 函数,因为 sizeof 运算符只会为您提供指针变量。例如:

printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on
                                    // whether this is a 32-bit or 64-bit build
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not
                                    // including the NUL terminator

至于哪个更好,这取决于您将如何处理这些变量。如果不需要对字符串进行任何更改,请使用后者,但dochar *更改为const char *,这样您就不会意外地尝试更改所指向的字符。如果您确实打算更改数据,请使用以前基于数组的版本,它允许您在初始化后对数组进行更改。

Although the two look similar and are often used interchangeably, they do mean different things. The first line:

char a[] = "string literal"; 

... creates an array that is large enough to hold the string literal, including its NUL terminator. It initializes this array with the string literal you specified. One benefit of this version is that the array can be modified at a later time. Also, the array's size is known even at compile time, so you can use the sizeof operator to determine its size. For example:

printf("%u\n",unsigned(sizeof(a))); // Will display 15, which is the array's size 
                                    // including the NUL terminator

The second line:

char *p  = "string literal"; 

... just sets a pointer to point to a string literal. This is faster than the first version, but you have the drawback that the literal should not be changed, because it may reside in a page marked as read only. You also have the drawback that to know the length of the string, you will need to use the strlen() function, since the sizeof operator will just give you the size of the pointer variable. For example:

printf("%u\n",unsigned(sizeof(p))); // Will likely display 4 or 8, depending on
                                    // whether this is a 32-bit or 64-bit build
printf("%u\n",unsigned(strlen(p))); // Will display the correct length of 14, not
                                    // including the NUL terminator

As to which is better, it depends on what you will be doing with these variables. If you do not need to make any changes to the string, use the later, but do change the char * to a const char *, so that you don't accidently attempt making changes to the characters being pointed to. If you do intend to change the data, use the former array based version which allows you to make changes to the array after initialization.

夜司空 2024-12-18 17:43:20

每个都强制编译器在静态内存中创建一个(至少在概念上)只读的字符串文字。

然后第一个使用它来初始化数组的内容。字符串文字仅用于选择其大小并对其进行初始化。

第二个创建一个直接指向原始字符串本身的指针。

他们之间没有真正的更好或更坏。他们只是不同。例如,数组通常使用更多内存(有一个字符串文字,然后数组中有该字符串文字的完整副本)。然而,由于它是一个普通数组,因此您可以根据需要对其进行修改。

直接指向字符串文字的指针通常会节省一些内存。它还意味着您可以为指针分配不同的值,以便它(例如)在不同时间指向不同的字符串文字。但是,您不允许修改它指向的数据——这样做会产生未定义的行为。

Each forces the compiler to create a string literal in static memory that's (at least conceptually) read-only.

The first then uses that to initialize the contents of an array. The string literal is just used to pick its size, and to initialize it.

The second creates a pointer directly to the original string literal itself.

There is no real better or worse between them. They're just different. For example, the array usually uses more memory (there's a string literal, then there's a complete copy of the string literal in your array). Since it's an otherwise normal array, however, you can modify it if necessary.

The pointer directly to the string literal will often save some memory. It also means you can assign a different value to the pointer so that it (for example) points at different string literals at different times. You are not, however, allowed to modify the data it points at -- doing so will give undefined behavior.

醉酒的小男人 2024-12-18 17:43:20

取决于你需要什么。

char a[] = "string literal";

创建一个具有自动存储期限的可变字符数组。这是合法的:

a[0] = 'c';

另一方面...

char *p  = "string literal";

创建一个指向只读内存的指针。该声明实际上应该是

const char *p  = "string literal";

You can not合法地修改 p 指向的内容。

Depends on what you need.

char a[] = "string literal";

Creates a mutable character array with automatic storage duration. This is legal:

a[0] = 'c';

On the other hand...

char *p  = "string literal";

Creates a pointer to readonly memory. The declaration should really be

const char *p  = "string literal";

You cannot legally modify what p points to.

指尖上的星空 2024-12-18 17:43:20

第一个声明一个数组并填充它(通过逐个设置元素,直到包含结束空字节)。可以修改数组。

第二个声明一个指针,并通过将其设置为常量文字来填充它。您可以修改指针(例如,使其指向其他地方),但不能修改它所指向的常量字符串(在大多数系统上,常量字符串将被放入只读段中)。

The first declares an array and fill it (by setting the elements one by one, till the ending null byte included). The array can be modified.

The second declares a pointer, and fill it by setting it to a constant literal. You can modify the pointer (e.g. to make it point elsewhere), but you cannot modify the constant string (which on most systems will be put in a read only segment) pointed by it.

゛清羽墨安 2024-12-18 17:43:20

第一个为您提供一个充满您指定的数据的数组,第二个为您提供一个指向某个内存(通常是只读)的指针,其中包含您指定的数据。

为了使“你得到的”的差异更清楚,请尝试以下操作:

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

int main(void)
{
  char a[] = "string literal";
  char *b = "string literal";

  printf("a is %lu bytes, b is %lu\n", (unsigned long) sizeof a,
                                       (unsigned long) sizeof b);

  return EXIT_SUCCESS;
}

这是一个现场演示,其中包含上面的代码。

One gives you an array filled with the data you specify, the second gives you a pointer to some memory (typically read-only) somewhere, containing the data you specified.

To make the difference in "what you get" more clear, try this:

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

int main(void)
{
  char a[] = "string literal";
  char *b = "string literal";

  printf("a is %lu bytes, b is %lu\n", (unsigned long) sizeof a,
                                       (unsigned long) sizeof b);

  return EXIT_SUCCESS;
}

Here is a live demo with the above code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文