
8章第善于利用指针
8 善于利用指针 第 章

指针如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是地址”。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化地称为指针”。C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是带类型的地址”。变量名地址内容int i=1j=2.k=3;存储单元的地址和存储单元的内容是两个不同的概念。//设int变量占2字节20001在程序中一般是通过变量名来引用变量的值。20012002直接按变量名进行的访问,称为宜直接访问”方式。还可以采用另一种称为22003间接访问”的方式,即将变量的地址存放在另一变量(指针变量)中2004k3然后通过该指针变量来找到对应变量的地址,从而访问变量。2005
指 针 如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译 系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就 是“地址”。 由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化地称为 “指 针”。 C语言中的地址包括位置信息(内存编号,或称纯地址)和它所指向的数据的类型信息,或者说它是 “带类型的地址”。 存储单元的地址和存储单元的内容是两个不同的概念。 在程序中一般是通过变量名来引用变量的值。 直接按变量名进行的访问,称为“直接访问”方式。还可以采用另一种称为 “间接访问”的方式,即将变量的地址存放在另一变量(指针变量)中, 然后通过该指针变量来找到对应变量的地址,从而访问变量。 int i=1,j=2,k=3; //设int变量占2字节 变量名 地址 内容 i 2000 1 2001 j 2002 2 2003 k 2004 3 2005

指针变量
指针变量

使用指针变量的例子(例8.1】通过指针变量访问整型变量#includeint main()pointer1ainta=100,b=10;100&a*pointer1//定义整型变量ab,并初始化int *pointer_1,*pointer_2:bpointer_2//定义指向整型数据的指针变量pointer_1,pointer_210&b*pointer2//把变量a的地址赋给指针变量pointer_1pointer1=&a:pointer_2=&b://把变量b的地址赋给指针变量pointer2printf("a=%d.b=%d\n",a.b)://输出变量a和b的值注意定义指针变量时,左侧应有类型名,否则就printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2)不是定义指针变量。//输出变量a和b的值return 0;C:/WINDOWS)system32)cmd.exe口X//企图定义pointer_1为指针变量。出错*pointer_1;100,b=10Ppointer-1-100,*pointer_2=10请按任意键继续//正确,必须指定指针变量的基类型int*pointer_1
使用指针变量的例子 【例8.1】通过指针变量访问整型变量。 #include int main() { int a=100,b=10; //定义整型变量a,b,并初始化 int *pointer_1,*pointer_2; //定义指向整型数据的指针变量pointer_1, pointer_2 pointer_1=&a; //把变量a的地址赋给指针变量pointer_1 pointer_2=&b; //把变量b的地址赋给指针变量pointer_2 printf("a=%d,b=%d\n",a,b); //输出变量a和b的值 printf("*pointer_1=%d,*pointer_2=%d\n",*pointer_1,*pointer_2); //输出变量a和b的值 return 0; } pointer_1 a &a → 100 *pointer_1 pointer_2 b &b → 10 *pointer_2 注意 • 定义指针变量时,左侧应有类型名,否则就 不是定义指针变量。 *pointer_1; //企图定义pointer_1为指针变量。出错 int *pointer_1; //正确,必须指定指针变量的基类型

怎样定义指针变量类型名*指针变量名int*pointer1,*pointer_2左端的int是在定义指针变量时必须指定的基类型。指针变量的基类型用来指定此指针变量可以指向的变量的类型。前面介绍过基本的数据类型(如int,char,float等),既然有这些类型的变量,就可以有指向这些类型变量的指针,因此,指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。在定义指针变量时要注意:(1)指针变量前面的*”表示该变量为指针型变量。指针变量名则不包含“*”。2)在定义指针变量时必须指定基类型。一个变量的指针的含义包括两个方面,一是以存储单元编号表示的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int,char,float等)。(3)如何表示指针类型。指向整型数据的指针类型表示为f'nt*”,读作指向int的指针”或简称'nt指针”。(4)指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量
怎样定义指针变量 类型名 *指针变量名; int *pointer_1, *pointer_2; 左端的int是在定义指针变量时必须指定的 “基类型 ”。指针变量的基类型用来指定此指针变量可以指向 的变量的类型。 前面介绍过基本的数据类型(如int,char,float等),既然有这些类型的变量,就可以有指向这些类型变量 的指针,因此,指针变量是基本数据类型派生出来的类型,它不能离开基本类型而独立存在。 在定义指针变量时要注意: (1) 指针变量前面的“*”表示该变量为指针型变量。指针变量名则不包含“*”。 (2) 在定义指针变量时必须指定基类型。一个变量的指针的含义包括两个方面,一是以存储单元编号表示 的纯地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int,char,float等)。 (3) 如何表示指针类型。指向整型数据的指针类型表示为 “int * ” ,读作 “指向int的指针 ”或简称 “int 指针”。 (4) 指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量

