...那么为什么下面的代码给出地址和实际内容的相同值(肉丸)?如何理解肉丸的%d值,它是随机的吗?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main()
{
int i;
int meatballs[5]= {1,2,3,4,5};
printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs,
meatballs);
return 0;
}
答案 0 :(得分:3)
meatballs
是一个数组,类型为int[5]
。但是,C不允许按值传递数组,因此数组衰减为函数调用的指针。这相当于指向数组&meatballs[0]
的第一个元素的指针,它的类型为int*
。
&meatballs
是指向数组的指针,它的类型为int(*)[5]
。由于它是一个指针,因此可以传递给函数。
如您所见,1和2都返回相同的地址,但它们有不同的类型:指向整数数组的指针与指向单个整数的指针。
注意:类型void*
和int*
不必具有相同的表示(1),以及{{1只有有效类型为%p
(2),否则您将获得未定义行为 (3)。打印地址时始终将指针转换为void*
:
void*
printf("%p %p", (void*)meatballs, (void*)&meatballs);
。与案例1一样,结果类型再次为%d
,但它被解释为int*
。这是明确的未定义的行为,输出是垃圾。要打印整数数组元素,请使用以下任一方法:
int
前两个将在索引printf("%d %d %d", meatballs[i], *(meatballs + i), *meatballs);
打印数组元素,最后两个将打印第一个元素。我建议在大多数情况下使用i
,因为它最清楚。
参考C标准(草案):
指向 void 的指针应具有与指向字符类型的指针相同的表示和对齐要求。 48) ......指向其他类型的指针需要没有相同的表示或对齐要求。
p 参数应为指向 void 的指针。 ...
......如果有任何争论 不是相应转换规范的正确类型,行为是 未定义。
答案 1 :(得分:0)
您必须使用一元解除引用运算符*
,以便实际值显示为%d
期望整数。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main()
{
int i;
int meatballs[5]= {1,2,3,4,5};
printf("\nmeatsballs %p %p %d \t \n",meatballs, &meatballs,
*meatballs);
return 0;
}
查看最后一个参数:*meatballs
。此代码实际上将1
打印为值,并且是数组中的第一个元素。所以你的猜测是正确的,这只是一个错误。