小白计算机c语言备考(九)指针

回顾

      上一章我们对宏定义有了基本的了解,刚开始的确会觉得这是一个很抽象的概念,但在我们逐渐练习中会有更深入的理解,学习它的确会觉得这是一个很难的东西,根本就不知道这是什么玩意,我就更需要花费时间去学习

学习内容

九、指针 

1. 地址与指针变量的概念,地址运算符与间址运算符。 

2.一维、二维数组和字符串的地址以及指向变量、数组、字符串、函数、结构体的指针变量的 定义。通过指针引用以上各类型数据。 

3.用指针作函数参数。 

4.返回地址值的函数。 

5.指针数组,指向指针的指针。 

学习章节

(一)地址与指针变量的概念,地址运算符与间址运算符

学习指针我们要先认识指针

什么是指针

指针就是内存地址

我们打一个比方

咱们可以把内存想象成一个大旅馆,每个房间都有一个编号(内存地址)。而指针呢,就像是一个能记住房间编号的小纸条。
 
通过这个小纸条(指针),我们就能找到对应的房间(内存地址),然后对房间里的东西(数据)进行操作。

指针的作用

后面有代码练习分析作用

1.操作其他函数中的变量

2.函数返回多个值

3.函数的结果和计算状态分开

4.方便操作数组和函数

(二)一维、二维数组和字符串的地址以及指向变量、数组、字符串、函数、结构体的指针变量的 定义。通过指针引用以上各类型数据 

指针变量的定义

存储内存地址的变量

格式

数据类型  *  变量名

图片

利用指针获取变量的数据

代码如下

//利用指针获取变量的数据
#include<stdio.h>
int main(){
	int a=10;
	//1.定义一个指针指向变量啊
	int *p=&a;
	//2.指针获取变量的数据
	printf("%d\n",*p);
	//指针修改数据
	*p=100;
	printf("%d\n",a);
	
	printf("%d\n",*p);
	return 0;
	
}

数组指针

就是指向数组的指针

利用指针遍历数组

//利用指针遍历数组  (数组指针)

#include<stdio.h>
int main(){
	
	int arr[]={12,3,4,67,89,78,67,56,45};
	int len=sizeof(arr)/sizeof(int);
	//用指针去获取数组
	
	int *p1=arr;
	int *p2=&arr[0];
	//这里都可以获取数组的首地址
	printf("%p\n",p1);
	printf("%p\n",p2);
	
	//利用指针遍历数组的每一个元素
	for(int i=0;i<len;i++)
{
	printf("%d\n",*p1++);
}

	return 0;
}

注意细节

arr参与计算的时候就是数组的第一个元素

用索引的方式遍历二维数组

代码如下

//用索引的方式遍历二维数组

#include<stdio.h>
int main(){
	int arr[3][5]={
		{9,8,7,6,5},
		
		{99,83,74,56,54},
		
		{91,82,74,66,58},
		
	};
	//其实这个3就代表了3个一维数组   5代表一个一维数组里面有几个数
	for(int i=0;i<3;i++){
	for(int j=0;j<5;j++){
		printf("%d\t", arr[i][j]);
		
	}
	printf("\n");
	
	}
	
	return 0;
	
	
}



*/




//如果二维数组的长度不一样


#include<stdio.h>
int main(){
	int  arr1[3]={1,2,3};
	int   arr2[5]={1,2,3,4,5};
	int  arr3[6]={1,2,3,4,5,6,7,8,9};
	//计算每一个数组的长度
	int len1=sizeof(arr1)/sizeof(int);
	int len2=sizeof(arr2)/sizeof(int);
	int len3=sizeof(arr3)/sizeof(int);
	//定义一个数组,装所有数组的长度
	int   lenarr[3]={len1,len2,len3};
	//用指针表示
	int*arr[3]={arr1,arr2,arr3};
	for(int i=0;i<3;i++){
		for(int j=0;j<lenarr[i];j++){
			printf("%d ",arr[i][j]);
			
			
		}
			printf("\n");
	}

}

 注意代码不能直接运行,有注释符号

用指针遍历二维数组

//用指针遍历一个二维数组

#include<stdio.h>
int main(){
	
	
	int  arr[3][5]={
		{1,2,3,4,5},
		{22,33,44,55,66},
		{33,44,55,66,77},
	};
	
	//获取二维数组的指针
	int (*p)[5]=arr;
	for(int i=0;i<3;i++){
		for(int j=0;j<5;j++){
			printf("%d ",*(*p+j));
		}
		printf("\n");
		p++;
		
	}
	return 0;
}

