指针一点理解

指针用来干什么?

  1. 需要传入较大的数据时用作参数
  2. 传入数组后对数组操作
  3. 函数返回不止一个结果
    1、需要用函数来修改不止一个变量,比如swap
  4. 需要动态申请内存…
指针场景一:交换二个变量的值

代码测试:

#include<stdio.h>
int main(){
	void swap(int *a,int *b);
	//指针就是保存地址的变量 
	//指针场景一交换二个变量的值
	int a=5;
	int b=6;
	swap(&a,&b);//把a,b的地址传进去 
	printf("a=%d\n",a);
	printf("b=%d\n",b);
	return 0; 
	 
	//指针场景二函数返回多个值,某些值就只能通过指针返回 
} 
void swap(int *a,int *b){//指针里面存的就是变量的地址,其实是个十六进制的数 
	int t=*a;
	*a=*b;
	*b=t;
}
指针场景二:函数返回多个值时,某些值就只能通过指针返回

代码测试:

//指针场景二:函数返回多个值时,某些值就只能通过指针返回 
#include<stdio.h>
void retminmax(int length,int minmax[],int *max,int *min); 
int main(){
	//同时返回一个数组中的最大值和最小值
	int max;
	int min;
	int minmax[]={1,2,3,4,5,6,7,8,9}; 
	retminmax(sizeof(minmax)/sizeof(minmax[0]),minmax,&max,&min);//传进去数组名就可以了 
	printf("max=%d min=%d",max,min);
	
} 
//这个函数并没有返回值,但是调用这个函数就可以把最大值,和最小值通过指针给带出来
//把要接收结果的变量的地址给传进去,让函数在里面把这些变量给填好 ,把值传回来 
void retminmax(int length,int minmax[],int *max,int *min){
	int i;
	for(i=0;i<length;i++){
		if(minmax[i]>*max){
			*max=minmax[i];
		}
		if(minmax[i]<*min){
			*min=minmax[i];
		} 
	}
 
}

指针应用场景三:函数返回运算的状态,通过指针返回
常用的套路就是让函数返回特殊的或者不属于正常范围的值,来表示出错 -1或者0
但是当任何数值都是有效的可能结果时,就得分开返回了 
	@return 如果除数为0就返回0,除数不为0,就返回1 

代码测试:


#include<stdio.h>
int divisor(int a1,int a2,int *result);
int main(){
	int a=6;
	int b=2;
	int c=0;	
	if(divisor(a,b,&c)==1){
		printf("a=%d b=%d c=%d",a,b,c);
	}
	
} 
int divisor(int a1,int a2,int *result){
	int ret=1;
	if(a2==0){
		return ret=0;
	}else{
		*result=a1/a2;//通过c地址,把c变量的内容给更改了,
	}
	return ret;
}

常犯的错误:定义了指针变量,还没有让指针指向任何的值就开始使用指针了
int *p;
*p=12;
这是错误的,这二句话表达了,刚开始创建了一个指针变量,
但是它并没有指向任何一个值,下一句是让指针变量指向一个值为12的地方,这个时候指针就会随便乱指 。

指针和数组

函数参数列表中的数组实际上就是指针
	1sizeof(a)==sizeof(int *) a是一个数组
	2、但是可以用数组的运算符[]进行运算 
  数组变量本身表达地址,所以
    1int a[10]; int *p=a;//无须用&取地址
	2、但是数组的单元表达的是变量,需要用&取地址
	3、a==&a[0] 
  []可以对数组做,也可以对指针做
    1、p[]<==>a[]
  运算符可以对指针做,也可以对数组做:
  	1*a=25;
  数组变量是const的指针,所以不能被赋值,一旦被初始化,就不能被改变 
  	1int a[]<==>int *const a=..... 

代码测试:


