指针综合2021-8-11

指针数组

基本介绍
要让数组的元素 指向 int 或其他数据类型的地址(指针)。可以使用
指针数组

指针数组的定义
数据类型 *指针数组名[大小]

1)比如:int *ptr[3];
2)ptr声明为一个指针数组
3)由 3 个整数指针组成。因此,ptr中的每个元素,都是一个指向 int 值的指针
void main(){
	char* pStr = "hello word!";//定义一个字符指针指向一个字符串
	char* books[] = {//定义一个指向字符的指针数组来存储字符串列表,指针数组的元素指向每个字符串的首地址
		"hello wawa",
		"hello haha",
		"hello henhen",
		"hello hihi",
	};
	int i,bookslen;
	bookslen = sizeof(books)/sizeof(books[0]);
	for(i=0;i<bookslen;i++){
		printf("books[%d] = %s,第九个字符 = %c\n",i,books[i],*(books[i]+8));
		//输出的内容是books[%d] = 字符串,第九个字符 = 字符,字符串的输出直接就是books[i](地址)
		//反观数组也是如此printf("%s",arr);%s表明输出字符串,arr退化为指针为字符数组首地址
		//而给首地址加上”*“,通过取值符号取出首地址的字符,通过加减地址可以取出组成字符串的其他字符
		//字符串中字符的输出则需要带上”*“即*(books[]+...)
	}
	//字符指针与这里指向字符的指针数组里面的元素是一样的
		printf("pStr = %s\n",pStr);//输出字符串
		printf("pStr = %c\n",*pStr);//输出首字符
		printf("pStr = %p\n",pStr);//输出首地址
		printf("pStr = %p\n",pStr+1);//输出次地址
		printf("pStr = %c\n",*(pStr+1));//输出次字符
		printf("pStr = %p\n",pStr+2);
}

返回指针的函数

C语言 允许函数的返回值是一个指针(地址),这样的函数称为指针函数。

指针函数注意事项和细节

1)用指针作为函数返回值时需要注意,函数运行结束后会销毁在它内部
定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的
指针不能指向这些数据
2)函数运行结束后会销毁该函数的所有局部数据,这里所谓销毁并不是将
局部数据所占用的内存全部清零,而是程序放弃对它的使用权限,后面的代
码可以使用这块内存(此内存被开辟在栈中,后面的函数即可能会使用)
3)C语言不支持在调用函数时返回局部变量的地址,如果确实有这样的需求
,需要定义局部变量为static变量(这里static变量会被存放在静态数据区,
不会被改变故即使栈中函数数据销毁,对static变量也没有任何影响)
#include<stdio.h>

int *func(){
	int n = 100;//局部变量,在func返回时,就会销毁
	return &n;
}

int main(){
	int* p = func();//返回指针
	int n;
	printf("~~~~~~~~~~~~~~");
	//函数后边跟个其他函数就会占用栈中销毁func()数据后的内存,从而输出不了100
	//如果没有任何函数跟在后面,那么仍然可以输出100,因为数据只是使用权限没有了,并没有清零
	n = *p;
	printf("\nvalue = %d\n",n);//是否输出100?不一定
	return 0;
}

函数指针

基本介绍

1)一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被
转换为函数所在的内存区域的首地址,这和数组名非常类似。
2)把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指
针变量就可以找到并调用该函数。这种指针就是**函数指针**

函数指针定义

returnType(*pointerName)(param list);
1)returnType 为函数指针指向的函数返回值类型
2)pointerName 为函数指针名称
3)param list 为函数指针指向的函数的参数列表
4)参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称
5)注意()的优先级高于  *  ,第一个括号不能省略,如果写作	returnType
*pointerName(param list),它表明函数的返回值类型为returnType * 
#include<stdio.h>
//说明
//1.max 函数
//2.接受两个int,返回较大数
int max(int a,int b){
	return a>b?a:b;
}

int main(){
	int x,y,maxVal;
	
	//说明 函数指针
	//1.函数指针的名字 pmax
	//2.int 表示该函数指针指向的函数是返回int类型
	//3.(int,int)表示 该函数指针指向的函数形参是接受两个int
	//4.在定义函数指针时,也可以写上形参名 int(*pmax)(int x,int y)=max;

	int(*pmax)(int,int) = max;
	printf("Input two numbers");

	scanf("%d %d",&x,&y);
	//(*pmax)(x,y)通过函数指针去调用 函数max
	maxVal = (*pmax)(x,y);
	printf("Max value:%d pmax=%p pmax本身的地址=%p\n",maxVal,pmax,&pmax);
}

回调函数

1)函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通
过函数指针调用的函数
2)简单的讲:回调函数是由别人的函数执行时调用你转入的函数(通过函
数指针完成)

应用举例

#include<stdio.h>
#include<stdlib.h>
//回调函数
//1.int(*f)(void)
//2.f 就是函数指针,它可以接收的函数是(返回int,没有形参的函数)
//3.f 在这里被initArray 调用,充当了回调函数角色
void initArray(int *array,int arraySize,int(*f)(void)){
	int i;
	//循环 10
	for(i=0;i<arraySize;i++){
		array[i] = f();//通过函数指针调用了 getNextRandomValue函数
	}
}

//获取随机值
int getNextRandomValue(void){
	return rand();//rand 系统函数,会返回一个随机整数
}

int main(){
	int myarray[10],i;//定义一个数组和 int

	//说明
	//1.调用initArray函数
	//2.传入了一个函数名getNextRandomValue(地址),需要使用函数指针接受
	initArray(myarray,10,getNextRandomValue);

	//输出赋值后的数组
	for(i=0;i<10;i++){
		printf("%d ",myarray[i]);
	}
	printf("\n");
	return 0;
}

回调函数注意事项

1)p是指向函数的指针变量,它只能指向函数的入口处而不可能指向函数中间的某一条
指令,因此不能用*(p+1)来表示函数的下一条指令。
2)如果要用指针调用函数,就必须先使用指针变量指向该函数。如:p = max 
3)在给函数指针变量赋值时,只须给出函数名而不必给出参数,例如:
p = max;                //将函数的入口地址赋给p
因为是将函数入口地址赋给p,而不牵涉实参与形参的结合问题。如果写成 p = max(a,b);
就错了。p = max(a,b)的作用是将调用max函数所得到的函数值赋给p,而不是将函数入
口地址赋给p
4)用函数指针变量调用函数时,只须将 (*p) 代替函数名即可 (p为指针变量名),在 (*p) 
之后的括号中根据需要写上实参。例如:c = (*p)(a,b);
5)用函数名调用函数,只能调用所指定的一个函数,而通过指针变量调用函数比较灵
活,可以根据不同情况先后调用不同的函数。(在一个程序中,一个指针变量可以先后
指向不同类型的不同函数)

指针的注意事项和细节

1)指针变量存放的是地址,从这个角度看指针的本质就是地址。
2)变量声明的时候,如果没有确切的地址赋值,为指针变量赋给一个NULL值是好的编
程习惯。
3)赋给NULL值的指针被称为空指针,NULL指针是一个标准库<stdio.h>中的值为零的常
量 #define  NULL  0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值