第十章 指针
19
10.4 字符串与指针
字符串的表示形式
1. 可以用字符数组表示字符串
main() { char string[]=”I love China!”; printf(“%s\n”, string); }
2. 可用字符指针变量来表示
main() { char *string=”I love China!”; printf(“%s\n”, string); }
9
10.2.2 指针变量的引用
& :取地址运算符 * :指针运算符
i_pointer-----指针变量,它的内容是地址量 Eg10.1 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址 main() &*i_pointer等价于i_pointer { (&*i_pointer)++与&*i_pointer++的区别 int a,b; int *pointer_1,*pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1,*pointer_2); }
21
10.5 指向函数的指针
赋值 函数名代表该函数的入口地址。因此,可用 函数名给指向函数的指针变量赋值。 指向函数的指针变量=[&]函数名;
注意:函数名后不能带括号和参数;函数名前的 “&”符号是可选的。
调用格式 (*函数指针变量)([实参表])
22
用指向函数的指针作函数参数
eg24
23
10.6返回指针值的函数
10
指针应用举例
例:输入两个数按由大到小输出. #include <stdio.h> main() p1 { int *p1,*p2,*p,a,b; &a p scanf("%d,%d",&a,&b); p1=&a;p2=&b; p1=&a;p2=&b; p2 scanf("%d,%d",p1,p2); if(a<b) &b { p=p1;p1=p2;p2=p; } printf("\na= %d,b=%d\n\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); } a 8 b 10
第10章 指 针
C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值
1
10.1 地址和指针的概念
内存中每个字 节有一个编号
——地址
2000 2002 2004 3010
内存
0 …… 3 6 9 …… 2000 …
程序中: int i,j,k;
6
变量* i_pointer
指针变量 i_pointer
10.2.1 定义一个指针变量
基类型 *指针变量名;
7
10.2.1 定义一个指针变量
基类型 *指针变量名;
例如:
int i,j; int *pointer_1,*pointer_2 float *pointer_3; char *pointer_4;
变量i_pointer 2000
2005
2006
指针变量
例
*i_pointer=20;
-----间接访问
…...
或者 scanf(“%d”,i_pointer);
5
10.2 指针与指针变量
指针:变量的地址 指针变量:专门存放变量地址的变量
内存
0 2000 2002 2004 3010 …… 3 6 9 …… 2000 …
3
(1)直接访问──直接利用变量的地址进行存取 scanf(“%d”,&num)的执行过程是这样的: 用变量名num作为索引值,检索符号表 ,找到变量 num的起始地址3000; 然后将键盘输入的值(假设为3)送到内存单元3000 和3001中。 printf("num=%d\n",num)的执行过程,与scanf()很相似: 找到变量num的起始地址3000, 从3000和3001中取出其值,最后将它输出。 (2)间接访问──通过另一变量访问该变量的值
pointer_1=&i; pointer_2=&j;
*pointer_1 *pointer_2 i j
8
注意:
1) 在定义指针变量时,变量名前的*表示该变量的 类型为指针变量.指针变量的命名规则与基本 变量的命名规则相同.
2) 在定义指针变量时必须指定其基类型. 3) 指针变量只能存放与它定义时的基类型相同 的变量的地址.
编译或函数调用时 为其分配内存单元
变量是对程序中数
据 存储空间的抽象
2
变量地址──系统分配给变量的内存单元的起始地址 例如: main() { int num; scanf("%d",&num); printf("num=%d\n", num); }
C编译程序编译到该变量定义语句时,将变量num 登录到 “符号表”中。符号表的关键属性有两个: •一是“标识符名(id)” , •二是该标识符在内存空间中的“地址(addr)” 。 为描述方便,假设系统分配给变量num的2字节存储单元 为 3000 和3001,则起始地址3000就是变量num在内存中 的地址。 变量值的存取──通过变量在内存中的地址进行 系统执行scanf(“%d”,&num);和printf(“num=%d\n”, num); 时,存取变量num值的方式可以有两种:
20
10.5 指向函数的指针
用函数指针调用函数
一个函数在编译时,被分配了一个入口地址,这个 地址就称为该函数的指针。 可以用一个指针变量指向一个函数,然后通过该指 针变量调用此函数。
指向函数的指针变量 定义格式 函数类型 (*指针变量)( );
注意:“*指针变量”外的括号不能缺, 否则成了返回指针值的函数。
swap(int *p1,int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; }
12
10.3 数组与指针
指向数组元素的指针
和指向变量的指针一样
例 int array[10]; int *p; p=&array[0]; // p=array; 或 int *p=&array[0]; 或 int *p=array; 数组名是表示数组首地址的地址常量
11
10.2.3 指针变量作为函数参数
——地址传递
main() { int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a; pointer_2=&b; if (a<b) swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); } Eg10.3
13
10.3 数组与指针
输出数组中的全部元素(eg10.5)
下标法 数组名计算地址法 指针变量法
14
数组名计算数组元素地址法
main() { int a[10]; int i; for(i=0;i<10;i++) scanf("%d",&a[i]); printf("\n"); for(i=0;i<10;i++) printf("%d ",*(a+i)); }
10.3.4 多维数组与指针
多维数组的地址
int array[3][4]; 从2维数组角度看,数组名array代表数组的起始 地址, 是一个以行为单位进行控制的行指针:
array+i:行指针值,指向2维数组的第i行。 *(array+i):(列)指针值,指向第i行第0列(控 制由行转为列,但仍为指针)。 *(*(array+i)):数组元素array[i][0]的值。 用array作指针访问数组元素array[i][j]的格式: *(*(array+i)+j)
函数的返回值可以是整型、字符、实型值, 当然也可以是指针型的值 即返回的是某个内存数据的地址 函数定义 指针类型名 * 函数名(参数列表) eg25
24
25
15
指针变量指向数组元素法
main() { int a[10]; int *p,i; for(i=0;i<10;i++) scanf("%d",&a[i]); printf("\n"); for(p=a;p<(a+10);p++) printf("%d ",*p); }
16
指针变量的运算
如果p指向数组a的首元素(p=a):
C语言规定:在程序中可以定义一种特殊的变量(称为指针变 量),用来存放其它变量的地址。
4
直接访问与间接访问
直接访问:按变量地址存取变量值 间接访问:通过存放变量地址的变量去访问变量
…...
例
整型变量i
i=3;
-----直接访问
2000 2001 2002 2003 2004 3 20 10
或者Scanf(“%d”,&i);
P++ *p++ *(p++)和*(++P)的区别 (*p)++