专升本C语言——第八章

指针是什么?

i_pointer=&i;//将i的地址放到i_pointer

指针变量就是地址变量,用来存放地址,指针变量的值是地址(即指针)

指针是一个地址,指针变量是存放地址的变量

指针变量

指针变量的定义

指针变量的一般形式:

类型名 * 指针变量名

int * pointer_1,*pointer_2;

指针变量前面的”*“表示该变量的类型为指针型变量

int型使“指针加1”意味着使地址值加4个字节,char使“指针加1”意味着使地址加1个字节

一个变量的指针的含义包括两个方面,一是以存储单元编号表示的地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int,char,float等)

指针整型数据的指针类型表示为“ int* ”,读作指向int的指针或简称int指针

指针变量中只能存放地址(指针),不要将一个整型赋给一个指针变量

*pointer_1=100;//pointer_1是指针变量,100是整数,不合法

指针变量的引用

给指针变量赋值
p=&a//把a的地址赋给指针变量p

指针变量p的值是变量a的地址,p指向a

引用指针变量指向的变量
p=&a;
printf("%d",*p);

其作用是以整数形式输出指针变量p所指向的变量的值,即变量a的值

*p=1;

表示将整数1赋给p当前所指向的变量,如果p指向变量a,则相当于把1赋给a,即a=1

引用指针变量的值
printf("%o",p);

作用是以八进制形式输出指针变量p的值,如果p指向了a,就输出了a的地址,即&a

& 取地址运算符。&a是变量a的地址
* 指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象

指针变量做函数参数

作用:将一个变量的地址传送到另一个函数中

函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值,如果不用指针变量是难以做到这一点的

通过指针引用数组

数组元素的指针

一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。所谓数组元素的指针就是数组元素的地址

int a[10]={
    
    1,3,5,7,9,11,13,15,17,19};//定义a为包含10个整形数据的数组
int *p;//定义p为指向整形变量的指针变量
p=&a[0];//把a[0]元素的地址赋给指针变量p

数组名代表数组中首元素(即序号为0的元素)的地址

p=&a[0];//p的值是a[0]的地址
p=a;//p的值是数组a首元素(即a[0])的地址

注意:数组名不代表整个数组,只代表数组首元素的地址

在引用数组元素时指针的运算

在指针指向数组元素时,可以对指针进行以下运算:

加一个整数(用+或+=),如p+1

减一个整数(用-或-=),,如p-1

自加运算,如p++,++p

自减运算,如p- -,- -p

两个指针相减,如p1-p2(只有p1和p2都是指向同一个数组中的元素才有意义)

如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素

p+1所代表的地址实际是(p+1)*d,d是一个数组元素所占的字节数

若p的值是2000,则p+1的值是2004

通过指针引用数组元素

下标法:如a[i]形式;

指针法:如*(a+1)或 *(p+1),其中a是数组名,p是指向数组元素的指针变量,其初值p=a

下标法
#include<stdio.h>
int main()
{
    
    
	int a[10];
	int i;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++)
		scanf("%d", &a[i]);
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}

运行结果:

please enter 10 integer numbers:1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
通过数组名计算数组元素地址,找出元素的值
#include<stdio.h>
int main()
{
    
    
	int a[10];
	int i;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++)
		scanf("%d", &a[i]);//&a[i]表示a[i]元素的地址,也可以改用(a+i)表示,即scanf("%d",a+i);
	for (i = 0; i < 10; i++)
		printf("%d ", *(a + i));
	printf("\n");
	return 0;
}

运行结果:

please enter 10 integer numbers:1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
用指针变量指出数组元素
#include<stdio.h>
int main()
{
    
    
	int i,a[10],*p=a;
	printf("please enter ten integer numbers:");
	for (i = 0; i < 10; i++)
		scanf("%d", p++);
	p = a;
	for (i = 0; i < 10; i++)
		printf("%d ", *p++);
	printf("\n");
	return 0;
}

