第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\n", 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\n", 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\n", &a); 9 printf("a = %p\n", a); 10 printf("a[0] = %d\n", 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\n", p1[-1]); // 5 11 printf("%d\n", p2[0]); // 33554432 12 printf("%d\n", 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\n", 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\n", 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\n", array[0]); // array[0] = a; 27 28 func2(array); 29 printf("array[0] = %c\n", array[0]); // array[0] = b; 30 31 return 0; 32 }