zoukankan      html  css  js  c++  java
  • 《C语言程序设计(第四版)》阅读心得(三)

    第八章  指针

    1、一个变量的地址称为该变量的指针

           一个专门用来存放另一变量的地址(即指针),称它为指针变量。指针变量的值是指针(即地址)

      

            如上图2000是变量的指针,pointer是指针变量, 赋值语句可以为  *pointer = 3; *表示指向,*pointer表示指针变量pointer指向的变量

    2、指针变量的定义   类型名  *指针变量名;

                                       &    取地址运算符        &a是变量a的地址;

                                        *    指针运算符            *p代表指针变量p指向的对象  

    #include<stdio.h>
    int main()
    {
        int a=100,b=10;
        int *pointer1, *pointer2;
        pointer1 = &a;  //注意不是 *pointer1 = &a,这里的指针变量名是pointer1
        pointer2 = &b;
        *pointer2 = 20;
        printf("a=%d,b=%d
    ",a,b);
        printf("*pointer1=%d,*pointer2=%d",*pointer1,*pointer2);
        return 0;
    }

    3、指针变量作为函数参数

    int main()
    {
        int a,b;
        int *pointer1,*pointer2;
        scanf("%d%d",&a,&b);
        pointer1 = &a;
        pointer2 = &b;
        if( a<b ) Swap1( pointer1,pointer2);
        printf("max=%d  min=%d",a,b);
        return 0;
    }

    下面看一下回字的四种写法

    void Swap1( int *p1, int *p2)
    {
        int temp;
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
    }

    这种写法是可以完成交换的,把p1指向的内容交换,也就是a和b的值交换了

    void Swap2( int *p1, int *p2)
    {
        int *temp;
        temp = p1;
        p1 = p2;
        p2 = temp;
    }

    这种做法的意思是把指针变量的值进行交换,但是这是办不到的。因为C语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式。

    不可能通过执行调用函数来改变实参指针变量的值,但是可以改变实参指针变量所指变量的值。

    void Swap3( int *p1, int *p2)
    {
        int *temp;
        *temp = *p1;
        *p1 = *p2;
        *p2 = *temp;
    }

    这种做法更加就不靠谱一点,*p1就是a,是整型变量, *temp是指针变量temp所指向的变量,但由于未给temp赋值,因此temp中并无确定的值,所以temp所指向的单元也是不可预见的,所以,对*temp赋值就是向一个未知的存储单元赋值,而这个未知的存储单元中可能存储着一个有用的数据,这样就有可能破坏系统的正常工作情况。

    void Swap4( int a, int b)
    {
        int temp;
        temp = x;
        x = y;
        y = temp;
    }

    这个就是比较明显的形参值的改变不能使实参值随之改变,x与y的值交换了,但是a与b的值并未受到影响

    4、通过指针引用一维数组

        1)在C语言中,数组名(不括形参数组,形参数组不占据实际的内存空间)代表数组中首元素(即序号为0的元素)的地址

    int *p;
    p = &a[0];
    p = a;   //以上两句等价

      2)如果指针变量p已经指向数组中的一个元素,那么p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。

      3)如果p的初值为&a[0],那么p+i和a+i就是数组元素a[i]的地址,*(p+i)或*(a+i)是p+i或a+i所指向的数组元素,即a[i]

      4)设p指向数组a的首元素(p=a)

    p++;
    *p;  
    //p++使p指向a[1],再执行*p得到a[1]的值
    
    *p++;
    //等价于*(p++);相当于a[i++]
    //先引用p的值,实现*p的运算,得到a[0],再自增
    
    *(++p);
    //相当于a[++i]
    //先p自增,再运算得到a[1]
    
    ++(*p);
    //相当于 ++a[0];

    5、通过指针引用多维数组

    设一个二维数组  int a[3][4]={ {1,3,5,7},{9,11,13,15},{17,19,21,23} };

    表示形式

    含义

    地址

    a

    二维数组名,指向一维数组a[0],即0行的首地址

    2000

    a+1 ,&a[1]

    1行首地址

    2016

    a[1],*(a+1)

    1行0列元素a[1][0]的地址

    2016

    a[1]+2,*(a+1)+2,&a[1][2]

    1行2列元素a[1][2]的地址

    2024

    *(a[1]+2),*(*(a+1)+2),a[1][2]

    1行2列元素a[1][2]的值

    元素值为13

    比较难理解的是 *(a+1)并不是a+1单元的内容(值),因为a+1并不是一个变量的存储单元,也就谈不上它的内容了。*(a+1)就是a[1]

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include<string.h>
     4 
     5 int main()
     6 {
     7     int a[2][3]= {1,2,3,8,5,6},*p=&a[0][0];
     8     printf("a[0]=%d
    ",*a[0]);  // 1
     9     printf("a[1]=%d
    ",*a[1]);  // 8
    10     printf("a[1]+1=%d
    ",*a[1]+1); // 9
    11     printf("(a[1]+1)=%d
    ",*(a[1]+1)); // 5
    12     printf("%d
    ",*(p+1)); //2
    13     return 0;
    14 }

    必须清楚:二维数组名(如a)是指向行的,因此a+1中的1代表一行中全部元素所占的字节

                        一维数组名(如a[1])是指向列元素的,a[0]+1中的1代表一个a元素所占的字节数

                        在指向行的指针前面加一个*,就转换为指向列的指针如 *(a+1)

                        在指向列的指针前面加一个&,就成为指向行的指针

    在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
  • 相关阅读:
    JSpider(1):配置与运行
    JSpider(4):Tasks,Events&Visitors
    WebUI Case(1): www.swtdesigner.com 首页 (续)
    java web开发_购物车功能实现
    java web开发_多拿网/淘宝网购物车选择操作
    java开发_快速搜索本地文件_小应用程序
    lucene(全文搜索)_恢复/更新索引操作
    lucene(全文搜索)_根据内容建立索引_源码下载
    程序员,都去写一写前端代码吧
    javascript_时间自动刷新
  • 原文地址:https://www.cnblogs.com/yuxiaoba/p/8470736.html
Copyright © 2011-2022 走看看