为什么这个C代码可以工作?

为什么这个C代码可以工作?,c,pointers,C,Pointers,编辑:非常感谢您的回复。我现在完全明白了 我正在努力学习更多关于C指针的知识。修修补补,我质疑我正在使用的两个动作之间的区别 乍一看,这段代码似乎是有效的,但我不确定有什么区别,以及这两种方法中是否有任何一种在某种程度上是错误的 我想知道这两段代码之间的区别是什么,何时传递地址,何时指针指向数组 有错的地方吗?如果是,正确的方法是什么 具有与结构网格{int val;}非常相似的简单结构网格(用于演示) 第一段代码。将指针的地址传递给数组 void set (mygrid *grid,

编辑:非常感谢您的回复。我现在完全明白了

我正在努力学习更多关于C指针的知识。修修补补,我质疑我正在使用的两个动作之间的区别

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

我想知道这两段代码之间的区别是什么,何时传递地址,何时指针指向数组

有错的地方吗?如果是,正确的方法是什么

具有与结构网格{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集(mygrid*grid,intfoo){
grid->bar=foo;//这应该是“*grid->bar”吗?但这似乎工作正常。
}
void main(){
int i;
int*数组;
int max=24;
阵列=malloc(网格大小)*最大值;
对于(i=0;i
第二段代码。我不完全确定这是为什么,但编译器没有输出任何警告。 我应该像这样将指针传递到数组的开头

    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?
    }
void集(mygrid*grid,intfoo){
int i;int max=24;//所以这个示例代码编译为:P
对于(i=0;i
在C语言中,数组与指针几乎相同。对我来说这并不奇怪,因为这是我学习的早期编程语言之一,但是如果你来自一种高级语言,其中数组是一种不同类型的对象,那么它可能会给人一种奇怪的感觉。

传递数组会退化为指向数组第一个成员的指针,就像
&array[0]

在第二个示例中,
数组
只是一个指针,而
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大师,但我也在努力提高我的理解力,因此如果这是错误的,请留下评论或编辑我的答案,以便我可以从错误中吸取教训:)

在您的第一段代码中

grid->bar
(*grid)相同。bar

。使用数组的名称表示其基址。因此,编写
数组
相当于
数组[0]

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

注意malloc的参数。它应该是
malloc(sizeof(mygrid)*max)
。我知道它是有效的,因为
mygrid
正好有一个整数长,但它“闻起来”而且感觉很糟糕:)哇!视力好。起初我想做一个int数组,但后来我想起了使用结构数组的具体示例。以防万一会有不同。然后我忘了编辑malloc back:PI问,因为在第一个例子中,我读到我必须做(int*a){a=3;}之类的事情。但是,尝试使上面的示例*grid->bar=foo而不是不带*符号,会导致以下错误:一元数“”的类型参数无效(具有“int”)啊。我对它是如何工作的有一个模糊的理解,但这使它非常清楚。我对语法和错误语法可能导致的错误感到困惑。关于空指针的建议也不错。虽然,考虑到我正在编写一个没有关键功能的小型ish应用程序,它内存不足的可能性应该很小。除非这是一个关键的部分,否则它真的值得检查吗?我一直听说经常检查是很重要的,因为你无法预测在封面下会发生什么来让你记住(这应该是一个好习惯)。另一方面,这似乎表明它不是那么明确,因为它可能没有直接的用处,但不会造成伤害。我想,如果你想快速失败或养成良好的习惯,那就检查一下,否则考虑一下这个平台。好吧,我碰巧同意那里的许多海报。如果系统无法为一个小整数数组保留空间,那么系统就已经不稳定或处于负载之下,甚至出现故障。绝对不是使用我的应用程序的环境。由于我的应用程序仅仅是一个按需工具,因此当出现这种情况时,我最好强制退出。没有必要让它对抗内存不足的情况。我将在m的函数中添加检查