读书笔记-C语言-指针-概述

1、计算机内存的每个字节也有编号,这些编号称为地址,也称指针。即指针就是地址,地址就是编号,也就是内存中字节的编号。

2、变量位于内存中,如定义变量int a;则变量a要占用内存中的4个字节(在visual c++6.0环境下)。变量a要占用哪4个字节呢?这是由计算机分配的,我们不能左右,而且在不同的计算机上运行程序或在同一计算机的不同时刻运行程序,变量被分配到的位置也不同。然而位置是可以假设的,假设变量a占据了内存中编号为1000~1003的4个字节,则这4个字节就被标记名称为“a”。用变量a保存一个整数,就是用这4个字节保存一个整数。例如执行语句a==1;则1就被保存到这4个字节中。

3、如果财务处位于办公楼的305,我们称财务处的地址是305,如果财务处比较大,占用了305-307三间房间,习惯上我们仍称财务处的地址为305,即取第一间房间号为地址。对于变量a,它占用了编号为1000-1003的4个字节,我们说变量a的地址为1000,也取它的第一个字节的编号作为变量的地址。注意变量a的地址为1000,变量a并不一定只占用编号为1000的这一个字节。(注意这里变量的地址都是假设的,实际运行程序时其地址不一定是1000、2000.例如变量a的实际地址可能是2031132,变量b的实际地址可能是3209356,而且一般以十六进制表示,分别为0x001efe1c、0x0030f88c)

4、变量的地址和变量的值

变量的地址:变量位于存储空间的“门牌号”,在整个程序运行期间,地址永久不变。

变量的值:变量空间中所保存的数据内容,在程序运行期间,变量的值是可以变化的。

5、访问变量有两种方式:(1)通过变量名(2)通过变量的地址。

访问变量:就是存取变量的值。

6、在程序中地址也需要变量来保存,然而地址不能被保存在普通变量中,C语言提供有一种特殊的专有变量专门用来保存地址,这种变量称为指针变量,指针变量也可简称为指针。“指针”准确含义有两个意思:一个是地址,二是指针变量。

7、定义指针变量

int  *p;

注意:变量名是p,不是*p。变量p的类型是int *,不是int。

可以通过如下语句将a的地址保存到p中:p=&a;

其中&表示取地址,我们在scanf语句中也使用过这个符号。&a表示变量a的地址,p=&a;则便是将a的地址赋值给指针变量p。

下面的做法是错误的:

int x;

x=&a;

x不是指针变量,不能保存地址。尽管内存中的字节编号是“整数”的,也不能用一个int型的变量来保存这种字节编号。

下面的做法也是错误的:

p=1;

因为p不能保存普通整数。

注意:1、由于变量a和变量x的定义语句分别是int a;int x;都没有*号,所以a、x都是普通变量,他们只能保存普通数据,不能保存地址。

2、由于变量p的定义语句是int *p;有*号,所以p是指针变量,他只能保存地址,不能保存普通数据。

3、指针变量也是变量,普通变量的特性指针变量同样具有。指针变量的空间也位于内存中,规定指针变量一律都占用4个字节。指针变量占用哪4个字节呢?它在内存中的位置也是由计算机分配的。但我们仍然可为其假设一个位置。假设指针变量p占据3000-3003的4个字节,这样也可以说,指针变量p的地址是3000.3000-3003的4个字节将用于保存一个地址,而不是用来保存 普通数据的。

5、指针变量p保存了普通变量a的地址,就是“对准了”普通变量a,因为将可通过p中保存的这个地址来访问变量a(就是存取变量a)。我们称:指针变量p指向了变量a或称p是指向变量a的指针变量。由于指针变量还可以简称为指针,后一句还可称为“p是指向变量a的指针”。

6、在一条定义语句中可以同时定义多个指针变量,也可以同时电议普通变量与指针变量,比如:

double *m, *n;

int  *x,y,  *z;

7、int  *p;

变量p的类型是int  *类型的。“int  *”类型是什么含义呢?它表示指针变量p所指向的数据的类型是int型,也就是说将来p要保存一个地址,但这个地址有讲究,必须是一个int型数据的地址才能被保存。

