C: 如何正确声明字符串数组?

发布于 2024-07-29 00:47:19 字数 506 浏览 3 评论 0原文

我看到了 :

const char*  arr = {"foo", "bar"};

const char*  arr[] = {"foo", "bar"};

什么是正确且普遍标准的方法?

两者有什么区别?

什么区别

   const char**arr = {"foo", "bar"};

    const char* arr[] = {"foo", "bar"};
 

和 和

   const char* * const arr = {"foo", "bar"};    

   const char* const * const arr = {"foo", "bar"};

I saw both :

const char*  arr = {"foo", "bar"};

and

const char*  arr[] = {"foo", "bar"};

What is the correct and generally standard way?

What is the difference between two?

what is the difference between

   const char**arr = {"foo", "bar"};

and

    const char* arr[] = {"foo", "bar"};
 

and

   const char* * const arr = {"foo", "bar"};    

and

   const char* const * const arr = {"foo", "bar"};

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

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

发布评论

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

评论(4

白云不回头 2024-08-05 00:47:19

这是不正确的,因为它没有正确的间接级别。

const char* arr = {"foo", "bar"};

这是不正确的,因为它缺少 =。 它看起来有点像函数定义。

const char* arr[] {"foo", "bar"};

这是通常的正确形式。

const char* arr[] = { "foo", "bar" };

编辑

您无法从聚合初始值设定项(即 { ..., ..., ... } )初始化指针。 你可以两者都做

const char* str1 = "A string";

const char str2[] = "Another string";

但这是不同的。

字符串文字的类型为“n 个字符的数组”,因此可以转换为指针,而初始化列表实际上不是数组,它只是初始化数组的一种方法。

This is not correct as it doesn't have the correct level of indirection.

const char* arr = {"foo", "bar"};

This is not correct as it's missing an =. It looks a bit like a function definition.

const char* arr[] {"foo", "bar"};

This is the usual correct form.

const char* arr[] = { "foo", "bar" };

Edit

You can't initialize a pointer from an aggregate initializer (i.e. { ..., ..., ... } ). You can do both

const char* str1 = "A string";

and

const char str2[] = "Another string";

but this is different.

A string literal has type 'array of n char' so can be converted to a pointer whereas an initializer list isn't actually an array, it's just a way to initialize arrays.

硬不硬你别怂 2024-08-05 00:47:19

关于常量...

const char* constValue = "foo";
constValue = "bar";
constValue[0] = 'x'; // will not work

char* const constPtr = "foo";
constPtr = "bar"; // will not work
constPtr[0] = 'x';

const char* const arr[] = { "foo", "bar", 0 }; // all const

“const char* const”通常是完全恒定的最佳解决方案。 另一种优化是,如果在本地作用域中声明它,则也将其设为静态。 0 ptr 对于哨兵值很有用。

With respect to constness...

const char* constValue = "foo";
constValue = "bar";
constValue[0] = 'x'; // will not work

char* const constPtr = "foo";
constPtr = "bar"; // will not work
constPtr[0] = 'x';

const char* const arr[] = { "foo", "bar", 0 }; // all const

'const char* const' is is often the best solution for something fully constant. One more optimization would be to also make this static if it is declared in a local scope. The 0 ptr is useful for a sentinel value.

有几种方法。 最简单的是声明一个 char 数组的数组,如下所示:

char strs[N][M + 1]; // M is max length of each string
...
strcpy(strs[i], "foo");

字符串的所有内存都是静态分配的,但数组中每个字符串的大小是固定的,并且您必须为最长的字符串确定大小,这可能导致一些内部碎片。 所有字符串都是可写的。

另一种方法是声明一个指向 char 的指针数组:

char *strs[N];
...
strs[i] = malloc(strlen("bar") + 1);
if (strs[i]) 
  strcpy(strs[i], "bar"); 

这样您可以根据数组中每个字符串需要的大小分配内存,并且可以根据需要调整字符串的大小。 您也可以只指向字符串文字,但请记住文字可能不可写; 即,您可能无法执行以下操作:

strs[j] = "foo";
strs[j][0] = 'b'; // may not be allowed on string literal

您可以动态分配整个粉碎:

char **strs = malloc(sizeof *strs * N);
for (i = 0; i < N; i++)
  strs[i] = malloc(SIZE + 1);

这种方法不仅允许您根据需要调整每个字符串的大小,还可以调整字符串的数量。 请注意,在这种情况下,strs不是数组类型,即使它被视为数组。

请注意,C 和 C++ 之间关于 malloc() 的最佳实践有所不同。 在 C 中,强制转换 malloc() 的结果被认为是不好的做法。 一方面,这是不必要的,因为 void 指针会隐式转换为其他对象指针类型。 另一方面,如果您忘记 #include stdlib.h 或者范围内没有 malloc() 的原型,它将抑制诊断。 请记住,如果 C 在引用函数之前没有看到该函数的原型,它将假定该函数返回 int,而该函数不能隐式转换为指针类型。

There are several approaches. The simplest is to declare an array of arrays of char, like so:

char strs[N][M + 1]; // M is max length of each string
...
strcpy(strs[i], "foo");

All the memory for the strings is statically allocated, but the size of each string in the array is fixed, and you have to size for your longest possible string, which may result in some internal fragmentation. All strings are writable.

Another approach is to declare an array of pointers to char:

char *strs[N];
...
strs[i] = malloc(strlen("bar") + 1);
if (strs[i]) 
  strcpy(strs[i], "bar"); 

This way you can allocate as much or as little memory as each string in the array needs, and you can resize your strings if necessary. You can also just point to string literals, but remember that literals may not be writable; i.e., you may not be able to do something like:

strs[j] = "foo";
strs[j][0] = 'b'; // may not be allowed on string literal

You can dynamically allocate the whole smash:

char **strs = malloc(sizeof *strs * N);
for (i = 0; i < N; i++)
  strs[i] = malloc(SIZE + 1);

This approach allows you to not only resize each string as necessary, but to resize the number of strings. Note that in this case, strs is not an array type, even though it is being treated as an array.

Note that best practices with respect to malloc() differ between C and C++. In C, it's considered bad practice to cast the result of malloc(). For one thing, it's unnecessary, as void pointers are implicitly cast to other object pointer types. For another, it will supress a diagnostic if you forget to #include stdlib.h or otherwise don't have a prototype for malloc() in scope. Remember that if C doesn't see a prototype for a function before it is referenced, it will assume that the function returns int, which cannot be implicitly converted to a pointer type.

挽清梦 2024-08-05 00:47:19

通常,如果可能的话,我在这里使用动态内存。 我发现考虑指针比考虑数组类型更简单。

//Allocate pointers for the strings
char **c = (char**)malloc(maxnumofstrs*sizeof(int));
//allocate memory for each string
for(int i = 0; i < maxnumofstrs; i++)
{
   c[i] = (char*)malloc(maxwidth);
}

Typically, I use dynamic memory if possible here. I find it is simpler to think about pointers than fighting with the array type.

//Allocate pointers for the strings
char **c = (char**)malloc(maxnumofstrs*sizeof(int));
//allocate memory for each string
for(int i = 0; i < maxnumofstrs; i++)
{
   c[i] = (char*)malloc(maxwidth);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文