840 likes | 944 Views
第九章 指针. 本章主要任务: 1 、指针的基本概念,变量访问方式; 2 、指针变量定义、赋值、引用。 3 、指针作为函数参数。 4 、数组的指针及指向数组(或数组元素)指针变量。 5 、指向数组的指针作为函数参数。. 内存.
E N D
第九章 指针 本章主要任务: 1、指针的基本概念,变量访问方式;2、指针变量定义、赋值、引用。 3、指针作为函数参数。 4、数组的指针及指向数组(或数组元素)指针变量。 5、指向数组的指针作为函数参数。
内存 内存(内部存储器):是由大规模集成电路芯片组成存储器,包括RAM、ROM。运行中的程序和数据都是存放在内存中的。与内存相对的是外存,外存是辅助存储器(包括软盘、硬盘、光盘),一般用于保存永久的数据。一定要记住:程序、数据是在内存中由CPU来执行和处理的。外存上尽管可以保存程序和数据,但是当这些数据在没有调入内存之前,是不能由CPU来执行和处理的。
内存地址 内存地址:内存是由内存单元(一般称为字节)构成的一片连续的存储空间,每个内存单元都有一个编号。内存单元的编号就是内存地址,简称地址。 CPU是通过内存地址来访问内存,进行数据存取(读/写)。
变量、变量名、变量的地址、变量值 变量: 命名的内存空间。变量在内存中占有一定空间,用于存放各种类型的数据。 变量名: 变量名是给内存空间取的一个容易记忆的名字。 变量的地址: 变量所使用的内存空间的地址。 变量值: 在变量的地址所对应的内存空间中存放的数值即为变量的值或变量的内容。
指针、变量的指针 指针: 就是 “内存单元的地址”。指针指向一个内存单元。 变量的指针: 就是“变量的地址”。变量的指针指向一个变量对应的内存单元。
指针变量 指针变量: 就是地址变量。地址(指针)也是数据,可以保存在一个变量中。保存地址(指针)数据的变量称为指针变量。 指针变量p中的值是一个地址值,可以说指针变量p指向这个地址。如果这个地址是一个变量i的地址,则称指针变量p指向变量i。指针变量p指向的地址也可能仅仅是一个内存地址。
说明 1、牢记:指针-地址。指针变量-地址变量。 2、指针变量是变量,它也有地址,指针变量的地址-指针变量的指针(指针的指针)。
系统访问变量的两种方式(变量的存取方式) 1、直接访问:按地址存取内存的方式称为“直接访问” 。 2、间接访问(使用指针变量访问变量) 。
直接访问 1)按变量名直接访问,按变量地址直接访问。 如:a=3; *(&a)=3; 从系统的角度看不管是按变量名访问变量,还是按变量地址访问变量,本质上都是对地址的直接访问。用变量名对变量的访问属于直接访问,因为编译后,变量名-变量地址之间有对应关系,对变量名的访问系统自动转化为利用变量地址对变量的访问。
直接访问 2)按地址直接访问(访问内存存储空间)-一般不要这么使用,这里仅为了说明概念。 如:*((int *)(2008))=5; 在地址2008保存一个整数。 farptr=(char far *)0xA0000000; *(farptr+offs+i1*MAXB)=*farbit; 操作显示内存。
间接访问(使用指针变量访问变量) 将变量a的地址(指针)存放在指针变量p中,p中的内容就是变量a的地址,也就是p指向a,然后利用指针变量p进行变量a的访问。 p=&a, *p=3。 从变量名获得变量地址用“&”运算符,从地址获得地址指向的数据用“*”运算符。
指针变量的定义 定义格式 : 基类型 *变量名;
说明 1、C语言变量先定义后使用,指针变量也不例外,为了表示指针变量是存放地址的特殊变量,定义变量时在变量名前加“*”号。 2、指针变量存放地址值,PC机用2个字节表示一个地址,所以指针变量无论什么类型,其本身在内存中占用的空间是2个字节。sizeof(pt1)=sizeof(f)=sizeof(pc)=2。
说明 3、指针变量的基类型(简称:指针变量类型):指针变量所指向数据的类型。我们知道,整型数据占用2个字节,浮点数据占用4个字节,字符数据占用1个字节。指针变量类型使得指针变量的某些操作具有特殊的含义。比如,pt1++;不是将地址值增1,而是表示将地址值+2(指向后面一个整数)。
指针变量的赋值方法 1、方法一:将地址直接赋值给指针变量(指针变量指向该地址代表的内存空间) 。 2、方法二:将变量的地址赋值给指针变量(指针变量指向该变量) 。
方法一 将地址直接赋值给指针变量(指针变量指向该地址代表的内存空间) 。 例如: char far *farptr=(char far *)0xA0000000; 将显存首地址赋值给指针。 float *f=(float *)malloc(4); malloc动态分配了4个字节的连续空间,返回空间首地址,然后将首地址赋值给浮点型指针f。这样浮点型指针f指向这个连续空间的第一个字节。
方法二 将变量的地址赋值给指针变量(指针变量指向该变量) 。 例如: int i,*p; p=&i;
指针变量的引用 &运算符(取地址运算符): 表示取变量的地址。 *运算符(指针运算符、间接访问运算符): 访问指针变量指向的变量的值。
指针变量作为函数的参数 指针变量作为函数参数时,同样是从实参单向传递指针变量的内容给形参,只是传递的内容是一个地址值。可以通过这个地址值间接改变实参、形参所共同指向的变量。所以尽管不能改变实际参数地址本身,但是可以间接改变地址所指向的变量。
应用举例 例10-2:输入a,b;交换a,b数据后输出。
说明 1、将主调函数变量的地址传递给被调用函数,就是说函数应当传递的是变量的地址。这样被调用函数的形参应当使用指针变量接受主调函数的地址值。
说明 2、在被调用函数中通过形参指针变量间接访问,修改实参、形参地址所共同指向的变量。本例的操作是交换两个指针变量所指向的变量。
数组的指针 数组的指针: 就是数组的地址。数组的地址指的是数组的起始地址(首地址),也就是第一个数组元素的地址。 C语言还规定数组名代表数组的首地址。
举例 对于整型数组int a[10]; 数组的指针就是数组的起始地址&a[0],也可以用数组名a表示。
指向数组的指针变量(指向数组元素的指针变量) 指向数组的指针变量: 存放数组元素地址(初始时一般为数组首地址)的变量,称为指向数组的指针变量(简称:数组的指针变量)。
说明 1、数组的指针变量的定义与数组元素的指针变量的定义相同。实质就是基类型指针变量的定义。 例如: int a[10],*p; 定义了一个整型数组a,如果需要定义指向该数组的指针变量就要定义一个整型指针变量p。
说明 2、数组的指针变量的初始化可以用两种方法: (1)定义时初始化,可以使用已经定义的数组的数组名来初始化数组的指针变量。 (2)通过赋值初始化,将数组的首地址赋值给数组的指针变量(数组的指针变量的赋值也与一般的指针变量的赋值相同)。
举例 int a[10],*p; 定义了一个整型数组a,一个整型指针变量p。 p=a; 或者p=&a[0]; 将数组a的首地址赋值给整型变量p,此时p就是指向数组的指针变量。 也可以: int a[10],*p=a; 在定义数组的指针变量p的同时初始化指向已经定义的数组a。
通过指针引用数组元素 1、指针p+i的含义(复习):不是地址值p增加i个字节后的地址值,而是指p向后移动i个基类型元素后的地址值。p-i,p++,p--都有类似的含义。 2、指针与数组的关系 。
通过指针引用数组元素 两种方法: 通过下标(索引)来访问数组元素的,数组元素的访问还可以通过指针完成。
数组元素的地址表示 假如: p定义为指向数组a的指针。数组元素a[i]的地址可以表示为:&a[i],p+i,a+i。
数组元素的访问 例如: 数组元素a[i]的访问可以是:a[i],*(p+i),*(a+i)。
数组指针变量,数组名在许多场合甚至可以交换使用数组指针变量,数组名在许多场合甚至可以交换使用 假如: p=a,那么a[i]甚至可以表示为p[i](指针变量带下标)
注意 1、数组名,数组指针变量使用时的区别:数组名是常量指针,它指向数组首地址,数组指针变量是变量,它的值可以改变。在不至于混淆的场合,数组名,数组指针变量可以统称数组指针。 例如:假设a、b是数组名,p是同类型的数组指针变量。 a++; *(a++); a=a+i; a=b; 错误 而p++; *(p++); p=p+i; p=a;都是可以的。
数组指针作为函数参数可以分为4种情况 1、形参、实参都是数组名。 2、实参是数组名,形参是指针变量 。 3、形参、实参都是指针变量 。 4、实参是指针变量,形参是数组名 。
指向多维数组的指针和指针变量 多维数组的指针: 维数组的地址(首地址)。 多维数组的指针变量: 存放多维数组地址的变量。
二维数组的地址 假设一个二维数组int S[3][4]。 S数组是一个3x4(3行4列)的二维数组。可以将它想象为一个矩阵(图1)。各个数组元素按行存储,即先存储s[0]行各个元素(s[0][0],...s[0][3]),再存储s[1]行各个元素(s[1][0],...s[1][3]),最后存储s[2]行各个元素(s[2][0],...s[2][3])。
指向由m个元素组成的一维数组的指针变量 定义格式:基类型 (*p)[m]; 说明:指定p是一个指针变量,它指向包含m个元素的一维数组。()不能省略,否则表示指针数组。 例如: int s[3][4]; int (*p)[4]; p=s;
字符串的表示形式 1、字符数组。 2、字符指。
字符数组 将字符串的各个字符(包括结尾标志‘\0’)依次存放到字符数组中,利用数组名或下标变量对数组进行操作。