据我所知,数组名称不是变量, 那么我们怎么可能像这样取消引用它:
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和++这样的结构 是非法的。
答案 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
指的是不只是一个指针。