C++ 为什么我可以更改阵列

C++ 为什么我可以更改阵列,c++,c,arrays,pointers,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)数组在传递给函数时衰减为指向其第一个元素的指针。因此,该函数等价于 in

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

数组在传递给函数时衰减为指向其第一个元素的指针。因此,该函数等价于

int  func (  int*  b)
{

    b +=2;
    printf("%d",*b);
}
指针前进2,然后打印该位置的元素。对于常量,考虑参数是通过值传递的。Ie
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]
并不常见,但这只是为了说明发生了什么

数组在c中基本上是常量指针

不,他们不是。数组是对象的连续序列。指针是通过存储内存地址引用另一个对象的对象

为什么我可以更改阵列

b +=2;
b
不是数组<代码>b是一个指针。首先,传递指向数组的第一个元素的指针
arr
。向指针添加1会将其更改为指向数组的连续元素。添加2会将其更改为指向第二个连续元素。从第一个元素开始,第二个连续元素是索引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


注意:您已将函数声明为返回
int
,但未能提供返回语句。在C++中这样做会导致程序的未定义行为。

你好,好友,你在你的位置是非常正确的,数组是常数指针,但是当把地址传递给函数时,修改只能在指针变量B中看到,而不是在ARR中。这是因为b是函数的局部

如果print语句在main()函数中的形式为:

printf("%d",arr[0]);

输出应该是1。只是因为增量影响了局部值,而不是实际值。
希望能有帮助

声明参数时,
int b[]
表示
int*b
。它不是数组。实际上,
sizeof b
甚至会返回
sizeof int*

根据C规范

将参数声明为“类型数组”应调整为“类型限定指针”,其中类型限定符(如有)是数组类型派生的
[
]
中指定的类型限定符。如果关键字
static
也出现在数组类型派生的
[
]
中,则对于每个函数调用,对应的实际参数的值应提供对数组第一个元素的访问,该元素的数量至少与大小表达式指定的元素数量相同


这样,代码就可以将数组传递给需要指针的函数,这很好。在这种情况下,数组将降级为指向其第一个元素的指针。好像

func(arr)


当用作参数时,
int b[]
表示
int*b
。它不是数组。(
sizeof(b)
甚至会返回
sizeof(int*)
)如果
b+=2
,您只需将b中的地址值从数组的第一个元素更改为第三个元素,即
3
,因此代码是合法的,没有错误提示:对于不返回任何内容的函数,您应该使用
void
。你有未定义的行为。数组不是“基本上不变的指针”,这是一个常见的误解。您可以获取数组或其元素的地址,就像它今天所做的任何变量一样。你确定。你眨眼了吗?下次运行该程序时,它可能无法工作。好吧,如果它是未定义的行为,但M.M说它不是C语言。不管怎样,它都会让你的读者感到困惑,并发出警告。(您正在启用和标题警告,对吗?@ikegami不,我没有错过问题的要点。我提出了一种不同的方法来编写same@ikegami这是因为数组在传递给函数时会衰减为指向其第一个元素的指针。这不是在解释发生了什么吗?对不起,误读了。只是一个拙劣的解释。@ikegami我很乐意得到改进建议。还有什么要说的吗?@ikegami当a等于b时,b等于a。我真的很理解你在选择什么。我的朋友,你在你的位置上非常正确,数组是常量指针不,不,不。数组不是指针“非常正确,在你的位置上,数组是常量指针”,这一点都不正确,这是一个常见的神话,会给新程序员带来很多困惑。
func(arr)
func(&(arr[0]))