为什么我可以更改阵列

时间:2020-01-07 19:59:05

标签: c++ c arrays pointers

我正在为考试做研究,然后我在网上看到了这个问题。我的问题是数组不是在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)

4 个答案:

答案 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。仅仅因为增量影响了本地值,但没有影响实际值。 希望对您有帮助!