运行结果:

please enter 10 integer numbers:1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
p++//p++使p指向下一元素a[1]
*p;//得到下一个元素a[1]的值
*p++//++和*优先级,结合方向为自右而左,因此它等价于*(p++),先引用p的值,实现*p的运算,然后再使p自增1
*(p++)//先取*p值,然后使p加1
*(++p)//先使p加1,再取*p
++(*p)//表示p所指的元素加1

用数组名作函数参数


int main()
{
    
    
	void fun(int arr[],int n);//对fun函数的声明
	int array[10];//定义array数组
	fun(array,10);//用数组名作函数的参数
	return 0;
}

void fun(int arr[],int n)//定义fun函数 等价于void fun(int *arr,int n)
{
    
    
    
}

array是实参数组名,arr为形参数组名

sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。

&数组名,取出的是数组的地址。&数组名,数组名表示整个数组。

*(arr+i)等价于arr[i]

代表数组array序号为0的元素

arr[0]
*arr
array[0]

以变量名和数组名作为函数参数的比较

传递的信息 变量的值 实参数组首元素的地址
实参类型 变量名 数组名
要求形参的类型 变量名 数组名或指针变量
通过函数调用能否该该改变实参的值 不能改变实参变量的值 能改变实参变量的值
void fun(arr[],int n)
{
    
    
	printf("%d\n",*arr);//输出array[0]的值
	arr=arr+3;//形参数组名可以被赋值
	printf("%d\n",*arr);//输出array[3]的值
}

形参和实参都用数组名

int f(int x[],int n)//形参数组名x接受了实参数组首元素a[0]的地址,形参数组和实参数组共用一段内存单元
{
    
    

}
int main()
{
    
    
	int a[10];
	f(a,10);
}

实参用数组名,形参用指针变量

void f(int *x,int n)//形参x为int*型的指针类型
{
    
    

}
int main()
{
    
    
	int a[10];//实参a为数组名
	f(a,10);
}
//调用函数开始后,形参x指向a[0],即x=&a[0],通过x值的改变,可以指向a数组的任一元素

实参形参都用指针变量

void f(int *x,int n)//形参x是int*型的指针变量
{
    
    

}
int main()
{
    
    
    int a[10],*p=a;
	f(p,10);//实参p是int*型的指针变量
}
//先使实参指针变量p指向数组a[0],p的值是&a[0],然后将p的值传给指针变量x,x的初始值也是&a[0]
//通过x值的改变可以使x指向数组a的任一元素

实参为指针变量,形参为数组名

void f(int x[],int n)//形参为数组名x,编译系统把x作为指针变量处理,将a[0]的地址传给形参x,使x也指向a[0]
{
    
    

}
int main()
{
    
    
	int a[10],*p=a;
	f(p,10);//实参p为指针变量,他指向a[0]
}
//形参数组x和a数组共用同一段内存单元
//在函数执行过程中可以使x[i]的值发生改变,而x[i]就是a[i],这样main函数可以使用变化了的数组元素值

通过指针引用多维数组

多维数组元素的地址

指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素

定义一个二维数组a,它有3行4列

int a[3][4]={
    
    {
    
    1,2,5,7},{
    
    9,11,13,15},{
    
    17,19,21,23}};

a是二维数组名,a数组包含3行,即3行个元素:

 a[0];
 a[1];
 a[2];

每一个行元素又是一个一维数组,它包括4个元素。

例如:a[0]所代表的一维数组又包含4个元素

a[0][0];
a[0][1];
a[0][2];
a[0][3];

可以认为二维数组是“数组的数组”,即二维数组a是由3个一维数组所组成的

从二维数组的角度来看,a代表二维数组首元素的地址,现在的首元素是一个由4个整型元所组成的一维数组,因此a所代表的是首行(序号为0的行)的首地址。a+1代表序号为1的行的首地址。如果二维数组的首行的地址是2000,一个整型数据占4个字节,则a+1的值应该是2000+4*4=2016(因为第0行有4个整型数据),a+1指向a[1],或者说,a+1的值是a[1]的首地址,a[2]代表a[2]的首地址,他的值是2032

