进阶篇——二级指针
二级指针也是一个普通的指针变量,只是它里面保存的值是另外一个一级指针的地址
定义:
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;
}