C语言学习 通过代码学习理解指针

 首先是简单的定义基本类型的指针和二级指针的方法

指针就是保存地址的一个变量

 

#第一篇代码

如何定义指针 以及 * &的理解

#include <stdio.h>
/* 定义一级指针 二级指针  */
int main(void)
{
	
	//定义int char型变量
		int num = 1;
		char ch = 'a';
	//定义int char型指针,指针要和变量类型一致,
	//后面写NULL 让他们指向空地址,避免成为野指针
		int *num_p = NULL;
		char *ch_p = NULL;
	//用取地址符号&让指针分别指向num 和 ch 的地址
		num_p = &num;
		ch_p = &ch;
	//打印指针    *号的作用  
	//num_p里面放着的是num的地址 *num_p == *(&num), *和&相抵消 得num的值
		printf("num = %d\n",num);		//打印num的值
		printf("num_p = %p\n",num_p);	//打印num_p上储存的num的地址 %p用来打印地址
		printf("num_p = %d\n",*num_p);	//打印num_p解地址之后的值
		
		printf("ch_p = %c\n",ch);
		printf("ch_p = %p\n",ch_p);
		printf("ch_p = %c\n",*ch_p);
		
		printf("\n");
	//二级指针
	
		int **num_pp = NULL;
		char **ch_pp = NULL;
		
		num_pp = &num_p;
		ch_pp = &ch_p;
		
		//二级指针num_pp里面放着的是一级指针num_p的地址 *num_pp == *(&(&num)), *和&相抵消 得num的值
		printf("num_pp = %p\n",num_pp);	//打印num_pp上储存的num_p的地址 %p用来打印地址
		printf("*num_pp = %p\n",*num_pp);	//打印num_pp解地址之后的值,也就是num的地址
		printf("**num_pp = %d\n",**num_pp);	//打印num_pp解两次址之后的值,也就是num的值
		
		printf("ch_pp = %p\n",ch_pp);
		printf("*ch_p = %p\n",*ch_pp);
		printf("**ch_p = %c\n",**ch_pp);
		
  
		
		
		
		
		
			
		return 0;

	
}

 

 

 #第二个代码

数组指针和指针数组的区别

数组指针是一个指向数组的指针,通常指向二维数组 可以用来当作一个二维数组的行地址

指针数组则是包含着多个相同类型的指针

 

 

#include <stdio.h>
/*数组指针,与指针数组*/
int main(void)
{
	//定义一个二维数组
	int num[3][4] = {{1,3,5,7}, {9,11,13,15}, {17,19,21,23}};
	//定义一个数组指针,也可以称为是数组的行指针。
	//将数组指针指向空地址 免得产生野指针 
	//数组指针的[]内要填写偏移的地址量,例如我们指向的num二维数组
	//数组可以看成有三行四列 ,那偏移量就是后面的数字

	int (*num_p)[4] = NULL;
	//int (*num_p)[4] []中的4表示偏移量
	//将数组指针指向num的首元素地址 
	num_p = num;
	//用%p 打印num_p num_p+1 num_p+2的地址 
	printf("*(num_p+0)的值为 %p\n",*(num_p+0));
	printf("*(num_p+1)的值为 %p\n",*(num_p+1));
	printf("*(num_p+2)的值为 %p\n",*(num_p+2));
	printf("\n");
	
	//打印num_p num_p+1 num_p+2指向的值
	printf("**(num_p+0)的值为 %d\n",**(num_p+0));//**(num_p+0) == num[0][0] 的值
	printf("**(num_p+1)的值为 %d\n",**(num_p+1));//**(num_p+1) == num[1][0]	的值 
	printf("**(num_p+2)的值为 %d\n",**(num_p+2));//**(num_p+2) == num[2][0] 的值
	printf("\n");

	//定义一个指针数组 指针数组就是 数组的元素是由指针组成的
	//下面定义一个含有三个int型指针的数组
	int *num_pn[3] = { NULL };
	num_pn[0] = num;        //这里不需要&的原因是因为 数组名本身就代表着整个数组的首元素地址
							 //但是需要注意 这里的num是一个二维数组 他的首元素是一个整型数组而并非整型变量;
	num_pn[1] = num[1];	  	 //这里也不需要&因为num[1]是看作一个数组,名字为地址
	num_pn[2] = &num[1][1];  //这里就需要&啦,因为这代指的是一个整型变量了
	
	//打印地址出来 (地址是十六进制数字)
	//可以看出num_pn[0]与 num_pn[1]相差 4个int类型,也就是十六个字节
	//可以看出num_pn[1]与 num_pn[2]相差 1个int类型,也就是四个字节
	printf("num_pn[0]的值为 %p\n",num_pn[0]);
	printf("num_pn[1]的值为 %p\n",num_pn[1]);
	printf("num_pn[2]的值为 %p\n",num_pn[2]);
	printf("\n");
	//也可以打印出他们的值来进行理解
	printf("*num_pn[0]的值为 %d\n",*num_pn[0]);  //输出num[0][0]的值
	printf("*num_pn[1]的值为 %d\n",*num_pn[1]);  //输出num[1][0]的值
	printf("*num_pn[2]的值为 %d\n",*num_pn[2]);	 //输出num[1][1]的值
	printf("\n");
	
	
	

		return 0;


}

 

