第七章 指针 计算机公共教学部
教学目的与要求 掌握指针的概念,指针变量的定义与引用;认识指针的作用和意义;弄清指针与数组的关系;理解使用指针指向数组在程序设计所带来的方便;了解指向函数的指针、返回指针值的函数、多级指针。
教学重点与难点 指针与地址的基本概念,指针与变量的关系,指针与数组,指针与字符串,指针的应用。
7.1 地址和指针的概念 什么是指针 i k 变量与地址 程序中: int i; float k; 变量是对程序中数据 存储空间的抽象 7.1 地址和指针的概念 什么是指针 变量与地址 内存中每个字节有一个编号-----地址 …... 2000 2001 2002 2005 内存 2003 程序中: int i; float k; i 编译或函数调用时为其分配内存单元 k 变量是对程序中数据 存储空间的抽象
指针与指针变量 指针:一个变量的地址 指针变量:专门存放变量地址的变量叫指针变量 10 变量的内容 变量的地址 指针变量 变量地址(指针) …... 2000 2004 2006 2005 整型变量i 10 变量i_pointer 2001 2002 2003 指针 变量的地址 变量的内容 2000 指针变量 指针变量 变量 变量地址(指针) 变量值 指向 地址存入
&与*运算符 含义 10 i_pointer = &i = &(*i_pointer) i_pointer &i &(*i_pointer) 含义: 取变量的地址 单目运算符 优先级: 2 结合性:自右向左 含义: 取指针所指向变量的内容 单目运算符 优先级: 2 结合性:自右向左 两者关系:互为逆运算 理解 2000 10 i_pointer *i_pointer i …... 2000 2004 2006 2005 整型变量i 10 变量i_pointer 2001 2002 2003 指针变量 i_pointer = &i = &(*i_pointer) i = *i_pointer = *(&i) i_pointer &i &(*i_pointer) i *i_pointer *(&i) i_pointer-----指针变量,它的内容是地址量 *i_pointer----指针的目标变量,它的内容是数据 &i_pointer---指针变量占用内存的地址
间接访问:通过存放变量地址的变量去访问变量 直接访问与间接访问 直接访问:按变量地址存取变量值 间接访问:通过存放变量地址的变量去访问变量 指针变量 …... 2000 2004 2006 2005 整型变量i 10 变量i_pointer 2001 2002 2003 例 i=3; -----直接访问 20 3 例 *i_pointer=20; -----间接访问
10 例 k=i; k=*i_pointer; 例 k=i; --直接访问 k=*i_pointer; --间接访问 10 …... 指针变量 …... 2000 2004 2006 2005 整型变量i 10 变量i_pointer 2001 2002 2003 整型变量k 10
7.2指针变量的类型说明 指针变量的定义 存储类型 类型 *指针变量; int *p1;/* 定义一个名为p1的整型类型的指针变量 */ Static int *p2; /* 定义一个名为p2的字符类型的指针变量 */
表示定义指针变量 不是‘*’运算符 合法标识符 指针的目标变量的数据类型 指针变量与其所指向的变量之间的关系 3 变量i 2000 i_pointer *i_pointer i &i i=3; *i_pointer=3 3 变量i 2000 i_pointer *i_pointer i &i i=3; *i_pointer=3 指针变量的定义 一般形式:[存储类型] 数据类型 *指针名; 例 int *p1,*p2; float *q ; static char *name; 表示定义指针变量 不是‘*’运算符 指针变量本身的存储类型 合法标识符 指针的目标变量的数据类型 注意: 1、int *p1, *p2; 与 int p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值
指针变量的初始化 一般形式:[存储类型] 数据类型 *指针名=初始地址值; 例 int i; int *p=&i; 赋给指针变量, 不是赋给目标变量 变量必须已说明过 类型应一致 例 int i; int *p=&i; int *q=p; 例 int *p=&i; int i; 用已初始化指针变量作初值 例 main( ) { int i; static int *p=&i; .............. } () 不能用auto变量的地址 去初始化static型指针
p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义 零指针与空类型指针 零指针: 定义:指针变量值为零 表示: int * p=0; p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义 #define NULL 0 int *p=NULL: 例 int *p; ...... while(p!=NULL) { ...… } 例 char *p1; void *p2; p1=(char *)p2; p2=(void *)p1; p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较 表示不指定p是指向哪一种 类型数据的指针变量 void *类型指针 表示: void *p; 使用时要进行强制类型转换
7.3 指针变量的引用 5,10 #include “stdio.h“ main() { int a=5,b,c,*p; p=&a; 7.3 指针变量的引用 #include “stdio.h“ main() { int a=5,b,c,*p; p=&a; b=*p; c=a+*p; printf(“%d,%d”,b,c); } 5,10
指针变量常见使用方法 (1)给指针变量赋值 一般形式:指针变量=表达式; int i,*p; p=&i; (2)直接引用指针变量名 int i,j,*p=&i,*q; q=p; (3)通过一般指针变量来引用它所指向的变量 一般形式:*指针变量名 int i=1,j=2,k,*p=&i; k=*p+j;
7.4 指针作为函数参数 指针作为函数参数是地址传递,可以改变实参的值。 void swap(int *x,int *y) { int t;t=*x;*x=*y;*y=t; } main() int a=3,b=5; swap(&a,&b); printf("a=%d,b=%d\n“,a,b);
7.5 数组与指针 p array[0] 指向数组元素的指针变量 array[1] 例 int array[10]; int *p; ... 整型指针p &array[0] p 指向数组元素的指针变量 例 int array[10]; int *p; p=&array[0]; // p=array; 或 int *p=&array[0]; 或 int *p=array; 数组名是表示数组首地址的地址常量
如 int i, *p; p=1000; () i=p; () 指针的运算 指针变量的赋值运算 p=&a; (将变量a地址p) p=array; (将数组array首地址p) p=&array[i]; (将数组元素地址p) p1=p2; (指针变量p2值p1) 不能把一个整数p,也不能把p的值整型变量 指针变量与其指向的变量具有相同数据类型
pi p id (i为整型数,d为p指向的变量所占字节数) p++, p- -, p+i, p-i, p+=i, p-=i等 指针的算术运算: 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 无意义 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] a数组 p p+1,a+1 p+i,a+i p+9,a+9 例 p指向float数,则 p+1 p+1 4 例 p指向int型数组,且p=&a[0]; 则p+1 指向a[1] 1 例 int a[10]; int *p=&a[2]; p++; *p=1; 例 int a[10]; int *p1=&a[2]; int *p2=&a[5]; 则:p2-p1=3;
指针变量的关系运算 若p1和p2指向同一数组,则 p1<p2 表示p1指的元素在前 p1>p2 表示p1指的元素在后 p1==p2 表示p1与p2指向同一元素 若p1与p2不指向同一数组,比较无意义
a[i] p[i] *(p+i) *(a+i) a[i] *(a+i) 通过指针引用数组元素 a[0] a[1] a[2] a[3] a[9] ... a a+9 a+1 a+2 地址 元素 下标法 a[0] a[1] a[2] a[3] a[9] ... p p+9 p+1 p+2 地址 元素 指针法 *p *(p+1) *(p+2) *(p+9) *a *(a+1) *(a+2) *(a+9) p[0] p[1] p[2] p[9] a[i] p[i] *(p+i) *(a+i)
例 数组元素的引用方法 p142 例7.4 main() { int a[5],i,*pa,*qa; pa=qa=a; for(i=0;i<5;i++){ *qa=i+1; qa++; } for(i=0;pa<qa;i++){ printf("a[%d]=%d ",i,*pa); pa++; a[0] a[1] a[2] a[3] a[4] pa 1 2 3 4 5
7.6 数组名和数组指针变量作为函数参数 一级指针变量与一维数组的关系 int *p 与 int q[10] 数组名q是指针(地址)常量 p=q; p+i 是q[i]的地址 数组元素的表示方法:下标法和指针法, 即若p=q, 则p[i] q[i] *(p+i) *(q+i) 形参数组实质上是指针变量,即int q[ ] int *q 在定义指针变量(不是形参)时,不能把int *p 写成int p[]; 系统只给p分配能保存一个指针值的内存区(一般2字节);而给q分配2*n字节的内存区
printf("\ninput 5 score:\n"); for(i=0;i<5;i++) scanf("%f",&sco[i]); 7.6用数组名作函数参数 例7.5 用数组名和数组指针变量作函数参数,求输入一个学生5门成绩至数组a,求平均成绩。 (p142) #include "stdio.h" float aver(float *pa) { int i; float s=0; for(i=0;i<5;i++) s=s+*pa++; s/=5; return s; } main() { float sco[5],av,*sp; int i; sp=sco; printf("\ninput 5 score:\n"); for(i=0;i<5;i++) scanf("%f",&sco[i]); av=aver(sp); printf("average score is %5.2f\n",av); }
7.7 指向多维数组的指针变量 int a[3][4];
int a[3][4]; a a+1 a+2 行指针与列指针 *(a[0]+1) *(*(a+0)+1) 2000 2000 a[0] 2008 2016 a a+1 a+2 2000 2002 2008 2010 2016 2018 a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] a[0][2] a[0][3] a[1][2] a[1][3] a[2][2] a[2][3] a[0]+1 a[1]+1 a[2]+1 *(a+0)+1 *(a+1)+1 *(a+2)+1 对于二维数组: (1)a是数组名, 包含三个元素 a[0],a[1],a[2] (2)每个元素a[i] 又是一个一维数组, 包含4个元素 基类型
int a[3][4]; a a+1 a+i=&a[i]=a[i]=*(a+i) =&a[i][0], 值相等,含义不同 2000 2008 2016 2002 2010 2018 a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] a[0][2] a[0][3] a[1][2] a[1][3] a[2][2] a[2][3] a a+1 a+2 对二维数组 int a[3][4],有 a-----二维数组的首地址,即第0行的首地址 a+i-----第i行的首地址 a[i] *(a+i)------第i行第0列的元素地址 a[i]+j *(a+i)+j -----第i行第j列的元素地址 *(a[i]+j) *(*(a+i)+j) a[i][j] a+i=&a[i]=a[i]=*(a+i) =&a[i][0], 值相等,含义不同 a+i &a[i],表示第i行首地址,指向行 a[i] *(a+i) &a[i][0],表示第i行第0列元素地址,指向列
int a[3][4]; 地址表示: (1) a+1 (2) &a[1][0] (3) a[1] (4) *(a+1) 行指针 列指针 地址表示: (1) &a[1][2] (2) a[1]+2 (3) *(a+1)+2 (4)&a[0][0]+1*4+2 二维数组元素表示形式: (1)a[1][2] (2)*(a[1]+2) (3)*(*(a+1)+2) (4)*(&a[0][0]+1*4+2)
*(a[1]+2),*(*(a+1)+2),a[1][2] 表示形式 含义 地址 a 二维数组名,数组首地址 a[0],*(a+0),*a 第0行第0列元素地址 a+1 第1行首地址 a[1],*(a+1) 第1行第0列元素地址 a[1]+2,*(a+1)+2,&a[1][2] 第1行第2列元素地址 *(a[1]+2),*(*(a+1)+2),a[1][2] 第1行第2列元素值 2000 2008 2012 13
一维数组指针变量维数和 二维数组列数必须相同 指向一维数组的指针变量 定义形式: 数据类型 (*指针名)[一维数组维数]; 例 int (*p)[4]; int a[3][4]; a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] a[0][2] a[0][3] a[1][2] a[1][3] a[2][2] a[2][3] a a+1 a+2 p p+1 p+2 p[0]+1或 *p+1 p[1]+2或 *(p+1)+2 p的值是一维数组的 首地址,p是行指针 ( )不能少 int (*p)[4]与int *p[4]不同 可让p指向二维数组某一行 如 int a[3][4], (*p)[4]=a; *(*p+1)或 (*p)[1] *(*(p+1)+2) 一维数组指针变量维数和 二维数组列数必须相同
p p p 例 一维数组指针变量举例 main() 例 一维数组指针变量举例 int a[3][4]; a[0][0] a[0][1] a[1][0] a[1][1] a[2][0] a[2][1] a[0][2] a[0][3] a[1][2] a[1][3] a[2][2] a[2][3] p main() { static int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23}; int i,j,(*p)[4]; for(p=a,i=0;i<3;i++,p++) for(j=0;j<4;j++) printf("%d ",*(*p+j)); printf("\n"); } p p[0][j] p p=a[0]; p=*a; p=&a[0][0]; p=&a[0]; p=a[0]; p=*a; p=&a[0][0]; p=&a[0];
二维数组与一维数组指针变量的关系 如 int a[5][10] 与 int (*p)[10]; 二维数组名a是一个指向有10个元素的一维数组的指针常量 p=a+i 使 p指向二维数组的第i行 *(*(p+i)+j) a[i][j] 系统只给p分配能保存一个指针值的内存区(一般2字节);而给a分配2*5*10字节的内存区
7.8 字符串与指针 字符串表示形式 用字符数组实现 例 main( ) { char string[]=“I love China!”; \0 例 main( ) { char string[]=“I love China!”; printf(“%s\n”,string); printf(“%s\n”,string+7); }
{ char *string=“I love China!”; printf(“%s\n”,string); string+=7; 用字符指针实现 I l o v e C h i string n ! a \0 字符指针初始化:把字符串首地址赋给string char *string; string=“I love China!”; 例 main( ) { char *string=“I love China!”; printf(“%s\n”,string); string+=7; while(*string) { putchar(string[0]); string++; } string *string!=‘\0’
字符串指针作函数参数 例 用函数调用实现字符串复制 (1)用字符数组名作参数 (2)用指向字符指针变量作参数 b y u a r s t n d e to o . \0 a I m t e c h \0 r . from I a e c h \0 r . t m 例 用函数调用实现字符串复制 (1)用字符数组名作参数 (2)用指向字符指针变量作参数
void copy_string(char from[],char to[]) { int i=0; 字符串指针作函数参数 a I m t e c h \0 r . from b y u a r s t n d e to o . \0 I a e c h \0 r . t m void copy_string(char from[],char to[]) { int i=0; while(from[i]!='\0') { to[i]=from[i]; i++; } to[i]='\0'; main() { char a[]="I am a teacher."; char b[]="You are a student."; printf("string_a=%s\n string_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); 例 用函数调用实现字符串复制 void copy_string(char *from,char *to) { for(;*from!='\0';from++,to++) *to=*from; *to='\0'; } main() { char *a="I am a teacher."; char *b="You are a student."; printf("string_a=%s\nstring_b=%s\n",a,b); copy_string(a,b); printf("\nstring_a=%s\nstring_b=%s\n",a,b); (1)用字符数组名作参数 (2)用字符指针变量作参数
7.9字符指针变量与字符数组 char *cp; 与 char str[20]; str由若干元素组成,每个元素放一个字符;而cp中存放字符串首地址 char str[20]; str=“I love China!”; () char *cp; cp=“I love China!”; () str是地址常量;cp是地址变量 cp接受键入字符串时,必须先开辟存储空间 例 char str[10]; scanf(“%s”,str); () 而 char *cp; scanf(“%s”, cp); () 改为: char *cp,str[10]; cp=str; scanf(“%s”,cp); ()
字符串与数组关系 字符串用一维字符数组存放 字符数组具有一维数组的所有特点 数组名是指向数组首地址的地址常量 数组元素的引用方法可用指针法和下标法 数组名作函数参数是地址传递等 区别 存储格式:字符串结束标志 赋值方式与初始化 输入输出方式:%s %c scanf(“%s”,str); printf(“%s”,str); gets(str); puts(str); char str[]={“Hello!”}; () char str[]=“Hello!”; () char str[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘!’}; () char *cp=“Hello”; () int a[]={1,2,3,4,5}; () int *p={1,2,3,4,5}; () char str[10],*cp; int a[10],*p; str=“Hello”; () cp=“Hello!”; () a={1,2,3,4,5}; () p={1,2,3,4,5}; ()
7.10 函数指针变量 函数指针:函数在编译时被分配的入口地址,用函数名表示 ( )不能省 专门存放函数入口地址 max …... 指令1 指令2 指向函数的指针变量 定义形式: 数据类型 (*指针变量名)(); 如 int (*p)(); 函数指针变量赋值:如p=max; ( )不能省 int (*p)() 与 int *p()不同 专门存放函数入口地址 可指向返回值类型相同的不同函数 函数返回值的数据类型 函数调用形式: c=max(a,b); c=(*p)(a,b); 对函数指针变量pn, p++, p--无意义 函数指针变量指向的函数必须有函数说明
例 用函数指针变量调用函数,比较两个数大小 main() { int maxnum(int ,int), (*p)(); int a,b,c; p=max; scanf("%d,%d",&a,&b); c=(*p)(a,b); printf("a=%d,b=%d,max=%d\n",a,b,c); } int maxnum(int x,int y) { int z; if(x>y) z=x; else z=y; return(z); main() { int max(int ,int); int a,b,c; scanf("%d,%d",&a,&b); c=max(a,b); printf("a=%d,b=%d,max=%d\n",a,b,c); } int max(int x,int y) { int z; if(x>y) z=x; else z=y; return(z);
7.11 指针型函数 main() { float score[][4]={{60,70,80,90}, {56,89,67,88},{34,78,90,66}}; float *search(float (*pointer)[4],int n), *p; int i,m; printf("Enter the number of student:"); scanf("%d",&m); printf("The scores of No.%d are:\n",m); p=search(score,m); for(i=0;i<4;i++) printf("%7.2f\t",*(p+i));} float *search(float (*pointer)[4], int n) { float *pt; pt=*(pointer+n); return(pt); } 7.11 指针型函数 函数定义形式: 类型标识符 *函数名(参数表); 例 int *f(int x, int y) 例 指针函数实现:有若干学生成绩,要求输入学生序号后, 能输出其全部成绩 p p p p pointer pointer+1 34 78 90 66 56 89 67 88 60 70 80 score数组
7.12 指针数组和指向指针的指针 用于处理二维数组或多个字符串 指针数组 定义:数组中的元素为指针变量 7.12 指针数组和指向指针的指针 用于处理二维数组或多个字符串 指针数组 定义:数组中的元素为指针变量 定义形式:[存储类型] 数据类型 *数组名[数组长度说明]; 例 int *p[4]; 指针数组赋值与初始化 指针本身的存储类型 指针所指向变量的数据类型 赋值: main() { int b[2][3],*pb[2]; pb[0]=b[0]; pb[1]=b[1]; …….. } int *pb[2] pb[0] pb[1] int b[2][3] 1 2 3 4 6 区分int *p[4]与int (*p)[4] 初始化: main() { int b[2][3],*pb[ ]={b[0],b[1]}; …….. } int *pb[2] pb[0] pb[1] int b[2][3] 1 2 3 4 6
p[0]=a; p[1]=b; p[2]=c; p[3]=NULL; …….. } 或: { char *p[4]; 指针数组赋值与初始化 L i s p \0 F o r t r a n \0 B a s i c \0 p[0] p[1] p[2] p[3] 赋值: main() { char a[]="Fortran"; char b[]="Lisp"; char c[]="Basic"; char *p[4]; p[0]=a; p[1]=b; p[2]=c; p[3]=NULL; …….. } 或: { char *p[4]; p[0]= "Fortran"; p[1]= "Lisp"; p[2]= "Basic"; p[3]=NULL; 初始化: main() { char *p[]={"Fortran", "Lisp", "Basic",NULL}; …….. } L i s p \0 F o r t r a n \0 B a s i c \0 p[0] p[1] p[2] p[3]
二维数组与指针数组区别: 指针数组元素的作用相当于二维数组的行名 但指针数组中元素是指针变量 二维数组存储空间固定 二维数组的行名是地址常量 char name[5][9]={“gain”,“much”,“stronger”, “point”,“bye”}; g a i n \0 s t r o n g e r \0 p o i n t \0 m u c h \0 b y e \0 g a i n \0 s t r o n g e r \0 p o i n t \0 m u c h \0 name[0] name[1] name[2] name[3] name[4] b y e \0 char *name[5]={“gain”,“much”,“stronger”, “point”,“bye”}; 指针数组元素的作用相当于二维数组的行名 但指针数组中元素是指针变量 二维数组的行名是地址常量 二维数组存储空间固定 字符指针数组相当于可变列长的二维数组
一级指针 单级间接寻址 二级指针 一级指针 目标变量 二级间接寻址 多级指针 定义: 指向指针的指针 一级指针:指针变量中存放目标变量的地址 例 int *p; int i=3; p=&i; *p=5; &i 3 P(指针变量) i(整型变量) 一级指针 单级间接寻址 二级指针:指针变量中存放一级指针变量的地址 例 int **p1; int *p2; int i=3; p2=&i; p1=&p2; **p1=5; p1 &p2 &i 3 P2(指针变量) i(整型变量) 二级指针 一级指针 目标变量 二级间接寻址
定义形式:[存储类型] 数据类型 **指针名; 如 char **p; *p是p间接指向对象的地址 **p是p间接指向对象的值 最终目标变量的数据类型 指针本身的存储类型 i p1 p2 3 &i &p1 例 int i=3; int *p1; int **p2; p1=&i; p2=&p1; **p=5; **p2, *p1 *p2 例 int i, **p; p=&i; ()//p是二级指针,不能用变量地址为其赋值 多级指针 例 三级指针 int ***p; 四级指针 char ****p;
#include <stdio.h> void swap(int *r,int *s) { int *t; t=r; r=s; b p q 例 一级指针与二级指针 #include <stdio.h> void swap(int *r,int *s) { int *t; t=r; r=s; s=t; } main() { int a=1,b=2,*p,*q; p=&a; q=&b; swap(p,q); printf("%d,%d\n",*p,*q); a b p q r s a b p q s r a b p q 输出: 1,2
#include <stdio.h> void swap(int **r,int **s) { int *t; t=*r; 例 一级指针与二级指针 a b p q #include <stdio.h> void swap(int **r,int **s) { int *t; t=*r; *r=*s; *s=t; } main() { int a=1,b=2,*p,*q; p=&a; q=&b; swap(&p,&q); printf("%d,%d\n",*p,*q); a b r s p q a b r s p q b a p q 输出: 2,1
char *name[]={"hello","good","world","bye",""}; p=name+1; 例 用二级指针处理字符串 用*p可输出地址(%o或%x), 也可用它输出字符串(%s) #define NULL 0 void main() { char **p; char *name[]={"hello","good","world","bye",""}; p=name+1; printf("%o : %s ", *p,*p); p+=2; while(**p!=NULL) printf("%s\n",*p++); } name[0] name[1] name[2] name[3] name[4] char *name[5] world bye \0 hello good name p *(p++) p 运行结果: 644 : good bye
二级指针与指针数组的关系 int **p 与 int *q[10] 指针数组名是二级指针常量 p=q; p+i 是q[i]的地址 指针数组作形参,int *q[ ]与int **p完全等价;但作为变量定义两者不同 系统只给p分配能保存一个指针值的内存区;而给q分配10块内存区,每块可保存一个指针值
指针的数据类型 定义 含义 int i; 定义整型变量i p为指向整型数据的指针变量 int *p; int a[n]; 定义含n个元素的整型数组a int *p[n]; n个指向整型数据的指针变量组成的指针数组p int (*p)[n]; p为指向含n个元素的一维整型数组的指针变量 int f(); f为返回整型数的函数 int *p(); p为返回指针的函数,该指针指向一个整型数据 int (*p)(); p为指向函数的指针变量,该函数返回整型数 int **p; p为指针变量,它指向一个指向整型数据的指针变量
例 下列定义的含义 (1)int *p[3]; (2)int (*p)[3]; (3)int *p(int); (4)int (*p)(int); (5)int *(*p)(int); 指针数组 指向一维数组的指针 返回指针的函数 指向函数的指针,函数返回int型变量 指向函数的指针,函数返回int 型指针
7.13 有关指针的数据类型和指针运算的小结 有关指针数据类型的小结 定义 含义 int i ; int *p; int a[n]; 定义整型变量 int *p; p为指向整型数据的指针变量 int a[n]; 定义整型数组a,它有n个元素 int *p[n]; 定义整型数组p,它由n个指向整型数据的指针元素组成 int (*p)[n]; p为指向含n个元素的一维数组的指针变量 int f(); f为返回整型函数值的函数 int *p(); p为返回一个指针的函数,该指针指向整型数据 int (*p)() p为指向函数的指针,该函数返回一个整数值 int **p p是一个指针变量,它指向一个指向整数数据的指针变量
指针运算小结 指针变量加(减)一个整数 例如:p++、p--、p+i、p-i、p+=i、p-=i等。 p=&a(将变量a的地址赋给p) p=array; (将数组array首地址赋给p) p=&array[i];(将数组array第i个元素的地址赋给p) p=max; (max为已定义的函数,将max的入口地址赋给p) p1=p2; (p1和p2都是指针变量,将p2的值赋给p1) (2) 指针变量赋值
(3) 指针变量可以有空值,即该指针变量不指向任何变量 p=NULL; 假如p1指向a[1],p2指向a[4],则p2-p1=4-1=3。 但p1+p2并无实际意义。 (4) 两个指针变量可以相减 (5) 两个指针变量比较 p1<p2,
思考:如p是指向二维数组中a中元素的指针,开始指向a[0][0],则a[i][j]的地址如何表示?如p是指向二维数组中每一行的指针,则又有什么不同?