衣带渐宽终不悔,为“指针”消得人憔悴(二)

进阶篇——二级指针

二级指针也是一个普通的指针变量,只是它里面保存的值是另外一个一级指针的地址

定义:
int a = 888;
int *a1 = &a; //1 级指针,保存 a 的地址
int **a2 = &a1; //2 级指针,保存 a1 的地址,a1 本身是一个一级指针变量
在这里插入图片描述
    

二级指针的用途:

(1)普通指针可以将变量通过参数“带入”函数内部,但没办法将内部变量“带出”函数

在这里插入图片描述

(2)二级指针不但可以将变量通过参数,进入函数内部,也可以将函数内部变量 “带出”到函 数外部

#include <stdio.h> 
#include <stdlib.h> 

void boy_home(int **meipo){ 
	static int boy = 23; 
	*meipo = &boy; 
}

int main(void){ 
	 int *meipo = NULL; 
	 boy_home(&meipo); 
	 printf("boy: %d\n", *meipo); 
	
	system("pause"); 
	return 0; 
}

在这里插入图片描述

    

多级指针的定义、使用

可以定义多级指针指向次一级指针
  比如:
     int guizi1 = 888;
     int *guizi2 = &guizi1; //普通指针
     int **guizi3 = &guizi2; //二级指向一级
     int ***guizi4 = &guizi3; //三级指向二级
     int ****guizi5 = &guizi4; //四级指向三级
     // 有完没完。。。

#include <stdio.h> 
#include <stdlib.h> 

int main(void){ 
	int guizi1 = 888; 
	int *guizi2 = &guizi1; //普通指针 
	int **guizi3 = &guizi2; //二级指向一级 
	int ***guizi4 = &guizi3; //三级指向二级 
	int ****guizi5 = &guizi4; //四级指向三级 
	
	printf("柜子 2 拿枪: %d\n", *guizi2); 
	printf("柜子 3 拿枪: %d\n", **guizi3); 
	printf("柜子 4 拿枪: %d\n", ***guizi4); 
	printf("柜子 5 拿枪: %d\n", ****guizi5); 
	
	system("pause"); 
	return 0; 
}

    

指针和数组的纠缠

(1)数组完全可以使用指针来访问, days[3] 和 * (days+3) 等同

#include <stdio.h> 
#include <stdlib.h> 


int main(void) { 
	int days[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 
	int index = 0; 
	for (index = 0; index < 12; index++){ 
	**加粗样式**	//数组表示法 
		//printf("Month %2d has %d days.\n", index+1, days[index]); 

		//指针表示法 
		printf("Month %2d has %d days.\n", index+1, *(days+index));
	} 
	

	
	system("pause");
	return 0; 
}

    
(2)存储指针的数组

定义: 类型 * 指针数组名[元素个数] ;

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
	int girls[4][3]={{173, 158, 166}, 
					 {168, 155, 171}, 
					 {163, 164, 165}, 
					 {163, 164, 172}}; 
	
	int *qishou[2];//定义一个有两个元素的指针数组,每个元素都是一个指针变量 
	
	if(girls[0][0] > girls[0][1]){ 
		qishou[0] = &girls[0][0]; 
		qishou[1] = &girls[0][1]; 
	}else {
		qishou[0] = &girls[0][1]; 
		qishou[1] = &girls[0][0]; 
	}
	
	for(int i=2; i<12; i++){ 
	//girls[i/3][i%3] 
		if(*qishou[1] >= girls[i/3][i%3]){ 
			continue; 
		}
	
	//候选者高于第二位棋手候选女兵 //1.候选者比"冠军"矮 
		if(girls[i/3][i%3] <= *qishou[0]){ 
			qishou[1] = &girls[i/3][i%3]; 
		}else { //2.候选者比"冠军"高 
			qishou[1] = qishou[0]; 
			qishou[0] = &girls[i/3][i%3]; 
		} 
	}
	
	printf("最高女兵的身高: %d , 次高女兵的身高: %d\n", *qishou[0], *qishou[1]); 
	
	system("pause");
	return 0}

    

指针和二维数组

1. 指向数组的指针
int (*p)[3]; //定义一个指向三个成员的数组的指针
访问元素的两种方式:
数组法: (*p)[ j ]
指针法: * ((*p)+j)

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
	
	/*据同学们报告,A 栋学生楼有学生用高倍望眼镜偷看别人洗澡, 
	宿管办领导决定逐个宿舍排查,
	得到的线报是 A0 到 A3 宿舍的 某个子最矮的男生。 */ 
	
	int A[4][3]={{173, 158, 166}, 
				 {168, 155, 171}, 
				 {163, 164, 165}, 
				 {163, 164, 172}}; 
	
	int (*p)[3]; //定义一个指向三个成员的数组的指针 
	int * boy = NULL; 
	p = &A[0]; 
	
	//第一种 数组下标法 
	/*for(int i=0; i<4; i++){ 
		for(int j=0; j<3; j++){ 
			printf(" %d", (*p)[j]); //(*p) 等同于 a[0] ,a[0][0]等同于 (*p)[0]
		}
	printf("\n"); 
	p++; 
	}*/ 
	
	boy = &(*p)[0]; //boy = (*p); 
	
	//第二种 指针访问法 //int a[3]; int * p ; p = a; 数组成员: *p *(p+1) *(p+2) 
	for(int i=0; i<4; i++){ 
		for(int j=0; j<3; j++){
			printf(" %d", *((*p)+j)); 
			if( *boy > *((*p)+j)){ 
				boy = (*p)+j; 
			} 
		}
		printf("\n"); 
		p++; 
	}
	printf("偷窥的学生是: %d\n", *boy); 
	
	system("pause"); 
	return 0; 
}

    
使用普通指针访问二维数组

int A[4][3];
int *p; //定义一个指针
p = A[0];
或者 p=&A[0][0];
访问元素的两种方式:

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
	/*据同学们报告,A 栋学生楼有学生用高倍望眼镜偷看别人洗澡, 
	宿管办领导决定逐个宿舍排查,
	得到的线报是 A0 到 A3 宿舍的 某个子最矮的男生。 */ 
	
	int A[4][3]={{173, 158, 166}, 
				 {168, 155, 171}, 
				 {163, 164, 165}, 
				 {163, 164, 172}}; 
	
	int *boy = NULL;//坏男孩 
	int *p =NULL; //定义指针,用以遍历二维数组 
	
	//p = A[0]; 
	p = &A[0][0]; 
	boy = p; 
	
	for(int i=1; i<4*3; i++,p++){
		if(*boy > *p){ //*p 可以替换成 A[i/3][i%3] 
			 boy = p; 
		} 
	 }	
	
	 printf("偷窥的学生是: %d\n", *boy); 
	
	//2.根据指针计算下标 
	int pos = boy - A[0]; 
	
	printf("index: %d\n", pos); 
	printf("位于 A[%d] 宿舍\n", pos/3); 
	printf("是第 %d 个成员\n", pos%3); 
	
	system("pause"); 
	return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值