第九章:指针 级重点及要求: 燬掌握指针的概念、定义、指针变量的引 用,掌握地址与指针的关系,掌握指针 与数组的关系。 级掌握指针与函数的关系。 Q熟悉指针的运算,了解指向void类型的 指针
第九章:指针 重点及要求: 掌握指针的概念、定义、指针变量的引 用,掌握地址与指针的关系,掌握指针 与数组的关系。 掌握指针与函数的关系。 熟悉指针的运算,了解指向void类型的 指针
指针概述(1) 、指针概述: 1、地址的概念与取地址运算: 内存以字节编码,每个编码都是一个地址。我们原先学过的变 量、数组、函数等都放在内存中,至于它们放在内存的什么地方 这都是机器的事,我们只要知道它们是以怎样的顺序放在内存中 的,以便一一按顺序引用。我们怎样知道机器将某种数据放在内 存的什么地方呢?可用求地址运算符& 如:inta=3; &a就是变量在内存中的地址。 可以用 printf(“%xin”,&a);看出其地址。注意,这个地址并不 是始终不变的,这是由机器和操作系统来安排的,我们无法预先 知道
指针概述(1) 一、指针概述: 1、地址的概念与取地址运算: 内存以字节编码,每个编码都是一个地址。我们原先学过的变 量、数组、函数等都放在内存中,至于它们放在内存的什么地方, 这都是机器的事,我们只要知道它们是以怎样的顺序放在内存中 的,以便一一按顺序引用。我们怎样知道机器将某种数据放在内 存的什么地方呢?可用求地址运算符& 如:int a = 3 ; &a 就是变量在内存中的地址。 可以用printf(“%x \n” , &a); 看出其地址。注意,这个地址并不 是始终不变的,这是由机器和操作系统来安排的,我们无法预先 知道
指针变量(1) 则a表示的地址和&a[0的地址相同。 但&不能施加在常数、常量或表达式上,也不能施加在寄存器 变量上(因为寄存器变量在cpu中,不在内存中)。 指针变量 既然存储在内存中的各种变量都有一个地址,我们能否这样设 想:定义某种变量,让这个变量的值始终等于某个变量的地址, 如同某个房间号、门牌号一样?回答是肯定的。我们把这种存放 某种变量地址的变量称为指针变量。 201010 因此,在C语言中,将地2012|35 址形象化地称为指针 2010 2012q
指针变量(1) 则a表示的地址和&a [0]的地址相同。 但&不能施加在常数、常量或表达式上,也不能施加在寄存器 变量上(因为寄存器变量在cpu中,不在内存中)。 二、指针变量: 既然存储在内存中的各种变量都有一个地址,我们能否这样设 想:定义某种变量,让这个变量的值始终等于某个变量的地址, 如同某个房间号、门牌号一样?回答是肯定的。我们把这种存放 某种变量地址的变量称为指针变量。 10 35 …. a b 2010 2012 2010 p 2012 q 因此,在C语言中,将地 址形象化地称为指针
指针变量 说明(系统对变量的访问形式分为两种) 一个变量的访问(访问是指取出其值或向它赋值)方式 有两种: 1)直接访问,通过变量名访问,如通过变量名接访 2)间接访问,通过该变量的指针来访问,如通过指针 pi访问变量i
4 指针变量 说明(系统对变量的访问形式分为两种) 一个变量的访问(访问是指取出其值或向它赋值)方式 有两种: (1)直接访问,通过变量名访问,如通过变量名i直接访 问。 (2)间接访问,通过该变量的指针来访问,如通过指针 p访问变量i
指针变量 、定义指针变量: 「存储类型]激数据类型、*指针变量名1,指针变量 名2 如:int* 3 基类型,即该指针变 p,a=3; 量所指向的变量的类 int *9, b=5; 型 如何使一个指针变量指向另 201010 外一个变量呢? 201235 P=&a 2010 q=&b: 2012q
5 基类型,即该指针变 量所指向的变量的类 型 指针变量 三、定义指针变量: [存储类型 ] 数据类型 * 指针变量名1 ,* 指针变量 名2,… ; 如: int *p, a = 3; int *q, b=5; 如何使一个指针变量指向另 外一个变量呢? P=&a; q=&b; 10 35 …. a b 2010 2012 2010 p 2012 q
指针变量 为什么要为指针变量定义类型: 由于不同的数据有不同的数据类型,如char 仅占一个字节、int占两个字节、foat型占 个字节,而内存又是以字节为单位进行地址编 号,因而对char型,只要地址数加减1,取出 里面的数据就是char型的完整数据。对int型就 不同了,要取出其中的数据需2字节,就不能 对地址进行简单的加减1了。怎样取出一个完 整的in型数据或foat型数据呢?如果能够将指 针变量也定义为具有同样的数据类型,那么对 指针进行加1或减1运算,就是让指针移动相应 基类型对应的字节数
6 指针变量 • 为什么要为指针变量定义类型: 由于不同的数据有不同的数据类型,如 char 仅占一个字节、int 占两个字节、float型占三 个字节,而内存又是以字节为单位进行地址编 号,因而对char型,只要地址数加减1,取出 里面的数据就是char型的完整数据。对int型就 不同了,要取出其中的数据需2字节,就不能 对地址进行简单的加减1了。怎样取出一个完 整的int型数据或float型数据呢?如果能够将指 针变量也定义为具有同样的数据类型,那么对 指针进行加1或减1运算,就是让指针移动相应 基类型对应的字节数
指针变量() 2byte p 1234 3.14 byte P+1 P+2 P+1 P+3 2.12 二、指针变量赋值(这里要用到取地址运算符“&”) 指针变量的赋值:例、 pointer 1=&i; pointer 2=&i 注意,指针变量中只能存放地址,不能将一个非地址类型的数据(如常 数等)赋给一个指针变量,如: pointer1=100
指针变量(2) 二、指针变量赋值(这里要用到取地址运算符“&”) 指针变量的赋值:例、 pointer_1 = &i; pointer_2 = &j; 注意,指针变量中只能存放地址,不能将一个非地址类型的数据(如常 数等)赋给一个指针变量,如:pointer_1 = 100; 3.14 2.12 p P+1 4byte p P+1 P+2 P+3 1 2 3 4 2byte
也可以在定义指针变量的同时指定其初值,如、 Int a; int*p=&a 三、指针变量的引用 1、取地址运算:如:int卹p,i=3,j=5: p=&i;/让p其指向 变量i 2、对指针变量施加*运算,则代表取指针所指向的单元的内容。 这里,p与变量等价的。 区分:*运算符在不同场合的作用,编译器能够根据上下文环境判别的作用。 int a, b, c; int*p;(*表示定义指针) p=&a; p=100;(*表示指针运算符) c=a*b;(*表示乘法运算符)
8 也可以在定义指针变量的同时指定其初值,如、 int a; int *p = &a; 三、指针变量的引用 1、取地址运算:如:int *p , i=3, j=5; p=&i; /*让p其指向 变量i */ 2、对指针变量施加*运算,则代表取指针所指向的单元的内容。 这里,*p与变量i是等价的。 区分:*运算符在不同场合的作用,编译器能够根据上下文环境判别*的作用。 int a,b,c; int * p; (*表示定义指针) p = &a; *p = 100; (*表示指针运算符) c = a * b; (*表示乘法运算符)
指针变量(3) printf(“ odⅦn”,p); p=&i printf(%dn”,p) 但不能int char c=“A =&c;(类型不匹配) 区分运算符的以下用法: int a i intp=&a;/定义指针变量时指定初值,是为p指定初值* 卹p=100;/给指针p所指向的变量赋值,这里是给变量a赋值*
指针变量(3) printf(“%d \n” ,*p) ; p=&j; printf(“%d \n” ,*p) ; 但不能 int *p; char c=‘A’ ; p=&c ; (类型不匹配) 区分*运算符的以下用法: int a ; int *p = &a; /* 定义指针变量时指定初值,是为p指定初值*/ *p = 100; /* 给指针p所指向的变量赋值,这里是给变量a赋值*/
例I61c main() i int *pl, *p2, al, a2 scanf(“%d%d”,&al,&a2); pl=&al; p2=&a2; printf(“%d,%dmn”,*pl,p2); 2=p1 printf(“%d,%dmn”,*pl,*p2); 这里有一个运算符*,其作用是:加在指针变 量的前面,取出该指针变量所指对象的内容
10 例l6_1.c main( ) { int *p1, *p2, a1, a2; scanf(“%d %d” , &a1, &a2 ); p1 =&a1; p2=&a2; printf(“%d , %d \n” , *p1, *p2); p2 = p1; printf(“%d , %d \n” , *p1, *p2); } 这里有一个运算符*,其作用是:加在指针变 量的前面,取出该指针变量所指对象的内容