在 C99 中,为什么将变量 p
声明为指向数组的指针需要在将其作为参数传递给具有数组类型参数的函数之前进行转换,但声明变量 p
作为 void 指针然后将其转换为指向数组的指针可以作为指向数组的指针传递给同一函数吗?
#include <stdio.h>
int arreglo(int locArr[])
{
locArr[0]=1;
printf("el arreglo es : %i\n",locArr[0]);
return 0;
}
int main()
{
/* Declare a pointer p to array */
int (*p)[];
int manArr[10];
p=&manArr; /* assign the adress of manArr as case below */
/* Here passing pointer p is not allowed as expected,
since our function has int* as argument */
/* so I need to do a casting */
arreglo((int*)p);
}
/* **But in this other main function**: */
int main()
{
/* Declare a void pointer */
void *p=NULL;
/* Do a casting from p to void to p to array */
p=(int (*)[])p;
int manArr[10];
p=&manArr; /* assing the adress of the array manArr as in above case */
/* Now given the pointer to array as parameter to function WORKS¡¡,
why?. As before the function expects int* as argument not
a pointer to an array */
arreglo(p);
}
最佳答案
虽然 array-of-int 和 pointer-to-int 是等效的,但 pointer-to-array(-of-int) 是一个额外的间接级别。
这是您的程序,其中包含一些评论和更正。
#include<stdio.h>
int arreglo(int locArr[])
{
locArr[0]=1;
printf("el arreglo es : %i\n",locArr[0]);
return 0;
}
int main()
{
/* Declare a pointer p to array */
//int (*p)[]; //NO!
/* Declare a pointer p to int */
int *p;
int manArr[10];
//p=&manArr; /* assign the adress of manArr as case below */ //NO!
p=manArr;
/* Here passing pointer p is not allowed as expected,
since our function has int* as argument */ // Because `int*` and `int (*)[]` are different
/* so I need to do a casting */ //NO!
//arreglo((int*)p);
arreglo(p);
}
/* **But in this other main function**: */
int main()
{
/* Declare a void pointer */
void *p=NULL;
/* Do a casting from p to void to p to array */
//p=(int (*)[])p; //NO! This does absolutely nothing at all.
int manArr[10];
//p=&manArr; /* passing the adress of the array manArr as in above case */
p=manArr;
/* Now given the pointer to array as parameter to function WORKS¡¡,
why?. As before the function expects int* as argument not
a pointer to an array */
// A void* bypasses all type-checking, since it can be implicitly converted to any type
arreglo(p); //This would still compile if p="potato", because a void* converts to any type.
}
所以,让我们从头开始。
int i = 0; // a simple int variable
int a[3] = { 1, 2, 3 }; // an array of ints
int *p = a; // a pointer to int can be used the same as an array of int
p[0] = 4; // so now a[0] = 4, too
int i int a[3]
|----| |----|----|----|
| 0 | | 4 | 2 | 3 |
|----| |----|----|----|
^
int *p |
|----| |
| --|-----
|----|
指向数组的指针是完全不同的,因为它指向整个数组,而不仅仅是一个可能是也可能不是数组的一部分的单个 int。
int b[3] = { 5, 6, 7 };
int (*bp)[3] = &b; // bp points to the whole array b
-------------
V |
int b[3] | int (*bp)[3]
|----|----|----| | |----|
| 5 | 6 | 7 | --|-- |
|----|----|----| |----|
bp[0][0] = 8; // it now takes 2 dereferences to get to the int
-------------
V |
int b[3] | int (*bp)[3]
|----|----|----| | |----|
| 8 | 6 | 7 | --|-- |
|----|----|----| |----|
关于c - 为什么指向数组的指针在作为参数传递给具有数组类型参数的函数之前需要转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17438175/