8、在定义指针变量时,*号之前的类型如int  *中的int是表示该指针变量将保存何种类型数据的地址,换句话就是说指针变量所能指向的数据的类型,该类型成为指针变量的基类型。指针变量要保存的地址必须是 基类型这种类型数据的地址,指针变量只能指向同基类型的数据。

void基类型指针。基类型表示任意类型。

void  *pt;   pt可以保存任意类型数据的地址,而无论数据是什么类型的。

9、为指针变量赋值。为指针变量赋值,两种方式:通过赋值语句的方式,或在变量定义时赋初值。

(1)通过赋值语句为指针变量赋值。

int   a=1;

int     *p;

p=&a;

注意:同普通变量类似,在为指针变量赋值之前,指针变量的值也是不确定的,也是随机数。它里面是个随机地址。

建议在定义指针变量的同时为其赋初值。

(2)定义指针变量时赋初值(定义时初始化)

int  *p=&a;

(3)指针变量之间彼此互相赋值。所赋的值是其中保存的地址。赋值要求两个指针变量基类型必须相同。

int  *p=&a;

int   *q;

q=p;/*则q、p均保存了变量a的地址,q、p均指向了变量a*/

(4)不允许把一个“数”当做地址直接赋值给指针变量。

int  *p;p=1000;/*错误,即使我们知道某个变量的地址是1000也不能这么干*/

特殊的,允许把数值0直接赋值给指针变量。p=0;(系统规定,如果一个指针变量里保存的地址为0,则说明这个指针变量不指向任何内容,叫做空指针)。

系统在stdio.h头文件中定义有符号常量NULL(#define NULL 0),因此也可写为:

p=NULL;/*正确,NULL是0的代替符号,仍是p=0的意思,注意NULL四个字母必须全部大写*/

注意:指针变量未赋值和赋0值是不同的,指针变量未赋值时,其保存的地址是随机地址,是不能使用的。而降指针变量赋0值,其保存的地址是0,是确定的,它不指向任何内容。

在定义指针变量时,如果不能确定它所指向的位置,可以先将其初始化为0或NULL,以免指针变量的随机指向。例如:int   *p=0;

10、指针运算俩兄弟——两个运算符

(1)&取地址运算符。获取变量的地址,写作&变量名。&运算符既可以取普通变量的地址,也可以取指针变量的地址。&p得到的地址是3000,&a得到的地址是1000.

(2)*指针运算符(或称间接访问运算符,只用于指针变量)。获取或改写以p为地址的内存单元的内容,写做*指针变量名。它就是“按图索骥”,按照p中所保存的地址,找到数据的意思。

举例:

int  *p;

int a=1;

p=&a;

printf("%d",*p);//输出1

printf(“%d”,p);//输出p本身的值即,输出a的地址。229416

如果已经定义int b;还可以执行:

b=*p;

以上语句是将a的内容1赋值给b。但如写为b=p;是错误的,因为它是把p中所保存的地址本身赋值给b,而变量b是不能保存地址的。

*p=2;

以上语句是将2送入p所指向的变量中,即a被赋值为2,它等价于语句a=2;实际上*p等价于a,用*p或用a都能存取a这个变量;前者是通过地址的“门牌号”访问变量,后者是通过变量名访问变量。

11、&和*都是单目运算符,结合方向“自右向左”。&和*互为逆运算,即一个&和一个*可以相互抵消,如果有p=&a,则:&*p<=>&a    *&*&*&*p<=>*p<=>a

12、定义指针变量时的的*和执行语句中运算符的*是完全不同的,它们是两种符号。

(1)在变量定义时写*就是指针变量的标志(前有int、double等类型说明符),如int  *p;的*,它没有任何“取数据”或“改数据”的含义。

(2)在执行语句中写*(前没有int、double等类型说明符)才是“取数据”或“改数据”的含义。

13、&:仅右边有一个量时取地址。

14、变量地址是计算机分配的,在不同的计算机上或在不同时刻运行程序都可能会有所不同。

你可能感兴趣的:(读书笔记-C语言-指针-概述)