a[0]是一维数组名,该一维数组中序号为1的元素的地址用a[0]+1来表示

a[0]+1中的1代表1个列元素的字节数,即4个字节,a[0]的值是2000,a[0]+1的值是2004,

a[0]+0  ==  a[0][0]
a[0]+1  ==  a[0][1]
a[0]+2  ==  a[0][2]
a[0]+3  ==  a[0][3]

a[0] [3]元素的地址

&a[0][0];
&a[0][1];
&a[0][2];
&a[0][3];

a[0] [1]的值用地址法的表示方法

*(a[0]+1)是a[0][1]的值
*a(*(a+0)+1)*(*a+1)是a[0][1]的值
*(a[i]+j)*(*(a+i)+j)是a[i][j]的值
*(a+i)和a[i]是等价的

a[i]从形式上看是a数组中序号为i的元素,如果a是一维数组名,则a[i]表示a数组序号为i的元素的存储单元。a[i]是有物理地址的,是占存储单元的。但如果a是二维数组,则a[i]是一维数组名,它只是一个地址,并不代表某一元素的值(如同一维数组名只是一个指针变量一样)。a,a+i, a[i], *(a+i), (a+i)+j, a[i]+j;都是地址,而 *(a[i]+j)和 *( * (a+i)+j)是二维数组元素a[i] [j]的值

二维数组a的有关指针

表示形式 含义 地址
a 二维数组名,指向一维数组a[0],即0行地址 2000
a[0], *(a+0), *a 0行0列元素地址 2000
a+1,&a[1] 一行首地址 2016
a[1], *(a+1) 1行0列元素a[1] [0]的地址 2016
a[1]+2,*(a+1)+2,&a[1] [2] 1行2列元素a[1] [2]的地址 2024
*(a[1]+2), *( *(a+1)+2),a[1] [2] 1行2列元素a[1] [2]的值 元素为13

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tSLC5meh-1669523540368)(C:\Users\LENOVO\Desktop\Untitled.png)]

  • 二维数组名是指向行的,因此a+1中的1代表一行全部元素所占的字节数(16个字节)
  • 一维数组名是指向列元素的,a[0]+1中的1代表一个a元素所占的字节数(4个字节)
  • 在指向行的指针前面加一个*就是 *a和 *(a+1),他们就成为指向列的指针,分别指向a组0行0列元素和1行0列的元素。
  • 在指向列的指针前面加&,就成为指向行的指针,例如a[0]是指向0行0列元素的指针,在它前面加一个&,得到&a[0]与& *a等价,也就是与a等价,它指向二维数组的0行
//输出二维数组的有关数据(地址和值)
#include<stdio.h>
int main()
{
    
    
	int a[3][4] = {
    
     1,3,5,7,9,11,13,15,17,19,21,23 };
	printf("第一个:%d %d\n", a, *a);						//0行首地址和0行0列元素地址
	printf("第二个:%d %d\n", a[0], *(a + 0));				//0行0列的元素地址
	printf("第三个:%d %d\n", &a[0], &a[0][0]);				//0行首地址,0行0列元素地址
	printf("第四个:%d %d\n", a[1], a + 1);					//1行0列元素地址和1行首地址
	printf("第五个:%d %d\n", &a[1][0], *(a + 1) + 0);		//1行0列元素地址
	printf("第六个:%d %d\n", a[2], *(a + 2));				//2行0列首地址
	printf("第七个:%d %d\n", &a[2], a + 2);				//2行首地址
	printf("第八个:%d %d\n", a[1][0], *(*(a + 1) + 0));    //1行0列元素的值
	printf("第九个:%d %d\n", *a[2], *(*(a + 2) + 0));      //2行0列元素的值
	return 0;
}

运行结果:

第一个:-1068368920 -1068368920
第二个:-1068368920 -1068368920
第三个:-1068368920 -1068368920
第四个:-1068368904 -1068368904
第五个:-1068368904 -1068368904
第六个:-1068368888 -1068368888
第七个:-1068368888 -1068368888
第八个:9 9
第九个:17 17

指向多维数组元素的指针变量

指出数组元素的指针变量
//有一个3*4的二维数组,要求用指向元素的指针变量输出二维数组各元素的值
#include<stdio.h>
int main()
{
    
    
	int a[3][4] = {
    
     1,2,3,4,5,6,7,8,9,10,11,12 };
	int* p;										//p是int*型指针变量
	p = a[0];
	for (p = a[0]; p < a[0] + 12; p++)			//使p依次指向下一个元素
	{
    
    
		if ((p - a[0])% 4 == 0)					//p移动4次换行
			printf("\n");
		printf("%4d", *p);						//输出p指向的元素的值
	}
	printf("\n");
	return 0;
}

运行结果:

   1   2   3   4
   5   6   7   8
   9  10  11  12

计算a[i] [j]在数组中的相对位置的计算公式
i ∗ m + j i*m+j im+j
其中m为二维数组的列数(二维数组大小为n*m)

上述3*4的二维数组,它的2行3列元素a[2] [3]对a[0] [0]的相对位移量为2 * 4+3=11元素

如果一个元素占4个字节,则a[2] [3]对a[0] [0]的地址差为 11*4=44字节

若开始时指针变量p指向a[0] [0],a[i] [j]的地址为“&a[0] [0]+(i*m+j)”或p+(i * m+j)

a[2] [3]的地址是(p+2*4+3),即(p+11),a[2] [3]的值为 *(p+11)

指向m个元素组成的一维数组的指针变量

p先指向a[0] (即便p=&a[0]),则p+1不是指向a[0] [1],而是指向a[1],p的增值以一维数组的长度为单位

//输出二维数组任一行任一列元素的值
#include<stdio.h>
int main()
{
    
    
	int a[3][4] = {
    
     1,2,3,4,5,6,7,8,9,10,11,12 };			//定义二维数组a并初始化
	int(*p)[4], i, j;										//指针变量p指向包含4个整型元素的一维数组
	p = a;													//p指向二维数组的0行
	printf("please enter row and colum:");
	scanf("%d,%d,", &i, &j);								//输入要求输出的元素的行列号
	printf("a[%d,%d]=%d\n", i, j, *(*(p + i) + j));			//输出a[i][j]的值
	return 0;
}

运行结果:

please enter row and colum:1,2
a[1,2]=7

int(*p)[4]表示定义p为一个指针变量,它指向包括4个整型元素的一维数组

int a[4];    //(a有四个元素,每个元素为整形)
int (*p)[4];    //(*p)有四个元素,每个元素为整型,也就是p所指的对象是有4个整型元素的数组,即p是指向一维数组的,不能指向一维数组中的某一元素,p的值就是该一维数组的起始地址
#include<stdio.h>
int main()
{
    
    
	int a[4] = {
    
     1,3,5,7 };		//定义一维数组a,包括4个元素
	int(*p)[4];					//定义指向包含4个元素的一维数组的指针变量
	p = &a;						//p指向一维数组
	printf("%d\n", (*p)[3]);	//输出a[3],输出整型7
	return 0;
}
用指向数组的指针作函数参数

一维数组名可以作为函数参数,多维数组名也可以作函数参数。用指针变量作形参,以接受实参数组名传递来的地址

有两种方法:用指向变量的指针变量和用指向一维数组的指针变量

注意:实参和形参如果是指针类型,应当注意它们的类型必须一致

不应把int*型的指针(即元素的地址)传给int( *)[4]型(指向一维数组)的指针变量,反之亦然。

通过指针引用字符串

字符串的引用方式

