博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言-第七章、用指针实现程序的灵活设计
阅读量:6344 次
发布时间:2019-06-22

本文共 7065 字,大约阅读时间需要 23 分钟。

  hot3.png

 

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】 通过指针变量引用变量的值

#include
int 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】 指针变量及其简单运算

#include
int 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】 用一般变量作为参数,不能实现交换。

#include
int 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】若改写为指针函数为参数即可交换。

#include
int 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)下标法

#include
int 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)常量指针法:

#include
int 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)指针变量法:

#include
int 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)指针带下标法:

#include
int 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)逐个移动指针法:

#include
int 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】用指针变量输入多维数组的值

#include
int 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】用指向一维数组的指针变量输出二维数组中的各元素值。

#include
int 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】用字符指针处理字符数组中的字符串

#include
int main(){ char s[]="China"; char *p=s; while (*p!='\0') { putchar(*p); p++; } printf("\n"); return 0;}

【例7-12】用字符指针处理字符串

#include
int main(){ char s[]="China"; char *p=s; printf("%s\n",p); return 0;}

_4.2  字符指针作为函数参数

【例7-14】对字符串内容作修改

#include
void 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】  用指针数组处理二维数组

#include
int 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;

#include
int main(){ char *pa[5]={"Basic","Pascal","Fortran","C","Java"}; char **p; p=pa; while (pa

 

 

 

7_7  指针与函数

_7.1  指针型函数

指针型函数:返回指针值的函数

形式:类型说明符  *函数名(形参表列)

{

……         /*函数体*/

}

【例7-18】输入一个1~7之间的函数,输出对应星期名的英语单词。

#include
char *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】 求两数较大者

#include
int 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语言成绩,并将这些成绩逆序输出。

#include
int 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;}

 

 

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/8824/blog/781985

你可能感兴趣的文章
YourSQLDba 配置——修改备份路径
查看>>
nginx web服务理论与实战
查看>>
java 库存 进销存 商户 多用户管理系统 SSM springmvc 项目源码
查看>>
网易音乐版轮播-react组件版本
查看>>
ES6 - 函数与剩余运算符
查看>>
你对position了解有多深?看完这2道有意思的题你就有底了...
查看>>
WebSocket跨域问题解决
查看>>
ECMAScript6基本介绍
查看>>
世界经济论坛发布关于区块链网络安全的报告
查看>>
巨杉数据库加入CNCF云原生应用计算基金会,共建开源技术生态
查看>>
Ubuntu 16.04安装Nginx
查看>>
从 JS 编译原理到作用域(链)及闭包
查看>>
flutter 教程(一)flutter介绍
查看>>
CSS面试题目及答案
查看>>
【从蛋壳到满天飞】JS 数据结构解析和算法实现-Arrays(数组)
查看>>
每周记录(三)
查看>>
Spring自定义注解从入门到精通
查看>>
笔记本触摸板滑动事件导致连滑的解决方式
查看>>
Android推荐常用的31个库
查看>>
Runtime 学习:消息传递
查看>>