怎样引用指针变量①给指针变量赋值。②引用指针变量指向的变量。③引用指针变量的值。inta,*p;QQQp=&a;//把a的地址赋给指针变量口1/以整数形式输出指针变量p所指向的变量的值,即a的值printf("%d"*p)*p=1;//将整数1赋给p当前所指向的变量,由于p指向变量a,相当于把1赋给a,即a=1③//以八进制形式输出指针变量p的值,由于p指向a,相当于输出a的地址,即&aprintf("%o",p);注意要熟练掌握两个有关的运算符:(1)&取地址运算符。&a是变量a的地址。(2)*指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象
怎样引用指针变量 ① 给指针变量赋值。 ② 引用指针变量指向的变量。 ③引用指针变量的值。 int a, *p; p=&a; //把a的地址赋给指针变量p ① printf("%d",*p); //以整数形式输出指针变量p所指向的变量的值,即a的值 ② *p=1; //将整数1赋给p当前所指向的变量,由于p指向变量a,相当于把1赋给a,即a=1 ② printf("%o",p); //以八进制形式输出指针变量p的值,由于p指向a,相当于输出a的地址,即&a ③ 注意 • 要熟练掌握两个有关的运算符: (1) &取地址运算符。&a是变量a的地址。 (2) * 指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象

怎样引用指针变量【例8.2】输入a和b两个整数,按先大后小的顺序输出a和b解题思路:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)#include交换前交换后intmainop1p1-aint *p1,*p2*p.a.b://p1.p2的类型是int*类型5&aprintf("please entertwo integer numbers:"):5&aDD1/输入两个整数scanf("%d,%d"&a&b)P2bp2bp1=&a;//使p1指向变量a&b9p2=&b:&b9//使p2指向变量bif(a<b)1/如果a<b1/使p1与p2的值互换(p=p1:p1=p2:p2=p)注意a和b的值并未交换,它们仍保持原值,但//输出a.bprintf("a=%d,b=%d\n",a,b):p1和p2的值改变了。printf(max=%d.min=%d\n"*p1.*p2)//输出p1和p2所指向的变量的值实际上,第9行可以改为(p1=&b:p2=&a即return;了直接对p1和p2赋以新值,这样可以不必定C:AWINDOWS)system32)cmd.exe+entertwointegernumbers:5,g义中间变量p,使程序更加简练
怎样引用指针变量 【例8.2】输入a和b两个整数,按先大后小的顺序输出a和b。 #include int main() { int *p1,*p2,*p,a,b; //p1,p2的类型是int *类型 printf("please enter two integer numbers:"); scanf("%d,%d",&a,&b); //输入两个整数 p1=&a; //使p1指向变量a p2=&b; //使p2指向变量b if(a<b) //如果a<b { p=p1;p1=p2;p2=p;} //使p1与p2的值互换 printf("a=%d,b=%d\n",a,b); //输出a,b printf("max=%d,min=%d\n",*p1,*p2); //输出p1和p2所指向的变量的值 return 0; } 注意 • a和b的值并未交换,它们仍保持原值,但 p1和p2的值改变了。 • 实际上,第9行可以改为{p1=&b; p2=&a;}即 直接对p1和p2赋以新值,这样可以不必定 义中间变量p,使程序更加简练。 解题思路:不交换整型变量的值,而是交换两个指针变量的值(即a和b的地址)。 p1 a &a → 5 p2 b &b → 9 p 交换前 交换后 p1 a &a 5 p2 b &b 9 p