用字符数组存放一个字符串,可以通过数组名和下标引用字符串中的一个字符,也可以通过数组名和格式声明“%s”输出该字符串

//例如:
#include<stdio.h>
int main()
{
    
    
	char string[] = "I love china!";		//定义字符数组string
	printf("%s\n", string);					//用%s格式声明输出string,可以输出整个字符串
	printf("%c\n", string[7]);				//用%c格式输出一个字符数组元素
	return 0;
}

运行结果:

I love china!
c

用字符指针变量指向一个字符串变量变量,通过字符指针变量引用字符串常量

//例如:
#include<stdio.h>
int main()
{
    
    
	char* string = "i love china!";		//定义字符指针变量string并初始化,
    									//它只能指向一个字符类型数据,而不能同时指向多个字符数据
	printf("%s\n", string);				//输出字符串
	//上一句等价于下面两句
	//char *string;
	//string="i love china!";
	return 0;
}

运行结果:

i love china!

可以通过指针变量进行再赋值

string="i am a student.";//把字符串“i am a student."的第一个字符的地址赋给指针变量名string,此后string就指向"i am a student"

通过字符数组名或字符指针变量可以输出一个字符串

字符串中字符的存取
//将字符a串复制为字符串b,然后输出字符b
//下标方法
#include<stdio.h>
int main()
{
    
    
	char a[] = "i am a student.", b[20];	//定义字符数组
	int i;
	for (i = 0; *(a + i) != '\0'; i++)
		*(b + i) = *(a + i);				//将a[i]的值赋给b[i]
	*(b + i) = '\0';						//将b数组的有效数组之后加'\0'
	printf("string a is:%s\n", a);			//输出a数组中全部有效字符
	printf("string b is:");
	for (i = 0; b[i] != '\0'; i++)
		printf("%c", b[i]);					//逐个输出b数组中全部有效字符
	printf("\n");
	return 0;
}

//指针方法
#include<stdio.h>
int main()
{
    
    
	char a[] = "i am a student.", b[20], * p1, * p2;
	p1 = a, p2 = b;							//p1,p2分别指向a数组和b数组中的第一个元素
	for (; *p1 != '\0'; p1++, p2++)			//p1,p2每次自加1
		*p2 = *p1;							//将p1所指向的元素的值赋给p2所指的元素
	*p2 = '\0';								//在复制完全部有效字符后加'\0'
	printf("string a is: %s\n", a);			//输出a数组中的字符
	printf("string b is: %s\n", b);			//输出b数组中的字符
	return 0;
}

运行结果

string a is: i am a student.
string b is: i am a student.

字符指针作函数参数

//用字符数组名作为函数参数
#include<stdio.h>
int main()
{
    
    
	void copy_string(char from[], char to[]);
	char a[] = "i am a teachar.";
	char b[] = "you are a student.";
	printf("string a=%s\nstring b=%s\n", a, b);
	printf("copy string a to string b:\n");
	copy_string(a, b);
	printf("\nstring a=%s\nstring b=%s\n", a, b);
	return 0;
}
void copy_string(char from[], char to[])
{
    
    
	int i = 0;
	while (from[i] != '\0')
	{
    
    
		to[i] = from[i];
		i++;
	}
	to[i] = '\0';
}

//用字符型指针变量作实参
#include<stdio.h>
int main()
{
    
    
	void copy_string(char from[], char to[]);		//函数声明
	char a[] = "i am a teachar.";					//定义字符数组a并初始化
	char b[] = "you are a student.";				//定义字符数组b并初始化
	char* from = a;									//from指向a数组首元素
	char* to = b;									//to指向b数组首元素
	printf("string a=%s\nstring b=%s\n",a, b);
	printf("\ncopy string a to string b:\n");
	copy_string(from, to);							//实参为字符指针变量
	printf("string a=%s\nstring b=%s\n", a, b);
	return 0;
}
void copy_string(char from[], char to[])			//形参为字符数组
{
    
    
	int i = 0;
	while (from[i] != '\0')
	{
    
    
		to[i] = from[i];
			i++;
	}
	to[i] = '\0';
}

