【问题标题】:Why can't I assign an array to pointer directly in C?为什么我不能直接在 C 中将数组分配给指针?
【发布时间】:2010-08-17 16:03:11
【问题描述】:

我有以下程序。但是,我不明白为什么我必须传递数组的地址。当它们都指向同一个地址时。这是 int 数组的第一个元素的地址。

当我尝试执行“来自不兼容指针类型的赋值”时收到警告:

ptr = var;

完整的源代码:

void print_values(int (*ptr)[5])
{
    size_t i = 0;
    for(i = 0; i < 5; i++) {
        printf("%d: [ %d ]\n", i, (*ptr)[i]);
    }
}

int main(void)
{
    /* declare a pointer to an array integers */
    int (*ptr)[5] = NULL;
    /* array of integers */
    int var[] = {1, 2, 3, 4, 5};
    /* assign the address of where the array is pointing to (first element) */
    ptr = &var;
    /* Both are pointing to the exact same address */
    printf("var  [ %p ]\n",(void*)var);
    printf("&var [ %p ]\n", (void*)&var);

    print_values(ptr);
    return 0;
}

我用gcc 4.4.4 c89 -Wall -Wextra -O0编译代码

【问题讨论】:

  • 我试图改写你的标题,因为它没有意义。请验证我是否正确选择了您的问题的要点。
  • 我觉得你的标题比我的好。谢谢。
  • 你的代码 sn-p 编译得很好。你的意思是如果你将ptr = var 添加到main 中会出错吗?

标签: c pointers


【解决方案1】:

这纯粹是类型问题。

在大多数表达式上下文中,数组的名称(例如var)衰减为指向数组初始元素的指针,而不是指向数组的指针。 [请注意,这并不意味着 var 是一个指针 - 它非常不是一个指针 - 它只是 表现 像指向第一个元素的指针大多数表达式中的数组。]

这意味着在表达式中var 通常会衰减为指向int 的指针,而不是指向int 数组的指针。

作为地址运算符 (&amp;) 的操作数是此衰减规则不适用的一个上下文(另一个是 sizeof 运算符的操作数)。在这种情况下,&amp;var 的类型直接派生自 var 的类型,因此该类型是指向 5 个数组的指针 int

是的,指针具有相同的地址值(数组第一个元素的地址是数组本身的地址),但它们具有不同的类型(int*int(*)[5]),因此在任务。

ISO/IEC 9899:1999 6.3.2.1/4:

除非它是 sizeof 运算符或一元 &amp; 运算符的操作数,或者是用于初始化数组的字符串文字,否则表达式的类型为“type 的数组" 被转换为指向数组对象的初始元素并且不是左值的“类型指针”类型的表达式。 ...

【讨论】:

  • 我认为数组只会在函数中调用时衰减为指针。所以在表达式中。 int arr[5] = {1,2,3,4,5}; int *ptr = arr;当分配给指针时,数组会衰减为指针?
  • @robUK:不仅仅是函数调用,它是衰减发生的大多数表达式上下文。数组在用于初始化指针时衰减;需要一个指针值来初始化指向int 的指针,而不是int 的数组。
【解决方案2】:

var 本身是一个 (*int) 指向数组中的第一个元素。 C 中的指针和数组极为相似。将int (*ptr)[5] = NULL; 更改为int* ptr = NULL;ptr = &amp;var; 更改为ptr = var;

【讨论】:

    【解决方案3】:

    C 是一种强类型语言。当函数需要int * 类型的参数时,您必须传递int * 类型的参数。不是double *,不是char *,而是int *。即使那些double *char * 中的实际数字地址与您要传递的地址“相同”,它仍然不会改变任何东西——您仍然必须传递int *。该语言禁止您传递错误类型的值。

    这正是您的情况。该函数采用int (*)[5] 类型的参数。这意味着您必须传递该类型的参数。不允许传递int *。地址是否相同没有区别。

    【讨论】:

      【解决方案4】:

      据我所知,您正在将数组指针 (var) 分配给指向数组指针 ((*ptr)[5]) 的指针,这就是您收到该警告的原因。

      请尝试使用

      int *ptr = NULL;
      

      【讨论】:

        猜你喜欢
        • 2021-06-02
        • 2021-06-02
        • 2017-03-28
        • 2020-07-02
        • 1970-01-01
        • 2017-12-11
        • 2014-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多