6

嗨,我正在使用 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。

4

4 回答 4

5

car_car都是数组,并且不能在 C 中分配数组(除非数组嵌入在结构(或联合)中并且您执行结构分配)。

它们也是指向 char 的指针数组,而不是指向 char 数组的指针。您在代码中编写的内容可能就是您想要的 - 您可以在数组中存储指向最多 MAXINT 个名称的指针。但是,您应该正确描述类型 - 作为指向 char 或 char 指针的指针数组。

指向字符数组的指针如下所示:

char (*car)[MAXINT];

指向字符指针数组的点(谢谢,Brian)看起来像:

char *(*car)[MAXINT];

小心 MAXINT;这可能是一个非常大的数组(在 Linux 上,<values.h>定义MAXINTINT_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 的赋值都不应该编译 -argvoid *. 您大概打算以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 *'),它会向各种滥用代码敞开大门。

于 2010-04-05T02:08:20.653 回答
3

您正在创建一个大小为 MAXINT 的新数组。我认为您想创建一个指向大小为 MAXINT 的数组的指针。

创建指向 char* 数组的指针:

以下是大小为 MAXINT 到 char* 元素的数组:

char * car[MAXINT]; 

下面是一个指针:一个大小为 MAXINT 的数组,指向 char* 元素:

char* (*car)[MAXINT];

以下是您如何设置指针:一个大小为 MAXINT 到 char* 元素的数组:

char* (*car)[MAXINT];
car = &arg->_car;

问题中的其他语法错误:

  • 您的结构定义后需要有一个分号。
  • 你应该使用foo*not foo。所以应该是:
    struct foo* thing = (struct foo *) arg;
  • 你应该使用thingnot arg
    bar = thing->_bar;
    car = thing->_car;
于 2010-04-05T02:10:50.237 回答
2

您不能按照您的方式分配给数组。您可以按元素进行复制。

for(int i = 0; i < MAXINT; i++)
{
  car[i] = (arg->_car)[i]
}

请注意,如果字符串不是常量,您可能需要使用strcpy.

于 2010-04-05T02:08:50.253 回答
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 语言中完全是例行公事。注意:以上是我的想法,不是从工作程序中复制的,所以我不能保证所有的 * 都在正确的位置。我怀疑这是一个家庭作业,所以我不想给你所有的东西......

于 2010-04-05T02:44:20.460 回答