c语言指针

看了《c和指针》 ,读书笔记如下。

关于指针

1、

int a=12;

int *b=&a;

int **c=&b;

-----------------------

期中第二句相当于 int *b; b=&a;

期中第三句相当于 c=&b;*c就是b,也就是&a;**c就是*b,就是a,也就是12

第三句是指针的指针,详情描述见下面例四。它有什么用

2、

char ch = 'a';

char *cp=&ch;

---------------------------------

一个赋值表达式:
X = Y;
在这个表达式里,符号X的含义是X所代表的地址,这被称为左值,左值在编译时可知,左值表示存储结果的地方;
在这个表达式里,符号Y的含义是Y所代表的地址的内容,这被称为右值,右值在运行时才可知,如无特别说明,右值表示“Y的内容”。

在《C专家编程(中文版)》中第4章,对左值和右值的基本描述,其余的拓展描述你可以自己看。
关于左值和右值。《c和指针》也有提及
比如 int a=50;
此时的a就是左值,是存50的地址;
a=a+1; 右值的a是内容,加一;左值的a是地址。
50=a+1;这种写法就是错误的。

&ch  右值:ch的地址。左值:非法。为什么非法,因为当表达式&ch求值时,它的结果应该储存在计算机的某个地方,但你无法知道它位于何处,所以不是合法左值。

cp   右值是cp的值。左值:cp所处的内存位置。

&cp 右值:指针变量的地址。左值:非法

*cp+1  右值:就是cp指向的ch内容加1.左值:非法

*(cp+1)右值:cp指向的ch的下一个单元内容。左值:cp指向的ch的下一个单元内容的地址

++cp 右值:cp指向的ch的下一个单元内容的一份拷贝。左值:非法。

cp++ 右值:cp指向ch的地址。然后cp再加一。左值:非法。

3、

int *a;

*a=12;

上述是非法的。未初始化,*a指向了哪里呢,覆盖了以前的内容,很容易覆盖一些重要的数据。这句话的意思就是把12存储在a指向内存的位置,但具体哪个位置,不得而知。

例四:指针的指针(它到底有什么用)

指针的指针看上去有些令人费解。它们的声明有两个星号。例如:
        char ** cp;
    
如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针,依次类推。当你熟悉了简单的例子以后,就可以应付复杂的情况了。当然,实际程序中,一般也只用到  二级指针,三个星号不常见,更别说四个星号了。
    指针的指针需要用到指针的地址。
        char c='A';
        char *p=&c;
        char **cp=&p;
    
通过指针的指针,不仅可以访问它指向的指针,还可以访问它指向的指针所指向的数据。下面就是几个这样的例子:
        char *p1=*cp;
        char c1=**cp;
    
你可能想知道这样的结构有什么用。利用指针的指针可以允许被调用函数修改局部指针变量和处理指针数组。

        void FindCredit(int **);

        main()
        {
            int vals[]={7,6,5,-4,3,2,1,0};
            int *fp=vals;
            FindCredit(&fp);
            printf(%d ,*fp);
        }

        void FindCredit(int ** fpp)
        {
            while(**fpp!=0)
            if(**fpp<0) break;
            else (*fpp)++;
        }

    
首先用一个数组的地址初始化指针fp,然后把该指针的地址作为实参传递给函数FindCredit()。FindCredit()函数通过表达式**fpp间接地得到数组中的数据。为遍历数组以找到一个负值,FindCredit()函数进行自增运算的对象是调用者的指向数组的指针,而不是它自己的指向调用者指针的指针。语句(*fpp)++就是对形参指针指向的指针进行自增运算的。但是因为*运算符高于++运算符,所以圆括号在这里是必须的,如果没有圆括号,那么++运算符将作用于二重指针fpp上。

#include <stdio.h>
void FindCredit(int **);

        main()
        {
            int vals[]={7,6,5,-7,3,2,1,0};
            int *fp=vals;
            FindCredit(&fp);
            puts("找出数组中的负数来,它是");
            printf("%d
",*fp);
        }
        /*对照一下 *fp=vals【这里就是values的首地址】; 形参传递到实参相当于 **fpp=&fp 
        int a=12;
        int *b=&a;
        int **c=&b;        
        */ 

        void FindCredit(int ** fpp) //相当于**fpp=&fp 
        {
            while(**fpp!=0)
            if(**fpp<0) break;
            else (*fpp)++;
        }

//  首先用一个数组的地址初始化指针fp,然后把该指针的地址作为实参传递给函数FindCredit()。FindCredit()函数通过表达式**fpp间接地得到数组中的数据 

参考网站:http://www.cnblogs.com/gmh915/archive/2010/06/11/1756067.html

原文地址:https://www.cnblogs.com/bluewelkin/p/4060692.html