#第三篇代码

指针的强制转换

通过int类型指针来了解

也可以用其他类型试试

#include <stdio.h>
/*指针的强制转换*/
int main(void)
{
	int arr[5] = {1,2,3,4,5};
	printf("arr = %p\n",arr);
	printf("(int)arr = %x\n",(int)arr);
	printf("(int)arr + 1 = %x\n",(int)arr + 1);
	
	//强制转换成整数型指针 
	/*
	int *p1 = NULL;
	int *p2 = NULL; 
	P1 = (int *)(&arr + 1);
	P2 = (int *)((int)arr +1);
	这样写会弹出
	 undeclared (first use in this function)
	 原因可能是因为 没有标准库(c99)
	*/
     int *p1 = (int *)(&arr + 1);   
	int *p2 = (int *)((int)arr +1);

	  
	//
	printf("%x\n",p1[-1]);     	// 输出 5
	printf("%x\n",*p2);  		// 输出 2000000
	
	/*
	大端序
	高地址存地位数据,低地址存高位数据
	小端序
	高地址存高位数据,低地址存地位数据
	
	 01 00 00 00
	 02 00 00 00
	 
	 得到 00 00 00 02 
	 
	 输出时 为 02 00 00 00 
	 
	 前面的0省略不打印
	*/
	
	
	
	
		return 0;
}

 #第四篇代码

指针的指向问题 

同样以int类型指针为例子

定义指针指向一维数组 和 二维数组的不同之处

