2011-08-04 241 views
2

编辑:非常感谢您的回复。我现在明白了这一点!为什么这个C代码有效?

我想了解更多关于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 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? 
    } 
+0

注意malloc的论点。它应该读取'malloc(sizeof(mygrid)* max)'。我知道它是有效的,因为'mygrid'只是一个int long,但它“闻起来”,感觉不好:) –

+0

哎呀!好视力。我一开始想做一系列的整数,但后来我记得具体的例子使用了一系列结构。以防万一它有所作为。然后我忘了编辑该malloc回来:P –

回答

2

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

+0

所以这两个代码都是有效的?我想我现在明白了。谢谢! –

-1

在C中,数组与指针非常相似。对我而言,这并不是很了不起,因为它是我学习的早期编程语言之一,但如果您是从高级语言中获得数组是另一种类型的对象的话,那么它可能会变得很奇怪。

+0

我问,因为在第一个例子中,我读了我必须做一些像(int * a){* a = 3; }。然而,试图让我上面的例子* grid-> bar = foo而不是*号,它会导致这个错误:一元'*'的无效类型参数(有'int') –

1

在第二个示例中,array只是一个指针,而malloc的返回值就是您获得的内存块的开始地址。

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

其次,你应该了解my_array[i]是如何工作的。它所做的就是获取阵列数据块的起始地址(这是my_array的实际值),然后查看从那里以特定偏移量存储的值。具体而言,如果my_arrayWhatEver(构成)类型,则它将访问从my_array + i*sizeof(WhatEver)my_array + (i+1)*sizeof(WhatEver)的数据。

在相关说明中(因为您正在学习C语言),强烈建议在使用malloc返回之前不要使用NULL

我没有C大师,但我也想提高我的理解,所以如果这是不正确,请发表评论或编辑我的答案,所以我可以从我的错误:)

+0

啊。我对这是如何工作有一个模糊的理解,但这很清楚。我大多对语法错误和语法错误的可能错误感到困惑。 –

+0

对NULL指针也很好的建议。尽管考虑到我正在编写一个没有关键功能的小应用程序,但它耗尽内存的可能性应该很小。是否真的值得检查它们,除非它是关键部分? –

+0

我一直都听说,经常检查是很重要的,因为你无法预测在封面下发生了什么事情,以获得你的记忆(它应该是一个好习惯)。 [Wikipedia似乎同意](http://en.wikipedia.org/wiki/Malloc#Allocation_failure)。另一方面,[这个问题的答案](http://stackoverflow.com/questions/1941323/always-check-malloced-memory)似乎表明它不是很清楚,因为它可能不是直接有用的,但它不会受到伤害。我想,如果你想快速失败或者养成良好的习惯,那么检查它,否则考虑平台。 – Caspar

0

学会在你的第一个一段代码

grid->bar is same as (*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不是一个结构,但是结构在第二个例子中的数组

+0

哎呀,我的不好,我把它写成了伪代码,我的焦点是指针的使用,对此感到抱歉!因此,因为数组指向int,传递指针与传递起始地址相同,对吧? –

+0

@roger_rales yes传递指针与传递int的起始地址相同 – lovesh