为什么这个C代码有效?

时间:2011-08-04 02:02:00

标签: c pointers

编辑:非常感谢您的回复。我现在理解这一点了!

我想了解更多有关C指针的信息。摆弄,我正在质疑我正在使用的两个动作之间的区别。

这段代码似乎乍一看似乎有效,但我不确定区别是什么,以及这两种方法中的任何一种在某种程度上是错误的。

我想知道这两段代码之间有什么区别,我应该通过地址,还有指向数组的指针?

是否有任何错误?如果是这样,那么正确的方法是什么?

有一个简单的struct grid,就像struct grid {int val; }(用于演示目的)

第一段代码。将指针的地址传递给数组。

    void set (mygrid *grid, int foo){
        grid->bar = foo; //should this be '*grid->bar?' But this seems to work properly.
    }

    void main(){
        int i;
        int* array;
        int max = 24;

        array = malloc(sizeof(grid) * max);

        for(i = 0; i < max; i++){
            set(&array[i], 0);
        }
    }

第二段代码。我不完全确定为什么会这样,但编译器不会输出任何警告。 我应该像这样将指针传递给数组的开头?

    void set(mygrid *grid, int foo){
        int i; int max = 24; //so this example code compiles :P

        for(i = 0; i < max; i++){
            grid[i].bar = foo;
        }
    }

    void main(){
        int* array;
        int max = 24;

        array = malloc(sizeof(grid) * max);
        set(array, 0); //Why not &array?
    }

4 个答案:

答案 0 :(得分:2)

将数组传递衰减为指向数组第一个成员的指针,就像&array[0]一样。

答案 1 :(得分:1)

在你的第二个例子中,array只是一个指针,malloc的返回值只是你得到的内存块起始地址。

它不必用于数组;它可以用于存储任意sizeof(int) * max个字节的数据。数组(在C中)实际上只是一种很好的思考方式。使用固定的内存块分成相等大小的部分。

其次,您应该了解my_array[i]的工作原理。它所做的就是获取数组数据块开始的地址(这是my_array的实际值),然后查看存储在特定偏移处的值。具体来说,如果my_array属于(组成)WhatEver类型,那么它将访问从my_array + i*sizeof(WhatEver)my_array + (i+1)*sizeof(WhatEver)的数据。

在相关的说明中(因为你正在学习C),强烈建议在做任何事情之前检查malloc的返回值是否为NULL

我不是C大师,但我也在努力提高自己的理解,所以如果这不正确,请发表评论或编辑我的答案,以便我可以从错误中吸取教训:)

答案 2 :(得分:0)

在你的第一段代码中

  

grid->bar(*grid).bar

相同

。并使用数组名称是指其基地址。所以写array等同于&array[0]

&array[i] is equivalent to array+i
array[i] is equivalent to *(array +i)

在你的第二段代码中,我不明白为什么没有错误,因为在你的函数集中你没有声明max而我也没有看到全局max变量。 也在你使用的第二段代码中 set(array,0)因为数组已经是一个整数指针(参见声明int * array)。据我所知,mygrid不是结构,而是第二个例子中的结构数组

答案 3 :(得分:-1)

在C中,数组与指针几乎相同。对我而言,这并不是那么令人惊讶,因为它是我学过的早期编程语言之一,但是如果你来自高级语言,其中数组是不同类型的对象,那么它可能会变得奇怪。