《C语言入门到精通7教程》由会员分享,可在线阅读,更多相关《C语言入门到精通7教程(77页珍藏版)》请在金锄头文库上搜索。
1、第8章 指 针,8.1 指针的基本概念 8.2 指针与一维数组 8.3 指针与二维数组 8.4 指针与字符串 8.5 指 针 数 组 8.6 多 级 指 针 8.7 指针与函数 小结,C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值,8.1 指针的基本概念,程序中: short i; float k;,内存中每个字节有一个编号-地址,i,k,编译或函数调用时为其分配内存单元,变量是对程序中数据 存储空间的抽象,8.1.1 存储单元、内存地址及指针,指针就是存储单元的地址。 一个变量的指针就是该变量在内存中的存储单元的地址。 存
2、取变量中的数据 直接引用: 按变量名称存取变量值的方式。 间接引用: 将某变量 a 的指针(地址)放在另一个变量pa中, 通过对变量pa的值(a变量的地址),由此地址存取变量 a的方式。,例如l8-1d1: #include void main() int x,*px; float y; x=10; y=23.5; px= ,8.1.2 指针变量 指针:一个变量的地址 指针变量:专门存放变量地址的变量,2000,指针,指针变量,变量的内容,变量的地址,变量的指针和指向变量的指针变量,变量的指针:就是变量的在内存中的存储单元的地址。 指针变量: 存放(指向某个变量的)地址的变量。,用运算符*表示
3、指针变量所指向的对象。 如:指针变量 pa 指向变量 a 。 用 *pa 表示 pa 的对象,即变量a 。( *pa 与 a 为同一个变量) 下例两语 句作用相同 a=345; *pa=345;,指针部分,指针:就是变量的地址。 指针变量:是可存放指针的变量。 指针类型:由变量的类型决定。,例: 指针变量 pa 指向变量 a,即表明变量pa中存放着变量a 的地址。 pa= *pa与a等价,一般形式: 数据类型 *指针名;,合法标识符,指针的目标变量的数据类型,表示定义指针变量 不是*运算符,例 int *p1,*p2; float *q ; static char *name;,注意: 1、i
4、nt *p1, *p2; 与 int *p1, p2;不同,每一个指针变量前有* 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 int *p,a; char c; float x; p只能指向a,不能指向c或x。 4、指针变量定义后,变量值不确定即指向不确定,称为悬挂指针,不能间接引用悬挂指针。应用前必须先赋值 5、指针变量只能存放地址,不能存放非地址类型数据。 如语句 int *p; p=1000; 不合法; (内存空间的实际分配由操作系统负责)。,指针变量的定义与初始化 指针变量的定义,指针变量的初始化 一般形式:数据类型 *指针名=初始地址
5、值;,赋给指针变量, 不是赋给目标变量,例 int i; int *p=,变量必须已定义过 类型应一致,例 int i; int *p=,用已初始化指针变量作初值,例 main( ) int i; static int *p= . (),不能用auto变量的地址 去初始化static型指针,指针变量的引用 -直接访问,3,例 *i_pointer=20; -间接访问,20,例 k=i; -直接访问 k=*i_pointer; -间接访问,10,例 k=i; k=*i_pointer;,例8.1 取地址运算符 ,程序运行: a=100,*pa=100 a=200,*pa=200 a=300,*p
6、a=300,2000,200,300,例8.2 使两个指针变量交换指向。 #include void main() int a=10,b=20; int *p1= ,程序运行: a=10,b=20,*p1=10,*p2=20 a=10,b=20,*p1=20,*p2=10,1001,1012,例l8-2d1 使两指针变量所指对象的值交换 main() int *p1, *p2, a, b, t; a=10; b=20; p1= ,运行结果: a=20,b=10,20,10,10,例 main( ) int i=10; int *p; *p=i; printf(“%d”,*p); ,危险!,例
7、main( ) int i=10,k; int *p; p= ,注意:指针变量必须先赋值,再使用,零指针与空类型指针 零指针:(空指针) 定义:指针变量值为零 表示: int * p=0;,p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义,#define NULL 0 int *p=NULL:,p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较,例 int *p; . while(p!=NULL) . ,void *类型指针 表示: void *p; 使用时要进行强制类型转换,例 char *p1; void *p2; p1=(char
8、*)p2; p2=(void *)p1;,表示不指定p是指向哪一种 类型数据的指针变量,8.1.3 指针的运算 指针变量的赋值运算 int a,array10,i=2,*p1,*p2; p1= (指针变量p2值p1) 不能把一个整数p,也不能把p的值整型变量,如 int i, *p; p=1000; () i=p; (),指针变量与其指向的变量具有相同数据类型,指针的算术运算: pi p id (i为整型数,d为p指向的变量所占字节数) p+, p-, p+i, p-i, p+=i, p-=i等 若p1与p2指向同一数组,p1-p2=两指针间元素个数(p1-p2)/d p1+p2 无意义,例
9、p指向float数,则 p+1 p+1 4,例 p指向int型数组,且p= 则p+1 指向a1,例 int a10; int *p=,例 int a10; int *p1=,1,指针变量的关系运算 若p1和p2指向同一数组,则 p1p2 表示p1指的元素在后 p1=p2 表示p1与p2指向同一元素 若p1与p2不指向同一数组,比较无意义 p=NULL或p!=NULL,间接访问主调函数中的变量地址传递 特点:共享内存,“双向”传递,swap(int x,int y) int temp; temp=x; x=y; y=temp; main() int a,b; scanf(%d,%d, ,例 将两
10、数从大到小输出,5,9,5,5,9,COPY,8.1.4 指针作为函数的参数,swap(int x,int y) int temp; temp=x; x=y; y=temp; main() int a,b; scanf(%d,%d, ,例l8-3d1 将两数从大到小输出,值传递,5,9,运行结果:5, 9,swap1(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,5,9,2000,2002,5,9,COPY,5,例8.3 编写函数s
11、wap1,交换两个变量的值。,swap1(int *p1, int *p2) int p; p=*p1; *p1=*p2; *p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,5,9,2000,2002,5,9,例8-3 编写函数swap1,交换两个变量的值。,运行结果:9,5,地址传递,swap2(int *p1, int *p2) int *p; *p=*p1; *p1=*p2; *p2=*p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,编译警
12、告! 结果不对!,int x; int *p=,例l8-3d2 编写函数swap2,交换两个变量的值。,5,9,2000,2002,COPY,指针变量在使用前 必须赋值!,swap2(int *p1, int *p2) int *p; p=p1; p1=p2; p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,例l8-3d3 编写函数swap3,交换两个变量的值。,5,9,2000,2002,COPY,2000,2002,2000,swap2(int *p1, int *p2) int *p; p=p1; p1=p2;
13、 p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf(%d,%d, ,例l8-3d3 编写函数swap3,交换两个变量的值。,5,9,2000,2002,只交换了形参指针 变量值!,例8.4 编制函数,求一元二次方程ax2+bx+c=0的根(a0)的两个实根。 #include #include int root(float a,float b,float c,float *x1,float *x2) float d; d=b*b-4*a*c; if(d=0) *x1=(-b+sqrt(d)/2/a; *x2=(-b-sqrt(d)/2
14、/a; return 1; else return 0; void main() float a,b,c,x1,x2; int flag; scanf(%f %f %f, ,程序设计分析:因函数计算后有两个实根要返回给主调函数,所以用指针作为函数的参数。,程序运行: 1 -5 3 x1=4.30 x2=0.70,传地址的两个特点: 实参可以是常量、变量或表达式,其实参值是指针数据类型。 在被调函数中,可以通过地址间接访问主调函数中的变量,而达到改变主调函数中的变量值。,例l8-20d4,#include”stdio.h” int x,y,z; void p(int *x,int y) +*x;
15、 y-; z=*x+y; printf(“A:%d,%d,%dn”,*x,y,z); void main( ) x=2; y=3; z=4; p( ,A: 3,2,5 B: 3,3,5 A: 4,2,6 C: 3,4,6,结果,3,2,4,5,6,2,8.2.1 一维数组元素表示, 变址运算符 ai *(a+i),8.2 指针与一维数组,指针法,例8.5 查看数组元素的地址及数组元素的值。 #include void main() short i,x5=1,-6,5,7,2; for(i=0; i5; i+) printf(%x,%dn,x+i,*(x+i); printf(n); ,程序运行: 19ba, 1 19bc, 6 19be, 5 19c0, 7 19c2, 2,用指针变量引用一维数组元素,ai pi *(p+i) *(a+i),指针变量类型应与数组元