第29课 指针和数组分析(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第29课 指针和数组分析(下)相关的知识,希望对你有一定的参考价值。

1. 数组的访问方式

(1)以下标的形式访问数组中的元素:如a[i];

(2)以指针的形式访问数组中的元素:如*(a+i)

2. 下标形式 VS 指针形式

(1)指针形式以固定增量在数组中移动时,效率高于下标形式

(2)指针增量为1且硬件具有硬件增量模型时,效率更高

(3)下标形式与指针形式的转换:a[n]==*(a+n)==*(n+a)==n[a];

▲注意:

  ①现代编译器的生成代码优化率已大大提高,在固定增量时,下标形式的效率与指针形式相当;

②但从可读性和代码维护的角度看,下标形式更优

【实例分析】数组的访问方式

#include <stdio.h>

int main(){
    
    int a[5] = {0};
    int* p = a;
    int i = 0;

    for(i=0; i<5; i++)
    {
       p[i] = i + 1; //利用指针给数组元素赋值
    }

    for(i=0; i<5; i++)
    {
       //以指针形式来访问数组元素
       printf("a[%d] = %d\n",i,*(a+i));
    }

    for(i=0; i<5; i++)
    {
       //以下标形式来访问数组元素
       i[a] = i + 10; //比较另类,相当于a[i] = i + 10
    }

    for(i=0; i<5; i++)
    {
       //通过指针来访问数组元素
       printf("p[%d] = %d\n",i,p[i]);
    }
  
    return 0;
}

【编程实验】数组和指针不同

//ext.c

//实验时,本文件应为.c,而不能是头文件。因为头文件会被直接包含在相应文件中,
//而.c文件是分别编译的

int a[5] = {1, 2, 3, 4, 5}; //在该文件中,a被看作一个数组

//29-2.c

#include <stdio.h>

//命令行编译这两个文件:gcc 29-2.c ext.c

int main(){
    
   //外部文件中a被定义成一个数组。int a[5] = {1, 2, 3, 4, 5}; 

    //实验1:
    extern int a[]; //本文件,如果这样声明,a仍被看作一个数组
   
    printf("&a = %p\n", &a); //这里的&a为整个数组的地址
    printf("a = %p\n",a);    //a为首元素的地址,数值上等于&a
    printf("*a = %d\n",*a);  //打印出第1个元素,即1


    //实验2:
/*
    extern int* a;  //如果这样声明,编译器将a当成是一个int型的
                    //指针来使用。
   
    printf("&a = %p\n", &a); //会从符号表中查到指针a的地址,指向数组
    printf("a = %p\n",a);    //从指针a处,取一个int型的数据,即第1个元素,为1
    printf("*a = %d\n",*a);  //试图从地址0x01处取出数据,违规内存访问错误。
*/  
    return 0;
}

 

3. a和&a的区别

(1)a为数组首元素的地址

(2)&a为整个数组的地址,即可将数组看成是一种数据结据。如int[5];

(3)a和&a的区别在在指针运算

  a + 1 == (unsigned int)a + sizeof(*a);//a代表首元素地址,*a表示第1个元素

  &a + 1 == (unsigned int)(&a) + sizeof(*&a) ==  (unsigned int)(&a) + sizeof(a);

【实例分析】指针运算经典问题

4. 数组参数

(1)数组作为函数参数时,编译器将其编译为对应的指针。因此,一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标示数组的大小。

     void f(int a[])等价于void f(int* a);

     void f(int a[5])等价于void f(int* a); //就是一个指针,丢失了数组长度的信息

【实例分析】虚幻的数组参数

5. 小结

(1)数组名和指针仅使用方式相同,数组名的本质不是指针,指针的本质也不是数组。

(2)数组名并不是数组的地址,而是数组首元素的地址

(3)函数的数组参数退化指针

以上是关于第29课 指针和数组分析(下)的主要内容,如果未能解决你的问题,请参考以下文章

指针和数组分析(下)

第28课 指针和数组分析(上)

指针和数组分析(上)

php怎么取出一组数组中每个下标下的最后一个元素

第41课 内存操作经典问题分析一

第36课 函数与指针分析