• 听翁恺老师mooc笔记(6)--指针运算


    指针值加1就是将指针值加上sizeof(指针所指变量的类型)

      1+1=2,那么指针加1是加上了1这个数字吗?试一下,在代码中定义了char数组,char也是整数,数组名是ac,ac中有10个元素,0-9,然后做了一个char *p=ac,定义了*p的一个指针,p指向了ac数组的第一个单元。然后分别输出p和p+1的值,结果是差了1:

     1 #include <stdio.h>
     2 
     3 int main(void){
     4     char ac[] = {0,1,2,3,4,5,6,7,8,9};
     5     char *p = ac;
     6     printf("p  =%p
    ",p);   //输出p的值
     7     printf("p+1=%p
    ",p+1); 
     8 
     9     return 0;
    10 }
    View Code

      再对程序进行修改,将char改成int,然后指针变量p改成q,结果显示q和q+1差了4:

     1 #include <stdio.h>
     2 
     3 int main(void){
     4     char ac[] = {0,1,2,3,4,5,6,7,8,9};
     5     char *p = ac;
     6     printf("p  =%p
    ",p);   //输出p的值
     7     printf("p+1=%p
    ",p+1); 
     8 
     9     int ai[] = {0,1,2,3,4,5,6,7,8,9};
    10     int *q = ai;
    11     printf("q  =%p
    ",q);   //输出p的值
    12     printf("q+1=%p
    ",q+1); 
    13 
    14     return 0;
    15 }
    View Code

      综合上述两个例子,char为何是加1,而int是为何是差了4那?因为sizeof(char)=1,sizeof(int)=4,所以我们再对指针加1的时候,实际不是再地址值上加1而是在地址值上加sizeof(指针所指变量的类型),为什么?因为char数组,第一个元素的地址是30,大小是1个字节,那么第二个元素的地址就是31,而int数组中1个元素需要占用4个字节,所以第一个元素(0)的地址是00,那么第二个元素的地址是04,第三个元素的地址差不多就是08,相邻单元的地址差了4个,正好和int类型的大小一致。

      q的值是第一个单元的地址,也就是说q指向了第一个单元,那么q+1=04,就是q+1指向了第二个单元。所以对指针做一个加1的东西意味着将它移到下一个单元去,实际的指针值加上的是sizeof变量类型。同学们可以使用这个程序试一下long long,double,short等,测试下是不是加的sizeof。

      我们在学指针和数组时说过,你拿到指针可以像数组一样操作,也可以拿到数组像指针一样操作,以上述例子为例,*p就相当于是ac[0],那么*(p+1)就相当于是ac[1],这里也可以做实验输出*p,*(p+1)的值都是多少,是否和a[1]的值一样。所以当p指向一个数组时,p+n实际上就是指向了数组n的第n个元素,所以*(p+n)=a[n]。但是如果指针不是指向数组这种一片连续分配的空间时,就这种运算没有意义。

    指针的其他加减运算(1)(2)(3)

      除了指针可以加1,还可以给(1)指针加、减一个整数(+,+=,-,-=),减的意思是往前挪一些,加是往后挪。还可以做(2)递增递减(++,--),在以后的运算中经常看到对指针加加减减的运算。还可以的运算是(3)两个指针可以相加或者向减,对这种运算实验下:(给学生详细介绍程序和结果)结果显示p1-p是5,我们可以理解第5个元素减去第0个元素就是5.而q1-q是6,不应该是6*4=24吗?可以再输出q1的地址和q的地址,使用十六进制计算器进行减法是24。所以,q1-q的差值不是地址相减,而是这两个地址的差除以sizeof类型,也就是告诉我们中间差了几个数组单元。

     *p++运算

      在指针运算中还比较常见的是*p++的运算,*p++有两个运算符,从优先级上来说,++比*的优先级高,但是++是后缀,所以*p++的意思是先*p,然后p++,相当于*(p++)。这个运算常用于数组类的连续空间操作:

     1 #include <stdio.h>
     2 
     3 int main(void){
     4     char ac[] = {0,1,2,3,4,5,6,7,8,9,-1};
     5     char *p = ac;
     6     int i;
     7     for(i=0;i<sizeof(ac)/sizeof(ac[0]);i++){
     8         printf("%d
    ",ac[i]);
     9     }
    10 
    11     while (*p!=-1){
    12         printf("%d
    ",*p++);
    13     }
    14     return 0;
    15 }
    View Code

    指针比较运算

      指针比较运算包括<,<=,==,>,>=,!=等等。指针的比较其实就是地址大小的比较,如果一个指针指向a[0],一个指针指向a[5],很明显a[0]要比a[5]的值要小,数组是顺序递增排列的

    0地址

      我们现代的操作系统,包括windows,macs,linux,unix等都是多进程的,基本的管理单元是进程,什么叫进程那?双击一个东西,这个东西运行起来就是一个进程,对于进程来说,操作系统会给他一个虚拟的地址空间,所有的进程都以为自己拥有一个从0开始的地址空间,直到4G(32位机器)。所以任何程序里面都有0地址,不是说这个程序使用了0地址,另外一个程序就不可以使用0地址,所有程序都有虚拟的0地址,那么这个虚拟的0地址的物理地址(真实地址)是多少我们不用管,这是操作系统的事。

      每个程序都有0地址,但是0地址通常是个不能随便碰的地址,一般我们使用0地址做一些特殊的事情,比如说你要返回指针,返回0告知你返回的指针是无效的,或者当你有了一个指针变量之后,可以先给他赋上一个0,0表示指针没有被真正初始化,当你对赋值0的指针操作的话,系统肯定会崩溃(可以实验验证下)。

      C语言事先定义了NULL(全部大写)作为预先定义的符号,表示0地址,有些编译器愿意你用0来表示0地址,有些则不愿意那么就可以使用NULL表示0地址。这件事情牵涉的比较深远,这块只做简单说明。

    指针类型转换

      一个指针有各种类型,有char,有int等。同一类型的指针,所有的指针的大小都是一样的,因为都是地址。但是不同类型的指针是不能互相赋值的(可以编码验证)。这主要是为了避免用错指针。

      关于指针的类型转换,可以使用void*:

    指针有什么用那?

      (1)需要传入比较大的数据时,可以使用指针作为参数,比如传递数组。

      (2)传入数组后,可以使用指针对数组做操作。

      (3)当函数返回不止一个结果时,可以使用指针做参数让它带出结果。

      (4)当使用函数修改不止一个变量时,比如swap,传指针进去,让函数修改变量的值

      (5)当动态申请的内存时。。。。

  • 相关阅读:
    CSS规范
    CSS规范
    CSS规范
    CSS function--(来自网易)
    CSS reset--(来自网易)
    js截取图片上传(仅原理)----闲的无聊了代码就不共享了!写的难看,不好意思给你们看了(囧)
    作业:JavaScript(数组篇-poker)给我的徒弟出个题。。。记得早点写完,然后大家3人可以早点打牌了
    BAT及各大互联网公司2014前端笔试面试题--JavaScript篇(昨天某个群友表示写的简单了点,然后我无情的把他的抄了一遍)
    BAT及各大互联网公司2014前端笔试面试题--Html,Css篇(昨天有个群友表示写的简单了点,然后我无情的把他的抄了一遍)
    本日吐槽!“人傻钱多”的P2P公司是否是程序员的合适选择(群聊天记录的娱乐)
  • 原文地址:https://www.cnblogs.com/c-programing-language/p/6497167.html
Copyright © 2020-2023  润新知