//用字符指针变量作形参和实参
#include<stdio.h>
int main()
{
    
    
	void copy_string(char* from, char* to);
	char* a = "i am a teacher.";				//a是char*型指针变量
	char b[] = "you are a student.";			//b是字符串数组
	char* p = b;								//使指针变量p指向b数组首元素
	printf("string a=%s\nsrting b=%s\n", a, b);	//输出a串和b串
	printf("\ncopy string a to srting b:\n");
	copy_string(a, p);							//调用copy_string函数,实参为指针变量
	printf("string a=%s\nstring b=%s\n",a, b);	//输出改变后的a串和b串
	return 0;
}
void copy_string(char* from, char* to)			//定义函数,形参为字符指针变量
{
    
    
    //多种写法
    //1.
	//for (; *from != '\0'; from++,to++)
	//{
    
    
	//	*to = *from;
	//}
    
    //2.
    //while ((*to = *from) != '\0')
	//{
    
    
	//	to++;
	//	from++;
	//}
    
    //3.
    //while ((*to++ = *from++) != '\0');
    
    //4.
    //while (*from != '\0')
	//	*to++ = *from++;
	//*to = '\0';
	//*to = '\0';
    
    //5.
    //while (*from)
	//{
    
    
	//	*to++ = *from++;
	//	*to = '\0';
	//}
    
    //6.
    //while (*to++ = *from++);
    
    //7.
    //while ((*to++ = *from++) != '\0');
    
    //8.
    //for (; *to++ = *from++;);
    
}

运行结果:

string a=i am a teachar.
string b=you are a student.

copy string a to string b:
string a=i am a teachar.
string b=i am a teachar.
调用函数时实参和形参的对应关系
实参 形参 实参 形参
字符数组名 字符数组名 字符指针变量 字符指针变量
字符数组名 字符指针变量 字符指针变量 字符数组名

使用字符指针变量和字符数组的比较

字符数组和字符指针变量的区别

  • 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),绝不是将字符串放在字符指针变量中
  • 赋值方式。可以对字符指针变量赋值,但不能对数组名赋值
char* a;			//a为字符指针变量
a = "i love you";	//将字符串首元素地址赋给指针变量,合法,
					//但是赋给a的不是字符串,而是字符串第一个元素的地址 

不能用以下办法对字符数组名赋值

char str[14];
str[1] = 'I';			//对字符数组元素赋值,合法
str = "i love china";	//数组名是地址,是常量,不能被赋值,非法
  • 初始化的含义,对字符指针变量赋初值
char* a = "i love you";//定义字符指针变量a,并把字符串第一个元素的地址赋给a
//等价于
char* a;				//定义字符串指针变量a
a = "i love you";		//把字符串第一个元素的地址赋给a
//不等价于
char str[14];			//定义字符串数组str
str[] = "i love you";	//企图把字符串赋给数组中的各元素,错误
//数组可以在定义时对各元素赋初值,但不能用赋值语句对字符数组中全部元素整体赋值
  • 存储单元的内容,编译时为字符数组分配若干存储单元,以存放各元素的值,而对字符指针变量,只分配一个存储单元(Visual C++指针变量分配4个字节)

指针变量的值是可以改变的,而数组名代表一个固定的值(数组首元素的地址),不能改变

//改变指针变量的值
#include<stdio.h>
int main()
{
    
    
	char* a = "i love china!";
	a = a + 7;			//改变指针变量的值,即改变指针变量的指向
	printf("%s\n", a);	//输出从a指向的字符开始的字符串
	return 0;
}

运行结果:

china!

字符数组各元素的值是可以改变的(可以对它们再赋值),但字符指针变量指向的字符串常量中的内容是不可以被取代的(不能对他们再赋值)

