我试图在c中创建一个字符串数组,如果我使用以下代码:

char (*a[2])[14];
a[0]="blah";
a[1]="hmm";

GCC给我“警告:来自不兼容的指针类型的赋值”。正确的做法是什么?

编辑:我很好奇为什么这应该给编译器警告,因为如果我做printf([1]);,它正确地打印“嗯”。


当前回答

每个元素都是指向其第一个字符的指针

const char *a[2] = {"blah", "hmm"};

其他回答

您的代码正在创建一个函数指针数组。试一试

char* a[size];

or

char a[size1][size2];

代替。

参见wikibooks关于数组和指针的内容

如果你不想跟踪数组中字符串的数量,并且想要遍历它们,只需在最后添加NULL字符串:

char *strings[]={ "one", "two", "three", NULL };

int i=0;
while(strings[i]) {
  printf("%s\n", strings[i]);
  //do something
  i++;
};

在ANSI C中:

char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";

如果您不想更改字符串,那么您可以简单地这样做

const char *a[2];
a[0] = "blah";
a[1] = "hmm";

当你这样做的时候,你会分配一个包含两个指针的数组给const char。这些指针将被设置为静态字符串“blah”和“hmm”的地址。

如果你确实希望能够改变实际的字符串内容,你必须做一些像这样的事情

char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");

这将分配两个连续的数组,每个数组14个字符,然后静态字符串的内容将被复制到其中。

以下是你的一些选择:

char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" };  // only since you brought up the syntax -

printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah

a2的优点是您可以使用字符串字面值执行以下操作

a2[0] = "hmm";
a2[1] = "blah";

对于a3,您可以执行以下操作:

a3[0] = &"hmm";
a3[1] = &"blah";

对于a1,即使在分配字符串字面量时,也必须使用strcpy()(最好是strncpy())。原因是a2和a3是指针的数组,你可以让它们的元素(即指针)指向任何存储,而a1是一个“字符数组”的数组,因此每个元素都是一个“拥有”自己的存储的数组(这意味着当它超出作用域时它会被销毁)-你只能复制东西到它的存储中。

这也给我们带来了使用a2和a3 -因为他们的缺点指出静态存储(存储字符串位置)的内容不能可靠地改变了(viz.未定义行为),如果你想分配non-string文字a2和a3的元素——你首先要动态地分配足够的内存,然后有自己的元素指向该内存,然后将字符复制到它,然后你必须完成后一定要释放内存。

呸——我已经开始想念c++了;)

附注:如果你需要例子,请告诉我。