指针变量作为函数参数口CAWINDOWS)system32/cmd.exeX【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出leaseenterand b:5,9,min现用函数处理,而且用指针类型的数据作函数参数请按任意键继续v#includeprintf("max=%d,min=%d\n",a,b)://输出结果int mainOretum 0;voidswap(int*p1,int*p2)://对swap函数的声明int a,b:int*pointer_1.*pointer_2://定义两个int*型的指针变量void swap(int*p1,int *p2)//定义swap函数printf(please entera and b:"):inttemp:1/输入两个整数//使*p1和*p2互换scanf("%d,%d",&a,&b):temp=*pl;//使pointer1指向a*p1=*p2;pointer1=&a;7pointer2=&b://使pointer2指向b*p2=temp;if(a<b)swap(pointer_1.pointer_2)://如果a<b,调用swap函数//本例交换a和b的值,而p1和p2的值不变。这恰和例8.2相反p1p1&a&aaaapointer_1apointer_159pointer_1pointer_155&a&a&a&abbpointer_2pointer_2p2p299&b&b→&bbb&b95pointer_2pointer_2&b&b
指针变量作为函数参数 【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出。 现用函数处理,而且用指针类型的数据作函数参数。 #include int main() { void swap(int *p1,int *p2); //对swap函数的声明 int a,b; int *pointer_1,*pointer_2; //定义两个int *型的指针变量 printf("please enter a and b:"); scanf("%d,%d",&a,&b); //输入两个整数 pointer_1=&a; //使pointer_1指向a pointer_2=&b; //使pointer_2指向b if(a<b) swap(pointer_1,pointer_2); //如果a<b,调用swap函数 printf("max=%d,min=%d\n",a,b); //输出结果 return 0; } void swap(int *p1,int *p2) //定义swap函数 { int temp; temp=*p1; //使*p1和*p2互换 *p1=*p2; *p2=temp; } //本例交换a和b的值,而p1和p2的值不变。这恰和例8.2相反 pointer_1 a &a → 5 pointer_2 b &b → 9 p1 &a a pointer_1 5 &a pointer_1 a &a → 5 pointer_2 b &b → 9 p1 &a a pointer_1 9 &a p2 &b b pointer_2 9 &b p2 &b b pointer_2 5 &b

指针变量作为函数参数【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函数处理,而且用指针类型的数据作函数参数void swap(intxint y)voidswap(int*p1.int*p2)//定义swap函数voidswap(int*p1.int*p2)inttemp;inttemp;int*temp:1temp=x:temp=*p1;//使*p1和+p2互换*temp=*p1x=y;*p1=*p2:*p1=*p2;y=temp;*p2=*temp:*p2=temp:7*p1就是a,是整型变量。而*temp在函数调用时,a的值传送给x,b是指针变量temp所指向的变量。的值传送给。执行完swap函数后但由于未给temp赋值,因此tempx和y的值是互换了,但并未影响到中并无确定的值(它的值是不可预a和b的值。在函数结束时,变量x和y释放了,main函数中的a和b并见的),所以temp所指向的单元也未互换。是不可预见的。所以,对+temp赋bbaa值就是向一个未知的存储单元赋值5959而这个未知的存储单元中可能存储→+着一个有用的数据,这样就有可能5995破坏系统的正常工作状况。xyxy
指针变量作为函数参数 【例8.3】题目要求同例8.2,即对输入的两个整数按大小顺序输出。现用函数处理,而且用指针类 型的数据作函数参数。 void swap(int *p1,int *p2) //定义swap函数 { int temp; temp=*p1; //使*p1和*p2互换 *p1=*p2; *p2=temp; } void swap(int *p1,int *p2) { int *temp; *temp=*p1; *p1=*p2; *p2=*temp; } *p1就是a,是整型变量。而*temp 是指针变量temp所指向的变量。 但由于未给temp赋值,因此temp 中并无确定的值(它的值是不可预 见的),所以temp所指向的单元也 是不可预见的。所以,对*temp赋 值就是向一个未知的存储单元赋值, 而这个未知的存储单元中可能存储 着一个有用的数据,这样就有可能 破坏系统的正常工作状况。 void swap(int x,int y) { int temp; temp=x; x=y; y=temp; } 在函数调用时,a的值传送给x,b 的值传送给。执行完swap函数后, x和y的值是互换了,但并未影响到 a和b的值。在函数结束时,变量x 和y释放了,main函数中的a和b并 未互换。 a b 5 9 ↓ ↓ 5 9 x y a b 5 9 9 5 x y

指针变量作为函数参数函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。要善于利用指针法。如果想通过函数调用得到n个要改变的值,可以这样做①在主调函数中设n个变量,用n个指针变量指向它们②设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值;③在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的值,也就是相关变量的地址传给该函数的形参;④在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值;5主调函数中就可以使用这些改变了值的变量
指针变量作为函数参数 函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到 多个变化了的值。如果不用指针变量是难以做到这一点的。要善于利用指针法。 如果想通过函数调用得到n个要改变的值,可以这样做: ① 在主调函数中设n个变量,用n个指针变量指向它们; ② 设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值; ③ 在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的值,也就是相关变量 的地址传给该函数的形参; ④ 在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值; ⑤ 主调函数中就可以使用这些改变了值的变量