写在前面
一个偶然的机会,学校ACM协会举行了一次试讲活动,内容为大一的C语言。而我恰巧分到了我最怕的、也是最难的指针,几经周折,多方请教,受益颇多。
此处整理出来,若能对读者有些许感触,也是极好的
一、内存中的数据是怎么存储的
内存中数据的存储如下:
线性,顺序,并且 “每个” 内存空间都有与之对应的地址
举个例子吧
如果将内存比作一个宾馆,将每一个存储空间比作一个房间,那么内存地址就相当于门牌号
二、程序中常用的“寻址方式”
此处只是列举的三个常用的,因为重点不在这里
(1)立即寻址
指令的地址字段指出的不是操作数的地址,而是操作数本身
(2)直接寻址
在指令格式的地址的字段中直接指出操作数在内存的地址
(3)间接寻址
间接寻址是相对直接寻址而言的,
在间接寻址的情况下,指令地址字段中的形式地址不是操作数的真正地址,
而是操作数地址的指示器,或者说此形式地址单元的内容才是操作数的有效地址。
比如
int b=0, a=3+2;//0,2和3属于立即寻址,也就是需要用的数据本身就在程序里面
int c=a+b;//此处根据a和b的名字来操作数据,a和b的其实可以用地址来替换,只不过写上一个0x***的没有只写上一个a简单,方便
int *p=&c //此处的p就是间接寻址,p中存储的不是数据而是数据的地址
三、指针是什么?
在理解了内存中的数据的存储方式已经常用的寻址方式后,再来谈指针就会轻松许多。
指针其实就是一个记录数据的地址的变量,
换言之,指针也是变量,只不过其中存储的不是数据而是地址。
如果你明白了什么是指针的话,那么多级指针之类的,都很容易理解.
拿二级指针来举例
二级指针就是指向指针的指针,两个指针里面存储的都是地址,
一级指针里面存储的是变量的地址,二级指针里面存储的是指针的地址
那么问题来了
既然指针中存储的是地址,内存中地址的长度(最大值)是确定的,那么为什么还要将指针分类为指向整形的,指向字符型等等???????
拿指向数组的指针
来说吧
在操作指向数组的指针时,肯定会牵扯到指针的自增,
此时系统就是根据指针类型的不同来判断自增的内存地址的多少
(一个整形占4个字节,那么就一次增加4个单元格,一个字符占一个字节,那么一次就增加一个字节)
四、指针能做什么
很多人(cai niao)都说,不用指针,我一样可以完成很多事情,为什么非要用指针,指针能做什么???
1 .什么时候用指针
如果用一个指针去指向一个变量的话,意义不大(自我感觉),在我看来(不一定正确)最常用的地方有两个
①用指针指向一个数组
例子一枚
#include
void main(){
int arr[]={1,2,3,5,31};
int *p=arr;
printf("%d\n",*(p+1));
printf("%d\n",*(arr+1));
printf("%d\n",arr[1]);
printf("%d\n",p[1]);
printf("-----------\n");
printf("%o\n",p);
printf("%o\n",arr);
printf("%o\n",&arr);
printf("%o\n",&arr[0]);
}
②用指针指向一个结构体
只要知道
结构体的指针来获取内部属性用的是“->”
2.为什么用指针
在我看来,在一般情况下不用指针也可以完成程序所需要的功能,
用指针是为了提高程序的效率,对程序进行优化
拿数组来举个例子。
选择排序
/例一、函数传递的是数组/
#include
void main(){
void swap(int arr[],int x,int y);
void sort1(int arr[],int n);
void printfArr(int arr[],int n);
int arr[]={111,22,13,4,51};
sort1(arr,5);
printfArr(arr,5);
}
void swap(int arr[],int x,int y){
int temp=arr[x];
arr[x]=arr[y];
arr[y]=temp;
}
void sort1(int arr[],int n){
int i=0,j=0,max=0;
for(i=0;iarr[max]){
max=j;
}
}
swap(arr,max,i);
}
}
void printfArr(int arr[],int n){
int i=0;
for(i=0;i
/例二、函数传递的是指针/
#include
void main(){
void swap(int *p,int x,int y);
void sort2(int *p,int n);
void printfArr(int *p,int n);
int arr[]={111,22,13,4,51};
int *p=arr;
sort2(p,5);
printfArr(p,5);
}
void swap(int *p,int x,int y){
int temp=p[x];
p[x]=p[y];
p[y]=temp;
}
void sort2(int *p,int n){
int i=0,j=0,max=0;
for(i=0;ip[max]){
max=j;
}
}
swap(p,max,i);
}
}
void printfArr(int*p,int n){
int i=0;
for(i=0;i
虽然结果都是能够对数组进行排序然后输出,但是其效率是完全不一样的。
为什么效率会不同呢???
-
如果参数传递的是一个数组,
函数在接收参数时会对数组进行一次复制(或者说将整个数组取出来),消耗较大,
有时候可能不一定用到数组中的所有的元素(比如例子中的swap函数) 如果传递的是指针的话,
好的一方面是仅仅传递一个指针,比较小,速度快;
但需要用到整个数组中的元素时,又需要根据指针多长访问内存,时间耗时在了此处。