第九章 指针
1.指针:特殊的数据类型
指针变量:具有指针类型的变量,用来存放变量的地址
指针的定义形式:类型关键字(基类型) *指针变量名
指针变量的基类型:指针变量指向的变量的数据类型
eg:int *pa;pa是一个指针变量,它指向一个整型变量
2.指针变量必须有指向,一般在定义指针变量时将其初始化为NULL;
NULL为stdio.h中定义为0的宏;
3.变量的指针:指向某变量的指针变量;
指针变量中存放的是变量的地址,所以变量的指针和变量的地址在数值上相等;
概念上,不同,变量的地址是常量不能赋值,变量的指针是变量,可赋值;
4.指针变量的初始化:
int *pa=&a; 等价 int *pa;pa=&a;
含义:定义一个可以指向整型数据的指针变量pa,
用整型变量a的地址值对指针变量pa进行初始化,
从而使指针变量pa具体的指向了整型变量a
5.直接寻址:直接按变量名或者变量的地址存取变量的内容的访问方式;
eg:scanf("%d",&a)-写;printf("%d",a)-读;
间接寻址:通过指针变量间接存取它所指向的变量的访问方式;
eg:int *pa=&a;先通过指针变量pa获得变量a的地址值,然后再到地址的存储单元中去访问变量a;
6.&,取地址运算符
*,指针运算符,间接寻址运算符
功能:①指针变量的定义:作为指针类型说明符,用于指针变量的定义
②指针的解引用:用于读取显示指针变量中存储的内存地址所对应的变量的值,
即得到指针变量指向的变量的值(前提:指针变量有指向)
eg:int *pa=&a;对*pa的修改相当于对a的修改
//例9-1 使用指针变量,通过间接寻址输出变量
//指针的一般用法
#include<stdio.h>
void main()
{
int a=1,b=2;
char c='a';
int *pa=&a,*pb=&b;
char *pc=&c;
*pa=5;
printf("*pa=%d\ta=%d\n",*pa,a);//5,5
printf("*pb=%d\tpc=%c\n",*pb,*pc);//2,a
}
7.按值传递:普通变量作函数形参,把实参值的复制传给函数,形参改变不影响实参;
按地址传递:指针或数组做函数形参,把地址值传给形参,形参改变影响实参;
//例9-2 按地址调用(指针变量作函数参数)
#include<stdio.h>
void Fun(int *par);
int main()
{
int arg=1;
printf("arg=%d\n",arg);//arg=1
Fun(&arg);
printf("arg=%d\n",arg);//arg=2
return 0;
}
void Fun(int *par)
{
printf("par=%d\n",*par);//arg=1
*par=2;
}
8.return从函数只能返回一个值,要得到多个值必须使用按地址调用
//例9-3 按地址调用,交换两数
#include<stdio.h>
void Swap(int *x,int *y);
int main()
{
int a,b;
printf("Please enter two numbers:");
scanf("%d %d",&a,&b);
printf("交换前:a=%d,b=%d\n",a,b);
Swap(&a,&b);
printf("交换后:a=%d,b=%d\n",a,b);
return 0;
}
void Swap(int *x,int *y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
//例9-4 按地址调用,键盘输入某班学生某门课的成绩,每班人数不超过40人,具体人数
由键盘输入,计算输出最高分及相应学生的学号
#include"stdio.h"
#define N 40
int ReadScore(int score[],long num[]);
void FindMax(int score[],long num[],int *MaxScore,long *MaxNum,int n);
int main()
{
int n,MaxScore;
int score[N];
long num[N],MaxNum;
n=ReadScore(score,num);
FindMax(score,num,&MaxScore,&MaxNum,n);
printf("\n");
printf("最高分:%d\n",MaxScore);
printf("学号:%ld\n",MaxNum);
return 0;
}
int ReadScore(int score[],long num[])
{
int i=-1;
do{
i++;
printf("\n请输入学号,-1结束:");
scanf("%ld",&num[i]);
if(num[i]>=0)
{
printf("请输入该同学成绩:");
scanf("%d",&score[i]);
}
}while(num[i]>=0);
return i;
}
void FindMax(int score[],long num[],int *MaxScore,long *MaxNum,int n)
{
int i;
*MaxScore=score[0];
*MaxNum=num[0];
for(i=0;i<n;i++)
{
if(score[i]>*MaxScore)
{
*MaxScore=score[i];
*MaxNum=num[i];
}
}
}
9.函数指针:指向函数的指针
数组名:存储数组第一个元素的内存地址;
函数名:函数的源代码在内存中的起始地址,函数的入口地址;
eg1:int(*compare)(int a,int b);compare是一个函数指针;
含义:形参compare是一个指针变量,指向一个有两个整型形参且返回值整型的函数;
分析:(*compare)表示compare是指针变量,(*compare)()表示指针变量指向函数;
调用语句:
①if((*compare)(a[j],a[k]))
原理:通过指针的解引用来调用函数指针所指向的函数;
②if(compare(a[j],a[k]))
原理:把函数指针当做函数名来直接使用;
eg2:int *compare(int a,int b);compare不是函数指针;
含义:是一个函数,有两个整型形参,返回值类型为整型指针
//例9-5 同时实现对成绩的升序和降序排序
#include"stdio.h"
#define N 40
int ReadScore(int score[],long num[]);
void Sort(int score[],long num[],int n,int (*compare)(int a,int b));
int Ascending(int a,int b);
int Descending(int a,int b);
void Swap1(int *x,int *y);
void Swap2(long *x,long *y);
void Print(int score[],long num[],int n);
int main()
{
int chioce;
int score[N],n;
long num[N];
n=ReadScore(score,num);
Print(score,num,n);
printf("1.升序\n");
printf("2.降序\n");
printf("请选择:");
scanf("%d",&chioce);
if(chioce==1)
{
Sort(score,num,n,Ascending);//函数指针指向Ascending()
}
else if(chioce==2)
{
Sort(score,num,n,Descending);//函数指针指向Descending()
}
else{
printf("没有这个选项!\n");
}
Print(score,num,n);
return 0;
}
int ReadScore(int score[],long num[])
{
int i=-1;
do{
i++;
printf("\n请输入学号,-1结束:");
scanf("%ld",&num[i]);
if(num[i]>=0)
{
printf("请输入该同学成绩:");
scanf("%d",&score[i]);
}
}while(num[i]>=0);
return i;
}
void Sort(int score[],long num[],int n,int (*compare)(int a,int b))
{
int i,j,k,temp1;
long temp2;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if((*compare)(score[j],score[k]))//调用函数指针指向的函数
{
k=j;
}
}
if(k!=i)
{
Swap1(&score[i],&score[k]);
Swap2(&num[i],&num[k]);
}
}
}
int Ascending(int a,int b)
{
return a<b;
}
int Descending(int a,int b)
{
return a>b;
}
void Swap1(int *x,int *y)
{
int temp;
temp=*x;
*x=*y;
*y=temp;
}
void Swap2(long *x,long *y)
{
long temp;
temp=*x;
*x=*y;
*y=temp;
}
void Print(int score[],long num[],int n)
{
int i;
printf("学号 成绩\n");
for(i=0;i<n;i++)
{
printf("%-12ld%-2d\n",num[i],score[i]);
}
}