C 认识指针

目录

一、取地址操作符(&)

二、解引用操作符(*)

三、指针变量

[1、 指针变量的大小](#1、 指针变量的大小)

[2、 指针变量类型的意义](#2、 指针变量类型的意义)

[2.1 指针的解引用](#2.1 指针的解引用)

[2.2 指针 +- 整数](#2.2 指针 +- 整数)

[2.3 调试解决疑惑](#2.3 调试解决疑惑)


认识指针,指针比较害羞内敛,我们需要通过他的好朋友们认识他

一、取地址操作符(&)

cpp 复制代码
//VS2022 x86
#include <stdio.h>
int main()
{
	int i = 1314;
	int* p = &i; //  &  取地址操作符;将 i 里的地址取出来放到 p 里
                 //int* 表示p是整型指针变量,指针是用来存放地址的
    printf("%p\n", p);    
	printf("%p\n", &i);
	return 0;
}

把平台换成 x86 好观察(x64也可以,只是长一些,为了这篇文章后面统一都是x86平台)

运行后可以看到之这一长串数字加字母,不用管他,知道这是地址就行,可以看出:

指针p 里存放的地址和从 变量i 中取出来的地址是一样的;每次编译地址都会变,但 p == &i 。


二、解引用操作符(*)

cpp 复制代码
#include <stdio.h>
int main()
{
	int i = 1314;
	int* p = &i;
	printf("%d\n", i);
	*p = 20;    // * 解引用操作符
	printf("%d\n", i);
	return 0;
}

可以看到 变量i 的值被改变了,这是因为 *p 的意思是将 p 里存放的地址通过解引用从而找到 变量i,然后赋值20;

可以这么理解,i 是一个宝藏,p 就是这个宝藏所在坐标,然后你通过正确的解读宝藏在地图上的位置(*)最终找到了宝藏,随后把它挖走并往里面放了个石头埋起来戏耍后面的人,i 就变成了石头。


三、指针变量

前面通过对他朋友的认识,顺便知道了指针变量是用来存放地址的,那这里我们需要了解他的特点

1、 指针变量的大小

cpp 复制代码
#include <stdio.h>
int main()
{
 printf("%zd\n", sizeof(char *));
 printf("%zd\n", sizeof(short *));
 printf("%zd\n", sizeof(int *));
 printf("%zd\n", sizeof(double *));
 return 0;

x86环境下(32位平台) x64环境下(64位平台)

结论:

  • 32位平台下地址是32个bit位,指针变量大小是4个字节;
  • 64位平台下地址是64个bit位,指针变量大小是8个字节;
  • 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

不管给他任何修饰词(int*、char*),在我们面前(32位平台)就是腼腆得很,在朋友面前(64位平台)就是开放得很,所以和他交上朋友才能更了解他嘿嘿。

那就疑惑了,变量规定类型是因为有字节大小区分,指针变量大小在不同类型下字节大小都一样,那为什么要规定指针变量的类型呢?

2、 指针变量类型的意义

2.1 指针的解引用

通过代码就能很清楚的看出来啦,好好看好好学

cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 0x11223344;	//十六进制,两个数字代表一个字节
	char* p = (char*) &n;    //不强转会报警告
	*p = 0;
	printf("%x", n);    //%x 打印十六进制整数
	return 0;
}
cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 0x11223344;	//十六进制,一个数字代表一个字节
	int* p = &n;
	*p = 0;
	printf("%x", n);
	return 0;
}

char* p int* p

可以看到,int* p 会将n的4个字节全部改为0,但是 char* p 只是将n的第⼀个字节改为0。

结论:指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)。

2.2 指针 +- 整数
cpp 复制代码
#include <stdio.h>
int main()
{
	int n = 10;
	printf("%p\n", &n);
	printf("=================\n");

	char* pc = (char*)&n;
	printf("%p\n", pc);
	printf("%p\n", pc + 1);
	printf("=================\n");

	int* pi = &n;
	printf("%p\n", pi);
	printf("%p\n", pi + 1);
	return 0;
}

我们可以看出, char* 类型的指针变量 +1 跳过 1个字节, int* 类型的指针变量 +1 跳过了 4个字节。 这就是指针变量的类型差异带来的变化。指针 +1 ,其实跳过1个指针指向的元素。指针可以+1,那也可以-1。

结论:指针的类型决定了指针向前或者向后走一步有多大(距离)。

2.3 调试解决疑惑

诶不对哇,3.2中 cha* p 怎么改第一个字节把0x11223344的44改了,不应该是改11吗,来,跟我调试起来

(1)

(2)Ctrl+Fn+F10(或者Ctrl+F10)进入调试

(3)

(4)

(5)注意左边的箭头,Fn+F10 箭头会指向下一条语句,下到图片位置

看到了吧,内存中的0x11223344是倒着存进内存里的,所以第一个字节是44,继续按Fn+F10就可以看到 44 变为 00。


相关推荐
Zfox_2 分钟前
【Linux】进程信号全攻略(二)
linux·运维·c语言·c++
shymoy7 分钟前
Radix Sorts
数据结构·算法·排序算法
风影小子15 分钟前
注册登录学生管理系统小项目
算法
黑龙江亿林等保18 分钟前
深入探索哈尔滨二级等保下的负载均衡SLB及其核心算法
运维·算法·负载均衡
少年负剑去20 分钟前
第十五届蓝桥杯C/C++B组题解——数字接龙
c语言·c++·蓝桥杯
lucy1530275107920 分钟前
【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者
人工智能·科技·单片机·嵌入式硬件·算法·机器学习
杜杜的man36 分钟前
【go从零单排】迭代器(Iterators)
开发语言·算法·golang
小沈熬夜秃头中୧⍤⃝1 小时前
【贪心算法】No.1---贪心算法(1)
算法·贪心算法
木向1 小时前
leetcode92:反转链表||
数据结构·c++·算法·leetcode·链表
阿阿越1 小时前
算法每日练 -- 双指针篇(持续更新中)
数据结构·c++·算法