指针简单理解

目录

指针用法及简单理解

一、概念

二、指针有关操作及理解

三、指针与变量关系及理解

四、实例

五、指针运算


指针用法及简单理解

一、概念

内存中每个字节的空间都会有一个编号,这个编号就是指针也叫作地址,保存指针的变量叫做指针变量。
只不过通常的情况下,我们常说的:
地址:说的是内存地址
指针:说的是指针变量

二、指针有关操作及理解

&: 获取变量的地址 在定义变量时。
*:在定义变量时,只起到一个标识作用,标识定义的是一个指针变量其他场景下,取操作都表示通过指针访问对应的地址上的数据
在64位系统中指针大小为8字节
在32位系统中指针大小为4字节

三、指针与变量关系及理解

 int a=10;
 //第一种给指针赋值的方法(初始化)
 int *p=&a;
 //第二种给指针赋值的方法(初始化)
 int *p=NULL;
 p=&a;
/*
p  可以看做一个用来保存地址的变量
*P 可以看做是操作p所保存地址的变量的内容
*/
 

在这里插入图片描述
简单点去理解指针:
把“a”看做一个仓库,既然是仓库就会有地址(&a),也能存放货物(10)。
指针可以看做是仓库雇佣的“工人”,既然雇佣了工人就要告诉工人仓库在哪,以操作那一种货物。

四、实例

#include <stdio.h>

int main(int argc, const char *argv[])
{
	//内存中每个字节的空间都有一个编号,这个编号就是指针,也叫地址
	//当程序执行到定义变量的语句时 操作系统会根据类型给变量分配空间
	int a = 10;

	//通过变量名可以获取到变量的地址
	//  & : 获取变量的地址  &a  取到的是变量的首地址  编号最小的那个
	//  %p 输出地址
	printf("&a = %p\n", &a);

	//常量没有地址可言
	//printf("&100 = %p\n", &100);//错误的
	
	//普通变量是可以 存储 变量的地址的
	//但是一般 不会这么做
	//因为 没法通过保存地址的变量取访问对应的内存空间
	//下面例子 temp可以保存 a的地址  但是没法通过 temp 改变a的值
	//long temp = &a;
	//printf("temp = %p\n", temp);
	//*temp = 1314;//错误的 普通变量不允许做 * 操作

	//定义一个指针变量p 保存 变量a的地址的
	//也称为 指针p 指向 a
	//格式  数据类型  *指针变量名;
	int *p = &a;
	printf("p = %p\n", p);

	//通过p是可以操作 a所在的内存空间的
	*p = 1314;//*p 表示访问 p保存的地址中的数据
	printf("a = %d\n", a);

	//指针保存了变量的地址后  有下面的关系
	//p <==> &a
	//a <==> *p
	printf("p = %p  &a = %p\n", p, &a);
	printf("*p = %d  a = %d\n", *p, a);

	//指针变量也是一个变量 也需要操作系统分配空间
	printf("&p = %p\n", &p);

	//指针只能保存已经分配给你的空间的地址
	int *p2 = 0x123456;
	//printf("p2 = %p\n", p2);  //可以保存  但是不能操作
	//*p2 = 520;//错误的
	
	//指针如果没有初始化 指向是不确定的 因为存的是随机值
	//这种指针叫做  野指针
	//野指针是有害的  错误不可预知
	//int *p3;//注意:代码中不要出现野指针
	
	//指针变量的初始化
	// NULL 空地址  0地址   NULL 本质   (void *)0
	int *p4 = NULL; //不确定要指向谁的指针先让他指向NULL
				//这种指针叫空指针
				//对空指针的操作  一定会段错误
	//*p4 = 1314;//段错误

	return 0;
}

五、指针运算

指针的运算,本质就是,指针变量里面存的地址之间的运算。所以,运算的操作就是有限的了

指针之间可以做 算数运算 : +、 -、 ++、 --

关系运算 :>、<、>=、<=、==、!=

赋值运算 : =

注: 同种类型的指针之间做运算才有意义,不同类型的指针做运算是没有意义的。

#include <stdio.h>

int main(int argc, const char *argv[])
{
	//指针类型 的作用
	//决定了从指针指向的编号开始,可以操作几个字节的空间
	//一般为了让指针操作的范围和指向的变量操作的范围一致
	//都使用和变量类型一致的指针
	int num = 1314;
	int *ppp = &num;

	//对于两个变量而言 地址运算没有意义 因为地址都是有操作系统分的 是随机的
	//对数组来说  指针的运算是有意义的 因为数组成员在内存上是连续的
	int s[5] = {10,20,30,40,50};
	int *p2 = &s[0];
	int *p3 = &s[2];
	//两个指针做减法 差值 是相差的 指针的 数据类型的个数
	//而不是相差的字节数
	printf("p3 - p2 = %ld\n", p3 - p2);//2 相差两个 int

	//指针的强制类型转换是 安全的
	char *q1 = (char *)p2;
	char *q2 = (char *)p3;
	printf("q2 - q1 = %ld\n", q2 - q1);//8

	//一个指针+ 或着 - 一个整数n
	//表示: +  或者  -    n*sizeof(指针的类型) 个字节
	int *p4 = p2+4;//相当于 加了4 个int
	printf("*p4 = %d\n", *p4);//50

	//两个指针是可以做关系运算的 但是一般也是在数组成员的地址中
	//比较大小才有意义  以大于为例 其他同理
	if(p3 > p2){
		printf("yes\n");
	}else{
		printf("no\n");
	}

	printf("--------------------\n");
	int a = 10;
	int b = 10;
	int *hqyj1 = &a;
	int *hqyj2 = &b;
	if(hqyj1 == hqyj2){//比较的是 a和b的地址
		printf("yes1\n");
	}
	if(*hqyj1 == *hqyj2){//比较的是  a和b的值
		printf("yes2\n");
	}
	printf("--------------------\n");

	//指针变量也是变量  变量之间是可以相互赋值的
	int *p5 = NULL;
	p5 = p2;//正确的
	p5 = p3;//正确的

	//注意下面的用法
	int s2[5] = {10,20,30,40,50};
	int *p = &s2[0];
	int ret1 = *++p;
	printf("ret1 = %d\n", ret1);//20 先算 ++p 然后对 ++p表达式的结果取 *操作
								// ++p 表达式的结果 是+之后的值
	printf("p = %p  &s[1] = %p\n", p, &s2[1]);//相等
	p = &s2[0];
	int ret2 = *p++;
	printf("ret2 = %d\n", ret2);//10 先算 p++ 然后对 p++ 表达式的结果取 *操作
								// p++ 表达式的结果 是+之前的值
	printf("p = %p  &s[1] = %p\n", p, &s2[1]);//相等

	return 0;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值