为什么在下面的函数中增加数组“a”不是错误?

时间:2015-07-18 06:28:16

标签: c arrays function pointers

#include<stdio.h>
void printd(char []);
int main(void){
       char a[100];
       a[0]='a';a[1]='b';a[2]='c';a[4]='d';
       printd(a);
       return 0;
}
void printd(char a[]){
        a++;
        printf("%c",*a);
        a++;
        printf("%c",*a);
}

说明:我原以为会导致左值错误。 但它正在处理任何错误并将bc作为输出。为什么这个递增数组“a”不是错误?

5 个答案:

答案 0 :(得分:5)

如果数组传递给函数,它衰减指向数组第一个元素的指针。

由于内部printd(),指针a可以递增和递减,指向a中定义的数组main()的不同元素。

请注意,在声明/定义任何类型T的函数参数列表时,表达式T[]T*等效。

有问题的具体案例

void printd(char a[]);

相同
void printd(char * a);

下面的代码显示了与OP代码相同的行为,pa的行为类似于a中的printd()

#include <stdio.h>

int main(void)
{
   char a[100];
   a[0]='a';a[1]='b';a[2]='c';a[4]='d';

   {
     char * pa = a;

     pa++;
     printf("%c", *pa);
     pa++;
     printf("%c", *pa);
   }

   return 0;
`}

答案 1 :(得分:3)

在C语言中,函数参数列表中的数组声明和函数参数列表之外的数组声明意味着完全不同的东西,即使它们在表面上看起来相似(或相同)。

在函数参数列表中使用数组声明时(与代码中的void printd(char a[])一样),您声明一个数组。函数参数列表中的顶级[]语法只是指针声明的替代形式。这意味着您的a参数实际上声明为char *a。它根本不是一个数组,它是一个普通的指针。能够递增这样的a没有什么不寻常的,这就是为什么你没有从中获得任何“左值误差”。

与此同时,a中的main是一个真正的数组。

答案 2 :(得分:0)

  

为什么这个递增数组“a”不是错误?

在C数组中作为指向任何函数的指针传递。这就是为什么你没有错误。

main()中的函数调用将数组的{em> name 传递给a作为参数,因为表达式中数组的名称求值为指向数组的指针。换句话说,表达式a是指向数组{(1}}(的第一个元素)的指针。因此,它的类型为a[],并且被调用的函数使用此指针(作为参数传递)来间接访问数组的元素。

现在,当您收到char *的第一个元素的地址时,a表示数组的初始地址位于a++之前。这就是为什么第一个1打印printf,即数组b的第二个元素。

答案 3 :(得分:0)

a也可以作为指针。它是指向数组第一个元素的指针。 a ++增加指针。也就是说,在a ++之后a [0]或* a现在给出了[1]在增量之前给你的东西,即'b'。

请注意,您不会将[0]的值从“a”增加到“b”。检查是否在数组中使用了不同的值,例如'a,'d','h','x'。

答案 4 :(得分:0)

数组作为指针传递给函数,可以递增。

因此,在您的示例中,无法在a函数中递增main(),因为a是一个数组且无法递增。

但是,尽管语法不行,a函数中的printd()是一个指针,因此可以递增。在a内增加printd()不会影响main()中的数组a - 尽管它们具有相同的名称,但它们是不同范围内的不同实体。