c 赋值中的类型不兼容,指针有问题吗?

发布于 2024-08-27 20:36:37 字数 798 浏览 6 评论 0原文

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

Hi I'm working with C and I have a question about assigning pointers.

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 and _car have same declaration so why am I getting an error about incompatible types? My guess is that it has something to do with them being pointers (because they are pointers to arrays of char *, right?) but I don't see why that is a problem.

when i declared char * car; instead of char * car[MAXINT]; it compiles fine. but I don't see how that would be useful to me later when I need to access certain info using index, it would be very annoying to access that info later. in fact, I'm not even sure if I am going about the right way, maybe there is a better way to store a bunch of strings instead of using array of char *?

EDIT: I didn't mean to use INT_MAX (maximum value of int), it's just some other int, which is about 20.

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

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

发布评论

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

评论(4

彻夜缠绵 2024-09-03 20:36:37

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

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

指向字符数组的指针看起来像:

char (*car)[MAXINT];

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

char *(*car)[MAXINT];

小心 MAXINT;这可能是一个非常大的数组(在 Linux 上,MAXINT 定义为 INT_MAX,至少为 231-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 *”),则可以防止这种滥用。 >')。

car and _car are both arrays, and you cannot assign arrays in C (except when the array is embedded in a structure (or union) and you do a structure assignment).

They are also arrays of pointers to char, rather than pointers to arrays of char. What you have written in the code is probably what you want - you could store pointers to up to MAXINT names in the array. However, you should describe the type correctly - as an array of pointers to char or char pointers.

A pointer to an array of characters would look like:

char (*car)[MAXINT];

And a point to an array of character pointers (thanks, Brian) would look like:

char *(*car)[MAXINT];

Be careful of MAXINT; that could be a very large array (on Linux, <values.h> defines MAXINT as INT_MAX, which is at least 231-1).


The code looks like:

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
}

Neither the assignment to bar nor car should compile at all - arg is a void *. You presumably meant to use thing in some shape or form. As Brian noted, there are problems there, too:

You either want:

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...
}

Or you want:

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...
}

Or, indeed:

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...
}

Finally, dealing with the array assignment, in C you can reasonably use memmove() to do this:

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...
}

The similar function memcpy() does not have reliable semantics if the areas to be copied overlap, whereas memmove() does; it is simpler to always use memmove() because it always works correctly. In C++, you need to be cautious about using memmove() (or memcpy()). In this code, it would be safe enough, but understanding why is non-trivial.

You do need to be aware that you are just copying pointers here - you are not copying the strings that the pointers point at. If something else changes those strings, it affects both the values seen via car and the variable in the calling code.

One last point - for now: are you sure you need the argument to the function as a void *? It opens up the code to all sorts of abuse which can be prevented if the function is declared to take a 'struct foo *' instead (or even a 'const struct foo *').

挥剑断情 2024-09-03 20:36:37

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

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

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

char * car[MAXINT]; 

以下是指向以下内容的指针:一个指向 char* 元素的大小为 MAXINT 的数组

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;

You are creating a new array of size MAXINT. I think you want to create a pointer to an array of size MAXINT.

Creating a pointer to an array of char*'s:

The following is an array of size MAXINT to char* elements:

char * car[MAXINT]; 

The following is a pointer to: an array of size MAXINT to char* elements:

char* (*car)[MAXINT];

the following is how you set a pointer to: an array of size MAXINT to char* elements:

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

Other syntax errors in the question:

  • You need to have a semicolon after your struct definition.
  • You should be using foo* not foo. So it should be:
    struct foo* thing = (struct foo *) arg;
  • You should be using thing not arg:
    bar = thing->_bar;
    car = thing->_car;
阳光的暖冬 2024-09-03 20:36:37

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

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

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

You can't assign to an array the way you're doing. You can do an element-wise copy.

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

Note that if if the strings aren't constant, you may need to use strcpy.

泛泛之交 2024-09-03 20:36:37

C 中的数组表示法确实令人困惑;你的代码并不意味着你认为它意味着什么。

arg->_car 表示“数组_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 中完全是例行公事。 注意: 以上是我的head 并且不是从工作程序复制的,所以我不能保证所有 * 都在正确的位置。我怀疑这是一项家庭作业,所以我不想给你一切...

Array notation in C is legitimately confusing; your code doesn't mean what you think it means.

arg->_car means "the address of the array _car". Similarly, car means "the address of the array car". If you're trying to copy the contents of _car to car, then this will do it:

memcpy(car, _car, MAXINT);

But your real question, I think, is "what's the best way to store a list of strings?" This answer is: a dynamic list (one that grows automatically as you add items).

You'd declare it like this:

#define CARSIZE 65
int numCars = 0;
char **car; /* a list of addresses, each one will point to a string */

To add a car:

char *newCar = malloc(CARSIZE); /* make room */
strncpy(newCar, "Mercedes", CARSIZE); /* newCar has the address of the string */
car[numCars++] = newCar; /* store it */

To list the cars:

int n;
for (n = 0; n < numCars; ++n)
    printf("%s\n", car[n]);

To remove the car at position n:

free(car[n]); /* release the memory */
/* condense the list of pointers */
for ( ; n < numCars - 1; ++n)
    car[n] = car[n+1];

This is completely routine in C. NOTE: The above is off the top of my head and not copied from a working program, so I can't promise all the * are in the right place. I suspect this is a homework assignment, so I don't want to give you everything...

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