7_1 指针的基本概念
_1.1 地址与指针
C语言中通常把地址成为指针。
_1.2 内存单元的指针与内存单元的内容
_1.3 变量的指针
变量的指针就是变量的地址
_1.4 直接访问与间接访问
7_2 指向变量的指针变量
_2.1 指针变量的定义
形式:基类型说明符 *变量名 如:int *p1
“*”也是一个说明符,p1是一个指针变量。
_2.2 指针变量的引用
1. 指针的专用运算符
(1) 取地址运算符& 例:&变量名
(2)指针运算符* 例:*变量名
2.指针变量的赋值
(1)指针变量的初始化
int a;int *ap=&a; /*定义指向整体变量a的指针变量ap*/
(2) 赋值语句:
①int *ap=&a,a; /*错误,不能把未定义的变量a的地址赋给ap*//*不允许把一个数赋予指针变量,被赋值的指针变量前也不能再加“*”说明符。*///②错例:int *p;p=1000; /*不能把一个数赋予指针变量*/*p=&a; /*被赋值的指针变量前不能再加“*”说明符*/
(3)将已被赋值的指针变量的值赋给另一指针变量
int a,*ap,*bp;ap=&a; /*使指针变量ap指向变量a*/bp=ap; /*将指针变量ap的值赋给指针变量bp;执行该语句后ap和bp都指向同一变量a*/
注:只有相同类型的指针变量之间可以相互赋值。
错例:
int a=3,*ap=&a;float bp;bp=ap; /*错误,指针变量bp只能指向float型变量(只能保存float型变量的地址)*/
(4) 可以给指针变量赋0值如:
char *p=0;
该指针称为空指针,为了程序的可读性,通常符号常量NULL来表示空指针的值。如:
char *p=NULL;
3. 指针变量加减一个整数
一个指针加一个整数,表示将指针后移;相反,一个指针减一个整数,表示将指针前移。
4. 两个同类指针变量相减
用于数组,差值表示两个指针变量之间相隔的元素个数
5. 两个同类指针变量作比较运算
用于判断先后关系
6. 指针变量的引用举例
【例7-1】 通过指针变量引用变量的值
#includeint main(){ int a,b; int *ap,*bp; a=100; b=10; ap=&a; bp=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*ap,*bp); return 0;}
【例7-2】 指针变量及其简单运算
#includeint main(){ int x=3,y,*xp=&x; y=*xp+5; printf("y=%d\n",y); y=++*xp; printf("%d\n",y); y=*xp++; printf("x=%d,y=%d\n",x,y); /*表示把x的值赋给y再使xp后移,即等价于y=*xp;xp++;*/ return 0;}
注:“++”和“*”的运算优先级相同且都是自右向左。
_2.2 指针变量作为函数参数
【例7-3】 用一般变量作为参数,不能实现交换。
#includeint main(){ int swap(int x,int y); int a=100,b=10; printf("%d,%d\n",a,b); swap(a,b); printf("%d,%d\n",a,b); return 0;}int swap(int x,int y) /*交换指针变量ap,bp所指向是地址单元中的内存*/{ int temp; temp=x; x=y; y=temp;}
【例7-4】若改写为指针函数为参数即可交换。
#includeint main(){ int swap(int *ap,int *bp); int a=100,b=10; printf("%d,%d\n",a,b); swap(&a,&b); printf("%d,%d\n",a,b); return 0;}int swap(int *ap,int *bp) /*交换指针变量ap,bp所指向是地址单元中的内存*/{ int temp; temp=*ap; *ap=*bp; *bp=temp;}
7_3指针与数组
_3.1 指针与一维数组
1. 指向数组元素的指针变量
形式:基类型说明符 *指针变量 如:
int a[10];int *p;p=&a[0];
C语言规定,把数组的首地址称为数组的指针。
(1)p、a、&a[0]均指向同一单元,它们是数组a的首地址,但是p是指针变量,而a、&a[0]都是指针常量。
2. 通过指针引用数组元素
三种方法:①下标法 ②常量指针法 ③指针变量法。
(1)下标法
#includeint main(){ int a[5],i; printf("Please input 5 numbers:"); for (i=0;i<5;i++) scanf("%d",&a[i]); for (i=0;i<5;i++) printf("a[%d]=%-4d",i,a[i]); printf("\n"); return 0;}
(2)常量指针法:
#includeint main(){ int a[5],i; printf("Please input 5 numbers:"); for (i=0;i<5;i++) scanf("%d",a+i); for (i=0;i<5;i++) printf("a[%d]=%-4d",i,*(a+i)); printf("\n"); return 0;}
(3)指针变量法:
#includeint main(){ int a[5],i,*p=a; printf("Please input 5 numbers:"); for (i=0;i<5;i++) scanf("%d",p+i); for (i=0;i<5;i++) printf("a[%d]=%-4d",i,*(p+i)); printf("\n"); return 0;}
(4)指针带下标法:
#includeint main(){ int a[5],i,*p=a; printf("Please input 5 numbers:"); for (i=0;i<5;i++) scanf("%d",&p[i]); for (i=0;i<5;i++) printf("a[%d]=%-4d",i,p[i]); printf("\n"); return 0;}
(5)逐个移动指针法:
#includeint main(){ int a[5],i,*p=a; printf("Please input 5 numbers:"); for (i=0;i<5;i++) scanf("%d",p++); p=a; for (i=0;i<5;i++) printf("a[%d]=%-4d",i,*p++); printf("\n"); return 0;}
3.用数组的指针作为函数的参数
【例7-7】用冒泡法对10个整数按升序排列
#include#define N 5int main(){ void output(int *p,int n); void sort (int x[],int n); int a[N],i,*p; printf("请输入%d个整数:\n",N); for (i=0;i x[j+1]) {t=x[j];x[j]=x[j+1];x[j+1]=t;} }}
_3.2 指针与多维数组
1.多维数组的地址
2.指向二维数组元素的指针变量
【例7-9】用指针变量输入多维数组的值
#includeint main(){ int a[2][3]={ {1,2,3},{4,5,6}},i; int *p=a[0]; for (i=0;i<6;i++) { printf("%-4d",p[i]); if ((i+1)%3==0) printf("\n"); } return 0;}
3.指向一维数组的指针变量
形式:类型说明符 (*指针变量名)[长度];如:
int (*p)[3];
【例7-10】用指向一维数组的指针变量输出二维数组中的各元素值。
#includeint main(){ int a[2][3]={1,2,3,4,5,6}; int *(p)[3]; int i,j; for (i=0;i<2;i++) { for (j=0;j<3;j++) printf("%-4d",*(*(p+i)+j)); printf("\n"); } return 0;}
7_4 字符串与指针
_4.1 字符指针的定义与引用
对指向字符变量的指针变量应赋予该字符变量的地址。如:
char c,*p=&c;
对指向字符串的指针变量应赋予一个字符串的首地址,如:
char c,*p="China";
等效于:char *p; p="China";
【例7-11】用字符指针处理字符数组中的字符串
#includeint main(){ char s[]="China"; char *p=s; while (*p!='\0') { putchar(*p); p++; } printf("\n"); return 0;}
【例7-12】用字符指针处理字符串
#includeint main(){ char s[]="China"; char *p=s; printf("%s\n",p); return 0;}
_4.2 字符指针作为函数参数
【例7-14】对字符串内容作修改
#includevoid change (char *s){ s[2]='r';}int main(){ char a[]="file"; change (a); printf("%s\n",a); return 0;}
7_5 指针数组
_5.1 用指针数组处理二维数组
【例7-15】 用指针数组处理二维数组
#includeint main(){ int a[2][3]={ {1,2,3},{4,5,6}},i,j; int *pa[2]; /*定义数组pa,它的两个数组pa[0]和pa[1]都是存放指针变量的*/ pa[0]=a[0]; pa[1]=a[1]; for (i=0;i<2;i++) { for (j=0;j<3;j++) printf("%-4d",*(pa[i]+j)); printf("\n"); } return 0;}
_5.2 用字符指针数组处理一组字符串
【例7-16】 用冒泡法对字符按字母顺序升序排列
#include#include void sort (char *a[],int n){ int i,j; char *t; for (i=0;i 0) {t=a[j];a[j]=a[j+1];a[j+1]=t;}}int main(){ char *p[5]={"Basic","Pascal","Fortran","C","Java"}; int i; sort (p,5); for(i=0;i<5;i++) printf("%s\n",p[i]); return 0;}
7_6 指向指针的指针
二级指针的定义格式: 类型说明符 **指针变量名; 如:
int **p;
#includeint main(){ char *pa[5]={"Basic","Pascal","Fortran","C","Java"}; char **p; p=pa; while (pa
7_7 指针与函数
_7.1 指针型函数
指针型函数:返回指针值的函数
形式:类型说明符 *函数名(形参表列)
{
…… /*函数体*/
}
【例7-18】输入一个1~7之间的函数,输出对应星期名的英语单词。
#includechar *day_name(int n){ char *name[]={"Monday ","Tuseday","Wednesday","Thursday","Friday","Saturday","Sunday"}; return (name[n-1]);}int main(){ int i; char *day_name(int n); printf("\t星期名对应的英文单词查询\n请输入一个1~7之间的整数:"); scanf("%d",&i); while (i<1||i>7) { printf("出错!,请重新输入:"); scanf("%d",&i); } printf("星期%d对应的英语单词:%s\n",i,day_name(i)); return 0;}
_7.2 指向函数的指针变量
格式:类型说明符 (*指针变量名)();如:
int (*p)();
【例7-19】 求两数较大者
#includeint max(int a,int b){ if(a>b) return a; else return b;}int main(){ int x,y,z; int (*p)(); p=max; printf("请输入两个整数(用逗号分隔):\n"); scanf("%d,%d",&x,&y); z=(*p)(x,y); printf("两数中较大者为:%d\n",z); return 0;}
7_8 指针应用过程中的注意事项
1. 要准确理解指针的含义,区别指针和指针变量的不同含义。
2. 在对数组进行操作时,要能正确的使用指针。
3. 读者须对各种有关的指针变量定义形式加深理解。
4. void指针,即“指向空类型的指针”,是指不指向具体数据对象的指针。
5. 指针还可以实现对动态分配的内存空间进行有效的管理。
C语言中,常用malloc()和free()这两个函数以及sizeof运算符动态分配和释放内存空间。
malloc()函数和free()函数所需的信息通常在头文件stdio.h 中,其函数原型及功能如下:
(1)malloc()函数
函数原型:
void *malloc (unsigned size)
功能:从内存分配一个大小为size个字节的内存空间。如果分配成功,返回新分配内存的首地址;如果没有足够的内存分配,则返回NULL。
为确保内存分配准确,函数malloc()通常和运算符sizeof 一起使用。例:
int *p;p=(int* )malloc(20*sizeof(int));/*分配20个所需的内存空间*/
(2) free函数
函数原型:void free(void *p);
功能:释放由指针变量p所指向的内存块,无返回值。如:
int *p;p=(int* )malloc(20*sizeof(int));/*分配20个所需的内存空间*/……free(p);
【例7-20】 输入n名学生的C语言成绩,并将这些成绩逆序输出。
#includeint main(){ float *score; int n,i; printf("请输入学生人数:"); scanf("%d",&n); score=(float*)malloc(n*sizeof(float)); if(!score) printf("分配空间失败!\n"); else { printf("请输入%d个学生的成绩(空格分隔):\n",n); for (i=0;i =0;i--) printf("%7.2f",score[i]); printf("\n"); free(score); } return 0;}