//第二个方法是获取指针的方式不一样      int **p=arr           其他都一样 

指针获取字符串

两种格式

方法一    char str[4]="abc"

注意     有结束标记         内容可以修改  

方法二    char *str="abc"

注意       有结束标记\n       只能读,内容不能修改            因为存的是地址会复用

太抽象我们可以代码理解

//用指针获取字符串
#include<stdio.h>
int main()
{
	
	//方法一
	char str1[4]="abc";//{'a','b','c','\0'}   所以要定义为4
	printf("%s\n",str1);
	//可以修改
	str1[0]='w';
	printf("%s\n",str1);
	
	//方法二   指针字符串
	
	char* str2="abcd";//{'a','b','c','d','\0'} 
	//注意不能修改   str2[0]='q'    
	printf("%s\n",str2);
	//字符串就是地址可以复用不会改变
	char* str3="abcd";
	printf("%p\n",str2);
	printf("%p\n",str3);
	return 0;
	
}


我们尝试用键盘输出一个字符串并进行遍历

//用键盘输出字符串并进行遍历

#include<stdio.h>
int main(){
	
	char str[100];
	printf("请输入一个字符串:\n");
	scanf("%s",str);
	printf("接受到的字符串为: %s\n",str);
	
	//用指针遍历
	char* p=str;
	while(1){
		//用指针获取字符串的每一个字符,直到遇到\n
		char c=*p;
		if(c==0){
			break;
		}
		printf("%c\n",c);
		p++;
	}
	
	
	return 0;
}

(三)用指针作函数参数  函数指针

函数指针

格式     返回值类型 (*指针名) (形参列表)

作用:利用函数指针,可以动态的调用指针

代码          里面有函数的形参

//函数指针
#include<stdio.h>
void  method1(){
	printf("method1\n");
}

int  method2(int num1,int num2){   //这里是形参
	printf("method2\n");
	return  num1+num2;
}
int main(){
	//定义两个指针指向两个函数
	void (*p1)()=method1;   
	int (*p2)(int,int)=method2;    
	//利用函数指针去调用函数
	p1();
	int num=p2(11,22);
	printf("%d\n",num);
	return 0;
	
}

这里我们在来稍微比较难的东西,真的有点抽象,就是用指针去存相同类型的函数,这个也是函数指针,然后去选择函数进行运算

题目:键盘输入两个数,然后选择调用的函数用函数指针

1.加     2.减     3.乘      4. 除

//题目:键盘输入两个数,然后选择调用的函数用函数指针

//1.加2.减3.乘 4. 除

//函数指针
#include<stdio.h>

int add(int num1,int num2){
	return num1+num2;
}
int subtract(int num1,int num2){
	return num1-num2;
}
int multiply(int num1,int num2){
	return num1*num2;
}
int divide(int num1,int num2){
	
	return num1/num2;
}
int main(){
	int (*arr[4])(int,int)={add,subtract,multiply,divide};
	printf("请输入两个数字:\n");
	int num1;
	int num2;
	scanf("%d%d",&num1,&num2);
	int choose;
	printf("请输入一个数字你要进行的计算(1.加2.减3.乘 4. 除): \n");
	scanf("%d",&choose);
	int res=(arr[choose-1])(num1,num2);
	printf("%d",res);
	return 0;
	
	
	
}

(四)返回地址值的函数,指针的运算

指针的运算

我们可以从打印地址开始学起

打印指针就是在打印地址

指针的运算规则

指针移动了一次,走了多少个字节

char :1          short:2      int :4     long   :4      longlong :8

如下代码

#include<stdio.h>
int main(){
	int a=10;
	int*p=&a;
	printf("%p\n",p);
	printf("%p\n",p+1);
	printf("%p\n",p+2);
	return 0;
	
}

指针加一或者指针减一 就是内存地址往前移动或者往后移动一个步长

步长和数据类型有关,上面有     这里的p是打印地址哦,别看错了

学习用指针地址获取值

#include<stdio.h>
int main()
{
	//指针和整数进行加减操作(每次移动一个步长)
	//指针和指针进行减操作(间隔步长)
	int  arr[]={1,2,3,4,5,6,7,8,9};
	int *p1=&arr[0];
	
	//通过指针获取数据
	printf("%d\n",*p1);
	printf("%d\n",*p1+1);//2
	//获取索引6的地址
	int *p2=&arr[6];
	//计算p1和p2间隔的步长
	printf("%d\n",p2-p1);
	printf("%p",p1);
	printf("%p",p2);
	return 0;
}




 注意细节

