浅谈指针

写在前面

一个偶然的机会,学校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<stdio.h>  
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<stdio.h>  
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;i<n-1;i++){  
        max=i;  
        for(j=i+1;j<n;j++){  
            if(arr[j]>arr[max]){  
                max=j;  
            }  
        }  
        swap(arr,max,i);  
    }  
}  
void printfArr(int arr[],int n){  
    int i=0;  
    for(i=0;i<n;i++){  
        printf("%d\n",arr[i]);  
    }  
}  

/例二、函数传递的是指针/

#include<stdio.h>  
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;i<n-1;i++){  
        max=i;  
        for(j=i+1;j<n;j++){  
            if(p[j]>p[max]){  
                max=j;  
            }  
        }  
        swap(p,max,i);  
    }  
  
}  
void printfArr(int*p,int n){  
    int i=0;  
    for(i=0;i<n;i++){  
        printf("%d\n",p[i]);  
    }  
}  

虽然结果都是能够对数组进行排序然后输出,但是其效率是完全不一样的。


为什么效率会不同呢???

  • 如果参数传递的是一个数组,

    函数在接收参数时会对数组进行一次复制(或者说将整个数组取出来),消耗较大,
    有时候可能不一定用到数组中的所有的元素(比如例子中的swap函数)

  • 如果传递的是指针的话,
    好的一方面是仅仅传递一个指针,比较小,速度快;
    但需要用到整个数组中的元素时,又需要根据指针多长访问内存,时间耗时在了此处。

因此,具体怎么取舍,还是要看具体情况


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,387评论 3 44
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,446评论 1 51
  • void* 类型指针:通用变体类型指针;可以不经转换,赋给其他指针,函数指针除外;malloc返回的就是void*...
    冰吉凌阅读 3,229评论 0 18
  • 我本无眼 混沌初开时, 我便有了眼。 我本无口 天地相离时, 我便有了口。 我本无识 日月照拂, 我便有了识。 我...
    cceeb1c6aac9阅读 205评论 0 1
  • zy_Mandy阅读 164评论 0 1