取消引用数组名称

时间:2015-04-08 10:53:29

标签: c arrays pointers mpi

据我所知,数组名称不是变量, 那么我们怎么可能像这样取消引用它:

int a[] = {1,2,3,4,5};
void *p = &a;

它的含义是什么? 为什么我们要做所有MPI功能需要这个解除引用?

 int buff[2];
 ...  
 MPI_Bcast(&buff, 2, MPI_INT, PROC, MPI_COMM_WORLD);

来自Kernighan&里奇:

  

数组名称和必须指针之间存在一个区别   请记住。指针是一个变量,因此pa = a和pa ++是合法的。   但是数组名称不是变量;像a = pa和++这样的结构   是非法的。

3 个答案:

答案 0 :(得分:2)

所有MPI函数都将消息缓冲区开头的地址作为void *提供。它们不需要类型指针,因为缓冲区中有关内存布局的所有信息都是由MPI数据类型提供的,在这种情况下是MPI_INT

int buff[2];
...  
MPI_Bcast(&buff, 2, MPI_INT, PROC, MPI_COMM_WORLD);

此代码在技术上是错误的。 &buff是类型int (*)[2]的表达式,即指向两个整数元素的数组的指针。虽然它的求值与buff的地址相同,但它在指针算法方面有不同的语义。

正确的表达应该是:

MPI_Bcast(buff, 2, MPI_INT, PROC, MPI_COMM_WORLD);

MPI_Bcast(&buff[0], 2, MPI_INT, PROC, MPI_COMM_WORLD);

传递&buff也很危险,因为之后可能会动态地而不是静态地分配buff,例如int *buff = malloc(2 * sizeof(int));现在&buff不会指向已分配内存的开头,而是指向指针所在的地址,这是完全错误的,MPI不会执行指针追逐。如果使用buff&buff[0],则不会发生这种情况。

另外,注意&地址 - 运算符,即它返回一个引用。要取消引用,请使用*运算符。

答案 1 :(得分:-1)

"数组名称"不存在。可以有一个指针类型的命名变量,它指向数组的第一个元素。

int a[] = {1,2,3,4,5};
void *p = &a;

a是指向第一个元素的int类型的指针," 1"。 p是一个void指针,在赋值之后它实际上指向存储数组第一个元素的地址的位置。

我不知道您的图书馆是如何运作的。通常,如果您调用的函数应该能够修改指针,则使用此模式。例如,这是有用的"当库分配新数组并更新指针引用时。我在引号中写得很有用,因为我不认为这是好习惯。

答案 2 :(得分:-1)

数组是一个变量,但不能分配给它(你不能“移动数组”)。

在许多上下文中,名称的计算结果是数组的第一个元素的地址,但它与第一​​个元素的地址不是等效的

您可以对数组名称使用sizeof并获取数组的实际大小(以字节为单位),如果名称等同于指针,则无法实现。像这样:

int a[4];

printf("the array a has size %zu\n", sizeof a);

在具有8位char和32位int的计算机上,上面将打印16。这证明名称a指的是只是一个指针。