zoukankan      html  css  js  c++  java
  • 第29课

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

    1. 数组的访问方式

    (1)访问数组元素有两种方式:以下标的形式访问数组中的元素 和 以指针的形式访问数组中的元素。

                  

    (2)下标形式 VS 指针形式

    • 指针以固定增量在数组中移动时,效率高于下标形式
    • 指针增量为1且硬件具有硬件增量模型时效率更高
    • 下标形式与指针形式的转换

                 

    ※※ 注意:现代编译器的生成代码优化率已大大提高,在固定增量时,下标形式的效率已经和指针形式相当,但从可读性和代码维护的角度来看,下标形式更优。

    【数组的访问方式】

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int a[5] = {0};
     6     int* p = a;
     7     int i = 0;
     8 
     9     for(i=0; i<5; i++)
    10     {
    11        p[i] = i + 1;
    12     }
    13 
    14     for(i=0; i<5; i++)
    15     {
    16        printf("a[%d] = %d
    ", i, *(a+i));
    17     }
    18 
    19     for(i=0; i<5; i++)
    20     {
    21        i[a] = i + 10;   // 等价于a[i] = i + 10
    22     }
    23 
    24     for(i=0; i<5; i++)
    25     {
    26        printf("p[%d] = %d
    ", i, p[i]);
    27     }
    28   
    29     return 0;
    30 }

    【数组和指针不同】

    ext.c

    1 int a[] = {1, 2, 3, 4, 5};

    29-2.c

     1 #include <stdio.h>
     2 
     3 // extern int a[];
     4 extern int *a;
     5 
     6 int main()
     7 {
     8     printf("&a = %p
    ", &a);
     9     printf("a = %p
    ", a);
    10     printf("a[0] = %d
    ", a[0]);
    11 
    12     return 0;
    13 }
    14 
    15 // extern int a[];
    16 // &a = 0x601040
    17 // a = 0x601040
    18 // a[0] = 1
    19 
    20 
    21 // extern int *a;
    22 // &a = 0x601040
    23 // a = 0x200000001
    24 // 段错误 (核心已转储)

    2. a 和 &a 的区别

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

    (2)&a 为整个数组的地址

    (3)a 和 &a 的区别在于指针运算,前者针对的是数组的元素,后者针对的是整个数组

    【指针运算经典问题】

     1 #include <stdio.h>
     2 
     3 int main()
     4 {
     5     int a[5] = {1, 2, 3, 4, 5}; 
     6     int* p1 = (int*)(&a + 1);       // 指向数组元素5的后一个位置
     7     int* p2 = (int*)((int)a + 1);   // 指向数组 (起始地址 + 1字节) 处,这里是整数运算,不是指针运算
     8     int* p3 = (int*)(a + 1);        // 指向第2个元素
     9 
    10     printf("%d
    ", p1[-1]);   // 5
    11     printf("%d
    ", p2[0]);    // 33554432
    12     printf("%d
    ", p3[1]);    // 2
    13 
    14     return 0;
    15 }

    3. 数组参数

    (1)数组作为函数参数时,编译器将其编译成对应的指针    // 数组长度信息没有意义,都是退化为指针

             

    (2)一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标示数组的大小

    【虚幻的数组参数】

     1 #include <stdio.h>
     2 
     3 void func1(char a[5]) // char a[5] ==> char *a
     4 {
     5     printf("In func1:sizeof(a) = %d
    ", sizeof(a)); // 8 ==> a退化为指针
     6     
     7     *a = 'a';
     8     
     9     a = NULL;  // a可以作为左值,证明不是数组
    10 }
    11 
    12 void func2(char b[]) // 数组长度有无没有关系,char b[] ==> char *b 
    13 {
    14     printf("In func2:sizeof(b) = %d
    ", sizeof(b)); // 8 ==> b退化为指针
    15     
    16     *b = 'b'; 
    17     
    18     b = NULL;  // a可以作为左值,证明不是数组
    19 }
    20 
    21 int main(){
    22     
    23     char array[10] = {0};
    24 
    25     func1(array);
    26     printf("array[0] = %c
    ", array[0]); // array[0] = a;
    27 
    28     func2(array);
    29     printf("array[0] = %c
    ", array[0]); // array[0] = b;
    30 
    31     return 0;
    32 }
  • 相关阅读:
    【数据结构与算法】C++Vector常用备忘
    【数据结构与算法】C++String常用备忘
    【JAVA】几个collection框架
    【JAVA】创建一维数组+创建二维数组
    DNN 错误代码 0x80070005 解决方案
    ehcache
    redis
    MySql优化—删除操作
    MySql优化过程及原理
    如何查看MySQL的执行计划
  • 原文地址:https://www.cnblogs.com/shiwenjie/p/11853973.html
Copyright © 2011-2022 走看看