我正在为考试做研究,然后我在网上看到了这个问题。我的问题是数组不是在c中基本上是常量指针吗(所以有错误)?起初,我想得到有关此“ b + = 2”的错误,但没有任何错误。
int func ( int b[])
{
b +=2;
printf("%d",*b);
}
int main()
{
int arr[]={1,2,3,4};
func(arr);
return 0;
}
(此程序的输出为3 btw)
答案 0 :(得分:5)
不是数组基本上是c中的常量指针
不,不是。数组是对象的连续序列。指针是通过存储内存地址引用另一个对象的对象。
我为什么能更改数组
b +=2;
b
不是数组。 b
是一个指针。最初,您将指针传递给数组arr
的第一个元素。在指针上加1会将其更改为指向数组的连续元素。加2将其更改为指向第二个连续元素。从第一个元素开始,第二个连续元素是索引2处的元素,在这种情况下,其值为3。此指针算法就是为什么可以使用指针来迭代数组元素的原因。
但是它是使用通常与数组关联的语法声明的
函数参数不能是数组。您可以将参数声明为数组,但是对该声明进行了调整,使其成为指向数组元素的指针。这两个函数声明在语义上是相同的:
int func ( int b[]); // the adjusted type is int*
int func ( int *b );
它们两个都声明一个函数,其参数是指向int
的指针。这种调整并不意味着数组是指针。这种调整是对数组隐式转换为指向第一个元素的指针的规则的补充,这种转换称为衰减。
请注意,仅在进行此调整的情况下才声明参数。例如在变量声明中:
int arr[]={1,2,3,4}; // the type is int[4]; not int*
// the length is deduced from the initialiser
int *ptr; // different type
还请注意,调整仅在化合物类型的“最高”水平进行。这些声明是不同的:
int funcA ( int (*b)[4]); // pointer to array
int funcB ( int **b ); // pointer to pointer
P.S。您已声明该函数返回int
,但未能提供return语句。在C ++中这样做会导致程序的行为未定义。
答案 1 :(得分:1)
数组在传递给函数时会衰减到指向第一个元素的指针。因此,该功能等效于
int func ( int* b)
{
b +=2;
printf("%d",*b);
}
指针前进2,然后打印该位置的元素。对于常数,请考虑按值传递参数。即b
是副本。你不能做
int arr[] = {1,2,3,4};
arr+=2;
但是你可以做
int arr[] = {1,2,3,4};
int* p = arr;
p += 2; // p now points to the third element
出于完整性考虑,main
可以写为
int main()
{
int arr[]={1,2,3,4};
func(&arr[0]);
return 0;
}
实际上,在将数组传递给函数时写&arr[0]
并不常见,但这只是为了说明会发生什么。
答案 2 :(得分:1)
声明参数时,int b[]
表示int *b
。它不是数组。实际上,sizeof b
甚至会返回sizeof int *
。
根据C规范,
将参数声明为“ 类型的数组”声明调整为“ type 的合格指针”,其中类型限定符(如果有) )是在数组类型派生的
[
和]
中指定的那些。如果关键字static
也出现在数组类型派生的[
和]
中,则对于每次调用该函数,相应的实际参数的值均应提供对第一个参数的访问。数组中的元素,其大小至少与size表达式指定的数量相同。
这将使您留下将数组传递给需要指针的函数的代码,这很好。在这种情况下,数组将降级为指向其第一个元素的指针。就像
func(arr)
是
func(&(arr[0]))
答案 3 :(得分:-4)
嗨,朋友们,您很正确地认为数组是常量指针,但是在将地址传递给函数时,修改只能在指针变量b中看到,而不能在arr中看到。这是因为b对于函数而言是本地的。
如果print语句已在main()函数中显示为:
printf("%d",arr[0]);
或
printf("%d",*arr);
输出将为1。仅仅因为增量影响了本地值,但没有影响实际值。 希望对您有帮助!