29_指针和数组分析(下)
2018-03-27 13:57
295 查看
关键词:下标形式VS指针形式、数组和指针的不同点、a和&a的区别、数组参数
(2) 通过指针的形式访问数组中的元素
(2) 指针增量为1,且硬件具有硬件增量模型时,效率更高;
(3)下标形式与指针形式的转换:a
输出结果:
总结: 通过上面程序验证可知:指针可以当作数组名使用。
输出结果:
修改:将数组的形式定义为指针的形式
输出结果
总结:这两个程序对比可知得到,数组名不是指针,只是我们在通常情况下将数组名作为常量指针来使用。
(2) &a为整个数组的地址
(3) 区别在于指针运算
a + 1 <==> (unsigned int)a + sizeof(* a)
&a + 1 <==> (unsigned int)a + sizeof(* &a) <==> (unsigned int)a + sizeof(a)
输出结果:
总结: 用-1访问数组指的是访问数组名的上一个元素;
void f(int a[]) <==> void f(int* a)
void f(int a[5]) <==> void f(int* a)
总结:一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标识数组的大小。
输出结果:
总结: 通过fun1中的a = null 和 fun2中的b = null 可知数组作为函数传递的为指针。
(2)数组名并不是数组的地址,而是数组首元素的地址;
(3)函数的数组参数退化为指针。
声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!
问题: 数组名可以当作常量指针使用,那么指针是否也可以当作数组来使用呢?
(1) 通过下标的形式访问数组中的元素int main() { int a[5] = {0}; a[1] = 3; a[2] = 5; return 0; }
(2) 通过指针的形式访问数组中的元素
int main() { int a[5] = {0}; *(a + 1) = 3; *(a + 2) = 5; return 0; }
1. 下标形式VS指针形式
(1) 指针以固定增量在数组中移动,效率高于下标的形式;(2) 指针增量为1,且硬件具有硬件增量模型时,效率更高;
(3)下标形式与指针形式的转换:a
<==> (a + n) <==> (n + a) <==> n[a]
note: 现代编译器的生成代码优化率已大大提高,在固定增量时,下标形式的效率已经和指针形式的相当;但从代码可读性和代码维护性的角度来看,下标形式的更优。
#include<std 4000 io.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)); } printf("\n"); 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; }
输出结果:
a[0] = 1 a[1] = 2 a[2] = 3 a[3] = 4 a[4] = 5 p[0] = 10 p[1] = 11 p[2] = 12 p[3] = 13 p[4] = 14
总结: 通过上面程序验证可知:指针可以当作数组名使用。
2. 数组和指针的不同点
extern.c a[5] = {0};
2.c #include<stdio.h> int main() { extern int a[5]; // 定义为数组的形式 printf("&a = %p\n", &a); printf("a = %p\n", a); printf("*a = %d\n", *a); }
输出结果:
&a = 0x804a024 a = 0x804a024 *a = 0
修改:将数组的形式定义为指针的形式
#include<stdio.h> int main() { extern int* a; // 定义为指针的形式 printf("&a = %p\n", &a); printf("a = %p\n", a); printf("*a = %d\n", *a); }
输出结果
&a = 0x804a024 a = 0x1 Segmentation fault
总结:这两个程序对比可知得到,数组名不是指针,只是我们在通常情况下将数组名作为常量指针来使用。
3. a和&a的区别
(1) a为数组首元素的地址(2) &a为整个数组的地址
(3) 区别在于指针运算
a + 1 <==> (unsigned int)a + sizeof(* a)
&a + 1 <==> (unsigned int)a + sizeof(* &a) <==> (unsigned int)a + sizeof(a)
#include<stdio.h> int main() { int a[5] = {1, 2, 3, 4, 5}; int* p1 = (int*)(&a + 1); // p1指向数组最后一个元素的后一个地址 int* p2 = (int*)((int)a + 1); // p2指向的值为:将a的地址值强制转化为int型后+1 int* p3 = (int*)(a + 1); // p3指向第二个元素 printf("%d, %d, %d \n", p1[-1], p2[0], p3[1]); return 0; }
输出结果:
5, 33554432, 3
总结: 用-1访问数组指的是访问数组名的上一个元素;
4. 数组参数
数组作为函数参数时,编译器将其编译成对应的指针:void f(int a[]) <==> void f(int* a)
void f(int a[5]) <==> void f(int* a)
总结:一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标识数组的大小。
#include<stdio.h> void fun1(char a[5]) { printf("In func1: sizeof(a) = %d\n", sizeof(a)); *a = 'a'; a = NULL; } void fun2(char b[]) { printf("In func2: sizeof(b) = %d\n", sizeof(b)); *b = 'b'; b = NULL; } int main() { char array[10] = {0}; fun1(array); printf("array[0] = %c\n", array[0]); fun2(array); printf("array[0] = %c\n", array[0]); return 0; }
输出结果:
In func1: sizeof(a) = 4 array[0] = a In func2: sizeof(b) = 4 array[0] = b
总结: 通过fun1中的a = null 和 fun2中的b = null 可知数组作为函数传递的为指针。
小结
(1) 数组名和指针仅使用方式相同,注意数组名的本质不是指针; 指针的本质不是数组;(2)数组名并不是数组的地址,而是数组首元素的地址;
(3)函数的数组参数退化为指针。
声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!
相关文章推荐
- 数组名与指针典型面试题的分析
- 实验9 指针1 1、程序填空:下列程序在数组中同时查找最大元素和最小元素的下标,分别存放在 main()函数的max 和 min 变量中。要求:根据运行结果分析程序和填空,并注释说明填充依据。
- C语言中字符数组和字符串指针分析
- 数组与指针典型面试题分析--深入理解指针含义
- C语言中字符数组和字符串指针分析
- 结构体变量、结构指针变量、结构数组作为函数的参数应用实例分析
- C语言中字符数组和字符串指针分析
- 32_数组指针和指针数组分析
- 数组名与指针典型面试题的分析(2)
- C 语言中字符数组和字符串指针分析
- C++中使用基类指针操作子类数组的分析
- 指针访问与数组访问的效率分析
- 数组 与 指针 之间的关系 分析
- 指针数组 和 数组指针分析 main函数的参数
- 主题四 指针和数组(下)----25.指针数组与数组指针分析
- 专题4-7数组参数和指针参数分析(国嵌C语言视频)
- C语言深度剖析-----数组参数和指针参数分析
- C语言中字符数组和字符串指针分析
- [C++] 从编译器角度分析数组名与指针的区别
- 信管14:对象数组、指针示例分析例程