#include <stdio.h>
/*int型数组指针,int型指针与数组的指向关系*/
int main(void)
{
	int num[5] = {1,3,5,7,9};
	int *num_p = NULL;
	
	//当数组前面加上&时它指的是整个数组的元素长度+1
	 num_p = (&num + 1);
	
	printf("%p\n%p\n%p\n",num_p,(num_p-1),&num_p[-1]);
	printf("\n");
	printf("%d\n%d\n%d\n",*num_p,*(num_p-1),num_p[-1]);
	printf("\n"); 
	
	
	//定义一个二维数组
	int num_1 [3][4] = {{1,3,5,7}, {9,11,13,15}, {17,19,21,23}};
	//定义一个数组指针
	int (*num_pp)[4] = NULL; 
	//定义一个int型指针
	int *num_ppp = NULL;
	//定义一个int型指针
	int *num_pppp = NULL;
	//将指针进行指向
	
	num_pp = num_1;
	num_ppp = num_1;
	num_pppp =(&num_1 + 1); 	// 数组名在和&或sizeof()一起使用时,代表整个数组,
							//加1之后指向数组最后一个元素后面的位置。 
	
	//数组指针
	printf("num_pp的值为 %p\n",num_pp);
	printf("**(num_pp)+1的值为 %d\n",**(num_pp)+1);
	printf("*(*(num_pp)+1)的值为 %d\n",*(*(num_pp)+1));
	printf(" *(*(num_pp+1)+1)的值为 %d\n", *(*(num_pp+1)+1));
	
	//int型指针
	printf("\n"); 
	printf("*num_ppp的值为 %d\n",*num_ppp);
	//这个需要注意,并不是指针位移一位,而是先对num_ppp进行解地址,再加一个1
	//*num_ppp+1 == *num_1 + 1 == num_1[0][0] + 1  
	printf("*num_ppp+1的值为 %d\n",*num_ppp+1);
	
	//int型指针 把数组当作成一个一维数组,每次增加一个,地址增加1*sizeof(int)
	//*(num_ppp+2) == a[0][2]    *(num_ppp+2) == a[2][2]   
	printf("*(num_ppp+2)的值为 %d\n",*(num_ppp+2)); 
	printf("*(num_ppp+10)的值为 %d\n",*(num_ppp+10));
			
			
	//指向数组最后一个元素后面的位置的int型指针  
	printf("\n"); 
	
	printf("*(num_pppp-1)的值为 %d\n",*(num_pppp-1));
	//数组最后一个元素后面的位置 回一位int类型的
	printf("*(num_pppp-2)的值为 %d\n",*(num_pppp-2)); 
	//数组最后一个元素后面的位置 回二位int类型的
	printf("*(num_pppp-1)也可以表示为num_pppp[-1]  %d\n",num_pppp[-1]);
	//数组最后一个元素后面的位置 偏移-1位int类型的
	printf("*(num_pppp-2) 也可以表示为num_pppp[-2] %d\n",num_pppp[-2]); 
	//数组最后一个元素后面的位置 偏移-2位int类型的
	



		return 0;
}

 

 #第五篇代码

指针与函数

讲的是一个比较特殊的指针,函数指针

比较特殊的是 函数指针不能通过偏移来定位到下一个函数 会发生段错误

 

 

 

 

 

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

//声明函数
int add(int x,int y);
//主函数
int main (void)
{
	//定义一个函数型指针
	int (*p_fun)(int x,int y) = NULL;
	p_fun = add;
	
	//定义两个整型变量
	int a,b;
	a = 10;
	b = 25;
	int num_fun = 0;
	printf("a = %d      b = %d\n",a,b);
	
	//用函数调用的方法调用a+b的函数
	printf("函数的调用, bijiao(a,b) = %d\n",add(a,b));
	printf("函数的指针调用,(*p_fun)(a,b) = %d\n",(*p_fun)(a,b));
    printf("===========================\n");
	
	return 0;	
	
}

int add(int x,int y)
{
	x += y;
	
	return x;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅游社交小程序功能有管理员和用户。管理员有个人中心,用户管理,每日签到管理,景点推荐管理,景点分类管理,防疫查询管理,美食推荐管理,酒店推荐管理,周边推荐管理,分享圈管理,我的收藏管理,系统管理。用户可以在微信小程序上注册登录,进行每日签到,防疫查询,可以在分享圈里面进行分享自己想要分享的内容,查看和收藏景点以及美食的推荐等操作。因而具有一定的实用性。 本站后台采用Java的SSM框架进行后台管理开发,可以在浏览器上登录进行后台数据方面的管理,MySQL作为本地数据库,微信小程序用到了微信开发者工具,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得旅游社交小程序管理工作系统化、规范化。 管理员可以管理用户信息,可以对用户信息添加修改删除。管理员可以对景点推荐信息进行添加修改删除操作。管理员可以对分享圈信息进行添加,修改,删除操作。管理员可以对美食推荐信息进行添加,修改,删除操作。管理员可以对酒店推荐信息进行添加,修改,删除操作。管理员可以对周边推荐信息进行添加,修改,删除操作。 小程序用户是需要注册才可以进行登录的,登录后在首页可以查看相关信息,并且下面导航可以点击到其他功能模块。在小程序里点击我的,会出现关于我的界面,在这里可以修改个人信息,以及可以点击其他功能模块。用户想要把一些信息分享到分享圈的时候,可以点击新增,然后输入自己想要分享的信息就可以进行分享圈的操作。用户可以在景点推荐里面进行收藏和评论等操作。用户可以在美食推荐模块搜索和查看美食推荐的相关信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值