指针

                      第九章   指针

1.指针:特殊的数据类型

  指针变量:具有指针类型的变量,用来存放变量的地址

  指针的定义形式:类型关键字(基类型)  *指针变量名 

  指针变量的基类型:指针变量指向的变量的数据类型

  eg:int *pa;pa是一个指针变量,它指向一个整型变量

2.指针变量必须有指向,一般在定义指针变量时将其初始化为NULL;

  NULLstdio.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]);

}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值