#include<stdio.h>
void retminmax(int length,int minmax[],int *max,int *min); 
int main(){
	//同时返回一个数组中的最大值和最小值
	int max;
	int min;
	int minmax[]={1,2,3,4,5,6,7,8,9}; 
	retminmax(sizeof(minmax)/sizeof(minmax[0]),minmax,&max,&min);//传进去数组名就可以了 
	printf("minmax=%d",minmax[4]);//看一下第5个元素有没有改变
	printf("\n"); 
	printf("max=%d min=%d",max,min);
	
	
} 
void retminmax(int length,int *minmax,int *max,int *min){//把数组minmax[]改成了*minmax依然可以运行 
	int i;
	printf("max sizeof(minmax)=%lu\n",sizeof(minmax));
	printf("max minmax=%p\n",minmax);
	minmax[4]=520;
	for(i=0;i<length;i++){
		if(minmax[i]>*max){
			*max=minmax[i];//还是用数组进行运算的 
		}
		if(minmax[i]<*min){
			*min=minmax[i];
		} 
	}
 
}

一、转换
总可以把一个非const的值转换成constvoid f(const int *x);
	int a=5;
	f(&a);//ok
	const int b=a;
	f(&b);//ok,传入的是一个const当然也是可以的 
	b=a+1;//error 
用来干什么呢?
 当要传递的参数的类型比地址大的时候,这是常用的手段;
 既可以用比较少的字节数传递值给参数,又能避免函数对外面的变量的修改 
 
 二、const数组
 保护数组值
 1、因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
 为了保护数组不被函数破坏,可以设置参数为const
    int sum(const int a[],int length); 
    
 三、指针运算
/**一、转换
总可以把一个非const的值转换成const的
	void f(const int *x);
	int a=5;
	f(&a);//ok
	const int b=a;
	f(&b);//ok,传入的是一个const当然也是可以的 
	b=a+1;//error 
用来干什么呢?
 当要传递的参数的类型比地址大的时候,这是常用的手段;
 既可以用比较少的字节数传递值给参数,又能避免函数对外面的变量的修改 
 
 二、const数组
 保护数组值
 1、因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
 为了保护数组不被函数破坏,可以设置参数为const
    int sum(const int a[],int length); 
    
 三、指针运算 
*/ 
#include<stdio.h>
//指针加法:p和p+1 ,意味着移到下一个单元,加上的是那个sizeof(那个类型) 
//指针减法的意思是:这二个地址的差除以这个类型的sizeof,也就是说这二个指针之间可以放几个这种类型的sizeof 
/*
解释*p++: *的运算符比++的运算符高
  1、取出p所指的那个数据来,完事之后顺便把p移到下一个位置上去
  2、常用于数组类的连续的空间操作
  3、在某些cpu上,这可以直接被翻译成一条汇编指令  
   */ 
int main(){
	//------------char型-------------------
	char ac[]={1,2,3,4,5,6,7};
	char *p=ac;
	char *p1=&ac[3]; 
	//*p<==>ac[0];
	//*(p+1)<==>ac[1];//要有括号 
	//*(p+n)<==>ac[n];//一回事 
	printf("p=%p\n",p);
	printf("p+1=%p\n",p+1);
	printf("*p=%d\n",*p); //*p=1
	printf("*(p+1)=%d\n",*(p+1)); //*(p+1)=2
	printf("---------------------------------------\n");
	printf("p1=%d\n",p1);
	printf("p=%d\n",p);
	//printf("p1=%p\n",p1);
	printf("p1-p=%d\n",p1-p);
	/*
	p1=6487539
	p=6487536
	p1-p=3//差了3个char 
	*/
	printf("---------------------------------------\n");
	//------------int型---------------------- 
	int ac1[]={0,1,2,4,5,6,7};
	int *q=ac1;
	int *q1=&ac1[3];//放的是地址 
	printf("q=%p\n",q);
	printf("q+1=%p\n",q+1);
	printf("*q=%d\n",*q); //*q=0
	printf("*(q+1)=%d\n",*(q+1)); //*(q+1)=1
	printf("---------------------------------------\n");
	printf("q1=%d\n",q1);
	printf("q=%d\n",q);
	printf("q1-q=%d\n",q1-q);
	/*
	q1=6487516
	q=6487504
	q1-q=3//差了3个int 
	*/
	/*
	运行结果: 
	  p=000000000062FE00
	  p+1=000000000062FE01
	  char型:加1 
	  q=000000000062FDE0
	  q+1=000000000062FDE4
	  int型:加4 
	*/
	
} 








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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值