您好我正在使用C,我有一个关于分配指针的问题。
struct foo
{
int _bar;
char * _car[SOME_NUMBER]; // this is meant to be an array of char * so that it can hold pointers to names of cars
}
int foofunc (void * arg)
{
int bar;
char * car[SOME_NUMBER];
struct foo * thing = (struct foo *) arg;
bar = thing->_bar; // this works fine
car = thing->_car; // this gives compiler errors of incompatible types in assignment
}
car和_car有相同的声明,为什么我收到有关不兼容类型的错误?我的猜测是它与指针有关(因为它们是指向char *数组的指针,对吗?)但我不明白为什么这是一个问题。
当我宣布char * car;
而不是char * car[MAXINT];
时,它编译得很好。但是当我需要使用索引访问某些信息时,我不知道这对我有什么用处,以后访问该信息会非常烦人。事实上,我甚至不确定我是否采用正确的方法,也许有更好的方法来存储一堆字符串而不是使用char *数组?
编辑:我不是故意使用INT_MAX(int的最大值),它只是其他一些int,大约是20。
答案 0 :(得分:5)
car
和_car
都是数组,并且您不能在C中分配数组(除非数组嵌入在结构(或联合)中并且您执行结构分配)。
它们也是指向char的指针数组,而不是指向char数组的指针。您在代码中编写的内容可能就是您想要的 - 您可以存储指向数组中MAXINT名称的指针。但是,您应该正确描述类型 - 作为char或char指针的指针数组。
指向字符数组的指针如下所示:
char (*car)[MAXINT];
指向一系列字符指针(感谢Brian)看起来像:
char *(*car)[MAXINT];
小心MAXINT;这可能是一个非常大的数组(在Linux上,<values.h>
将MAXINT
定义为INT_MAX
,至少为2 31 -1)。
代码如下:
struct foo
{
int _bar;
char * _car[MAXINT];
}
int foofunc (void * arg)
{
int bar;
char * car[MAXINT];
struct foo thing = (struct foo *) arg;
bar = arg->_bar; // this works fine
car = arg->_car; // this gives compiler errors of incompatible types in assignment
}
bar和car的分配都不应该编译 - arg
是void *
。你可能想要以某种形式或形式使用thing
。正如Brian所说,那里也存在问题:
你要么:
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo thing = *(struct foo *)arg;
bar = thing._bar; // this works fine
car = thing._car; // this is still an array assignment
...other code using bar and car...
}
或者你想要:
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo *thing = (struct foo *) arg;
bar = thing->_bar; // this works fine
car = thing->_car; // this is still an array assignment
...other code using bar and car...
}
或者,确实:
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT] = thing->_car; // this is still an array assignment
...other code using bar and car...
}
最后,处理数组赋值,在C中你可以合理地使用memmove()
来执行此操作:
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT];
memmove(car, thing->_car, sizeof(car));
...other code using bar and car...
}
如果要复制的区域重叠,则类似的函数memcpy()
没有可靠的语义,而memmove()
会这样做;始终使用memmove()
更简单,因为它始终可以正常工作。在C ++中,您需要谨慎使用memmove()
(或memcpy()
)。在这段代码中,它足够安全,但理解为什么是非平凡的。
你需要知道你只是在这里复制指针 - 你没有复制指针指向的字符串。如果其他内容更改了这些字符串,则会影响通过car
看到的值和调用代码中的变量。
最后一点 - 现在:你确定你需要函数的参数为void *
吗?它打开了各种滥用行为的代码,如果宣布该函数采用“struct foo *
”(甚至是“const struct foo *
”),则可以防止这种行为。
答案 1 :(得分:3)
您正在创建一个大小为MAXINT的新数组。我想你想创建一个指向大小为MAXINT的数组的指针。
创建指向char *的数组的指针:
以下是一个大小为MAXINT到char *元素的数组:
char * car[MAXINT];
以下是一个指针:一个大小为MAXINT到char *元素的数组:
char* (*car)[MAXINT];
以下是如何设置指针:一个大小为MAXINT到char *元素的数组:
char* (*car)[MAXINT];
car = &arg->_car;
问题中的其他语法错误:
foo*
而不是foo
。所以它应该是:struct foo* thing = (struct foo *) arg;
thing
而不是arg
:bar = thing->_bar;
car = thing->_car;
答案 2 :(得分:2)
您无法按照自己的方式分配数组。你可以做一个元素复制。
for(int i = 0; i < MAXINT; i++)
{
car[i] = (arg->_car)[i]
}
请注意,如果字符串不是常量,则可能需要使用strcpy
。
答案 3 :(得分:0)
C中的数组符号是合法的混淆;你的代码并不意味着你的意思。
arg->_car
表示“数组地址_car
”。同样,car
表示“数组car
的地址”。如果你试图将_car的内容复制到汽车,那么这样就可以了:
memcpy(car, _car, MAXINT);
但我认为,你真正的问题是“存储字符串列表的最佳方式是什么?”答案是:动态列表(在添加项目时自动增长的列表)。
你这样声明:
#define CARSIZE 65
int numCars = 0;
char **car; /* a list of addresses, each one will point to a string */
添加汽车:
char *newCar = malloc(CARSIZE); /* make room */
strncpy(newCar, "Mercedes", CARSIZE); /* newCar has the address of the string */
car[numCars++] = newCar; /* store it */
列出汽车:
int n;
for (n = 0; n < numCars; ++n)
printf("%s\n", car[n]);
要移除位置n处的汽车:
free(car[n]); /* release the memory */
/* condense the list of pointers */
for ( ; n < numCars - 1; ++n)
car[n] = car[n+1];
这在C中是完全常规的。注意:以上是我的头脑而不是从工作程序中复制,所以我不能保证所有*都在正确的地方。我怀疑这是一个家庭作业,所以我不想给你一切 ......