char a[] = "house";		//字符数组a初始化
char* b = "house";		//字符指针变量b指向字符串常量的第一个元素
a[2] = 'r';				//合法,r取代a数组元素a[2]的原值a
b[2] = 'r';				//非法,字符串常量不能改变

引用数组元素。对字符数组可以用下标法(用数组名和下标)引用一个数组元素(如a[5]),也可以用地址法(如*(a+5))引用数组元素a[5]。如果定义了字符种指针变量p,并使它指数组a的首元素,则可以用指针变量带下标的形式引用数组元素(如p[5]),同样,可以用地址法(如 *(p+5)引用数组元素a[5]

若字符指针变量p指向字符串常量,就可以用指针变量带下标的形式引用所指的字串中的字符

char *a="i love china";		//定义指针变量a,指向字符串常量
//a[5]的值是a所指向的字符串中的第六个字符(序号为5),即字母'e'

用指针变量指向一个格式字符串,可以用它代替printf函数中的格式字符串

char *format;
format="a=%d,b=%f\n";
printf(format,a,b);		//使format指向一个字符串
//相当于
printf("a=%d,b=%f\n"a,b);v

因此只要改变指针变量format所指向的字符串,就可以改变输入输出的格式,这种printf函数称为可变格式输出函数

//字符数组实现
char format[]="a=%d,b=%f\n";
printf(format,a,b);

返回指针值的函数

定义返回值的函数的一般形式为:
类型名 * 函数名 (参数表列)

//例如:
//有a个学生,每个学生有b门课程的成绩,要求在用户输入学生序号以后,能输出该学生的全部成绩,用指针函数来实现
#include<stdio.h>
int main()
{
    
    
	float score[3][4] = {
    
     {
    
    60,70,80,90},{
    
    56,89,67,88},{
    
    34,78,90,66} };//定义数组,存放成绩
	float* search(float(*pointer)[4], int n);							//函数声明
	float* p;
	int i, k;
	printf("enter the number of student:");
	scanf("%d", &k);													//输入要找的学生的序号
	printf("the score of No.%d are:\n", k);
	p = search(score,k);											//调用search函数,返回score[k][0]的地址
	for (i = 0; i < 4; i++)
		printf("%5.2f\t", *(p + i));								//输出score[k][0]~score[k][3]的值
	printf("\n");

	return 0;
}
float* search(float(*pointer)[4], int n)							//形参pointer是指向一维数组的指针变量
{
    
    
	float* pt;
	pt = *(pointer + n);												//pt的值是&score[k][0]
	return (pt);
}

运行结果:

enter the number of student:1
the score of No.1 are:
56.00   89.00   67.00   88.00

返回指针值的函数

定义返回值的函数的一般形式为:
类型名 * 函数名 (参数表列)

//例如:
//有a个学生,每个学生有b门课程的成绩,要求在用户输入学生序号以后,能输出该学生的全部成绩,用指针函数来实现
#include<stdio.h>
int main()
{
    
    
	float score[3][4] = {
    
     {
    
    60,70,80,90},{
    
    56,89,67,88},{
    
    34,78,90,66} };//定义数组,存放成绩
	float* search(float(*pointer)[4], int n);							//函数声明
	float* p;
	int i, k;
	printf("enter the number of student:");
	scanf("%d", &k);													//输入要找的学生的序号
	printf("the score of No.%d are:\n", k);
	p = search(score,k);											//调用search函数,返回score[k][0]的地址
	for (i = 0; i < 4; i++)
		printf("%5.2f\t", *(p + i));								//输出score[k][0]~score[k][3]的值
	printf("\n");

	return 0;
}
float* search(float(*pointer)[4], int n)							//形参pointer是指向一维数组的指针变量
{
    
    
	float* pt;
	pt = *(pointer + n);												//pt的值是&score[k][0]
	return (pt);
}

运行结果:

enter the number of student:1
the score of No.1 are:
56.00   89.00   67.00   88.00

猜你喜欢

转载自blog.csdn.net/weixin_51799303/article/details/128062927