第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 }
原文地址:https://www.cnblogs.com/shiwenjie/p/11853973.html