Why does this C code work?
EDIT: Thank you very much for your responses. I understand this properly now!
I am trying to learn more on C pointers. Tinkering around, I am questioning the difference between two actions I am using.
This code seems to work at first glance, but I am not sure of what's the difference, and if any of these two approaches is wrong in some way.
I'd like to know what's the difference between the two pieces of code, when I should I pass the adress, and when a pointer to an array?
Is any of the pieces wrong? If so开发者_JAVA百科, what would be the proper way?
having a simple struct grid pretty much like struct grid { int val; } (for demonstration purposes)
First piece of code. Passing address of the pointer to the array.
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);
}
}
Second piece of code. I am not entirely sure why this works, but the compiler doesn't output any warning. I am supposed to be passing the pointer to the start of the array like this?
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?
}
Passing an array decays into a pointer that points to the first member of the array, just like &array[0]
.
In your second example, array
is just a pointer, and the return value from malloc
is just the address of the start of the block of memory you get.
It doesn't have to be used for an array; it could be used for storage of an arbitrary sizeof(int) * max
bytes of data. An array (in C) is really just a nice way of thinking about & working with a solid block of memory divided up into equal size portions.
Secondly, you should understand how my_array[i]
works. All it does is take the address of where your block of array data starts (which is the actual value of my_array
), and then look at what value is stored at a particular offset from there. Specifically, if my_array
is of a (made up) type of WhatEver
, then it will access the data from my_array + i*sizeof(WhatEver)
to my_array + (i+1)*sizeof(WhatEver)
.
On a related note (since you're learning C), it's highly recommended to check that the return from malloc is not NULL
before doing anything with it.
I'm no C guru but am also trying to improve my understanding so if this is incorrect, please leave a comment or edit my answer so I can learn from my mistakes :)
In your first piece of code
grid->bar
is same as(*grid).bar
. and using name of an array refers to its base address. so writing array
is equivalent &array[0]
&array[i] is equivalent to array+i
array[i] is equivalent to *(array +i)
In you second piece of code i dont understand why there is no error because in your function set you do not declare max
and i dont see a global max
variable too.
also in your second piece of code you use
set(array,0)
because array is already an integer pointer(see the declaration int * array
).As far as i understand the mygrid
is not a struct but is an array of structs in the second example
In C, an array is pretty much the same as a pointer. For me this isn't so amazing, since it is one of the earlier programming languages I learned, but if you're coming from a high level language where an array is a different type of object, then it might come across as strange.
精彩评论