1.指针和整数不要进行乘除操作

2.指针和指针之间不进行加乘除操作

否则就没有意义

(五)指针数组,指向指针的指针

什么是指针数组

存放指针的数组

例如                     int  *arr[2]={ arr1,arr2};

比较一下数组指针和指针数组

指向指针的指针就是二级指针

如下代码

//二级指针的作用
#include<stdio.h>
int main(){
	int a=10;
	int b=20;
	//定义的是一级指针
	int*p=&a;
	//定义二级指针    
	//这个p是指向的,记得不要重名哦
	int**pp=&p;
	//作用一  :二级指针可以更改一级指针的地址
	//这里有点绕,因为二级指针的引用就是一级指针
	*pp=&b;
	// 作用二:利用二级指针获取变量的数据
	printf("%d\n",**pp);
	printf("%p\n",&a);
		printf("%p\n",&b);
		printf("%p\n",p);
		
		return 0;
	
	
}

代码练习

练习一   定义两个变量,用指针交换地址,使用交换函数   (指针的作用一)

void swap(int *p1,int *p2){
	int temp=*p1;
	*p1=*p2;
	*p2=temp;
}
#include<stdio.h>
int main(){
	
	int a=10;
	int b=50;
	printf("调用swap之前的:%d,%d\n",a,b);
	swap(&a,&b);
		printf("调用swap之后的:%d,%d\n",a,b);
	return 0;
	
}

练习二      利用函数返回多个值,求最值    (指针的作用二)

#include<stdio.h>
//利用函数指针求最大值
void  getmaxmin(int arr[],int len,int*max,int *min){
	*max=arr[0];
	for(int i=1;i<len;i++){
		if(arr[i]>*max){
			*max=arr[i];
		}
		
	}
     *min=arr[0];
	
	for(int i=1;i<len;i++){
		if(arr[i]<*min){
			*min=arr[i];
			
		}
	}
}


int main(){
	int arr[]={1,2,3,3,4,5,6,7,8,9};
	int len=sizeof(arr)/sizeof(int);
	int max=arr[0];
	int  min=arr[0];
	
	getmaxmin(arr,len,&max,&min);
	printf("最大值为:%d,最小值为%d\n",max,min);
	
	
	
	
	return 0;
	
}

练习三     (指针的作用三)

函数的结果和状态分开
定义一个函数,将两个数相除,并获取余数

//函数的结果和状态分开
//定义一个函数,将两个数相除,并获取余数


#include<stdio.h>

int getyushu(int num1,int num2,int*res){
	if(num2==0){
		return 1;
	}
	*res=num1%num2;
	return 0;
}
int main(){
	int a=10;
	int b=3;
	int res=0;
	
	int flag=getyushu(a,b,&res);
	if(!flag){
		printf("余数为%d\n",res);
		return 0;
		
	}
	
}

练习四   键盘输入字符串,指针遍历

//用键盘输出字符串并进行遍历

#include<stdio.h>
int main(){
	
	char str[100];
	printf("请输入一个字符串:\n");
	scanf("%s",str);
	printf("接受到的字符串为: %s\n",str);
	
	//用指针遍历
	char* p=str;
	while(1){
		//用指针获取字符串的每一个字符,直到遇到\n
		char c=*p;
		if(c==0){
			break;
		}
		printf("%c\n",c);
		p++;
	}
	
	
	return 0;
}

练习五   遍历二维的字符串数组用指针 

//字符串数组
//用指针去遍历字符串就行
//这个是二维数组

#include<stdio.h>

int  main(){
	char  strArr[3][20]={
		
		"zhangzhang",
		"lili",
		"xiaoxiao"
	};
	
	
	//方法一
	//遍历二维数组
	for(int i=0;i<3;i++){
		//表示二维数组的索引
		char *str=strArr[i];
		printf("%s\n",str);
	}
		printf("===============================\n");
		
		//方法二  5个字符串的指针,放到一个数组
		char  *strArr2[3]={
			
			"zhangzhang",
					"lili",
					"xiaoxiao"
		};
		
		for(int i=0;i<3;i++){
			char*str=strArr2[i];
			printf("%s\n",str);
		}
		return 0;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值