让我用一个例子来解释 -
#include <iostream>
void foo( int a[2], int b[2] ) // I understand that, compiler doesn't bother about the
// array index and converts them to int *a, int *b
{
a = b ; // At this point, how ever assignment operation is valid.
}
int main()
{
int a[] = { 1,2 };
int b[] = { 3,4 };
foo( a, b );
a = b; // Why is this invalid here.
return 0;
}
是否因为,数组在传递给函数foo(..)
时衰减到指针,因此可以进行赋值操作。在main
中,是因为它们是int[]
类型,它使赋值操作无效。两个案例中a,b
是否意味着相同?感谢。
修改1:
当我在函数foo
中执行此操作时,它会将b's
起始元素位置分配给a
。因此,从它的角度思考,是什么让语言开发人员在main()
中不做同样的事情。想知道原因。
答案 0 :(得分:9)
你回答了自己的问题。
因为这些
int a[] = { 1,2 };
int b[] = { 3,4 };
的类型为int[2]
。但是这些
void foo( int a[2], int b[2] )
的类型为int*
。
您可以复制指针,但无法复制数组。
答案 1 :(得分:1)
答案在于“按值传递”这一概念,这意味着被调用函数接收参数的副本 - 这些参数是指向int的指针。因此a
和b
是这些指针的本地副本(调用者中不存在;它们是来自数组的转换结果,即它们的第一个元素的地址)。如果你写了
void foo( int aparam[2], int bparam[2] )
{
int* a = aparam;
int* b = bparam;
a = b ;
}
Dennis Ritchie已经承认参数的数组语法是语言上的瑕疵,只是为了简化B程序的转换 - 古代历史!它也对C ++的设计产生了有害影响,因为数组不能通过值传递。这种语法是混淆的持续来源。所以... 不要使用;假装它不合法。如果每个人都这样做,它就会逐渐消失,并且可能在几十年内就会被赋予适当的语义。
更新:有关call-by-value(C和Java中唯一的调用形式;请参阅下面的评论),call-by-reference(在C ++中添加)的更多信息,以及其他评估策略,请参阅http://en.wikipedia.org/wiki/Evaluation_strategy
答案 2 :(得分:-2)
在主要功能中
a和b是常量指针,实际上它们是第一个元素的地址。它们就像l值。你不能复制到l值,但你可以改变它们指向的整数的值。
在foo函数中
a和b是指针。所以你可以改变他们的价值观。