《C专家编程》学习记录——指针和数组相同的地方

一、在普通的表达式中 

  普通的C语言表达式中,编译器把数组名数组名换成指向数组第一个元素的指针

  先看一段简单的代码

char a[8];

a[3]=9;
3[a]=2;
printf("a[3] = %d ", a[3]);
printf("3[a] = %d ", 3[a]);

结果是:

a[3] = 2
3[a] = 2

原因:表达式中的数组名被编译器当做一个指向该数组第一个元素的指针(ANSI C标准),即在表达式中,指针和数组是可以互换的,因为他们在编译器里的最终形式都是指针,并且都可以进行取下标操作。就像加法一样,取下标操作符的操作数是可以交换的,所以表达式使用中,a[3]和3[a]两种形式都是正确的。(只为理解表达式中数组名被编译器当做指向数组第一个元素的指针,实际不用)。

二、数组做函数形参

编译器把数组名当做指向第一个元素的指针,且长度未知。

下面两种形式都可以,数组名都是当指针用。

void fun1(int *p);
void fun2(int arr[]);
int b[10] = {22,22,22,22,22,22,22,22,22,22};
int main(void)
{
    
    int a[10] = {1,2,3,4,5,6,7,8,9,0};
    fun2(a);
    
}

void fun1(int *p)
{
    char i;
    
    p[1] = 20;
    *p = 10;
    for(i=0; i<10; i++)printf("%d   ",p[i]);printf("
");
    
    p=b;
    for(i=0; i<10; i++)printf("%d   ",p[i]);printf("
");
}

void fun2(int arr[])
{
    char i;
    
    arr[1] = 20;
    *arr = 10;
    for(i=0; i<10; i++)printf("%d   ",arr[i]);printf("
");
    
    arr=b;
    for(i=0; i<10; i++)printf("%d   ",arr[i]);printf("
");
}

数组名是不可修改的左值,因此下面代码会编译错误,

    int a[10] = {1,2,3,4,5,6,7,8,9,0};
    int b[10] = {22,22,22,22,22,22,22,22,22,22};
    
    a[1]=10;
    *a=20;
    a = b;  //编译失败

这也证明函数参数是数组时,实际编译器是当指针处理的

 另:结构体类型可以做函数参数,可以做函数返回值,可以做左值(用另一个结构体变量整体赋值)

另外:函数传参顺序,先右后左:

    char a[12] = "hello,world";
    char *p = a;
    printf("%x,  %x,  %x,  %x", a, ++p, p++, p++);

结果:

54a632c0,  54a632c3,  54a632c1,  54a632c0

这是因printf是一个函数,计算参数时,是从右向左压栈的,所以最右边的p++先打印p的地址54a632c0,然后p++为54a632c1,再打印p的地址54a632c1,再p++为54a632c2,再++p为54a632c3

 
原文地址:https://www.cnblogs.com/keepdoing123/p/12160730.html