当前位置:网站首页>打卡:4.22 C语言篇 -(1)初识C语言 - (11)指针
打卡:4.22 C语言篇 -(1)初识C语言 - (11)指针
2022-04-23 03:22:00 【每天都要学一点哦】
今天,我们来讲一下指针和结构体
指针
都说指针很难,其实很好理解的,我来带你了解一下
内存
说指针就不得不说一下内存
内存是电脑上特别重要的存储器
我们可以打开任务管理器

在任务管理器里面可以看到内存的使用情况,有每个软件运行所占的内存,可以看到计算机中程序的运行都是在内存中进行的
但是我们需要有效的使用内存空间,这里我们买个
4G内存的电脑,可以把4G的内存分成一个一个的小空间,这样就会方便管理
就像这样,
这是一大块儿的内存,我们要怎么去管理它呢?
类比一下生活,就像我们的国家,这么大的一个国家我们要怎么管理呢?你会想到省,县,镇,村,把一大块的国家分成一个省一个省管理,每个省都有自己的管理制度,但是服从于中央管理,内存也是这样,也会划分成这样一个一个的小格子,叫做内存单元,一个内存单元的大小是一个字节
来一个宿舍楼,叫13栋宿舍楼(因为我住的就是13栋,哈哈)

里面有很多的房间,但是都没有编号,我买了个外卖,我说有一个房间是我住的,送外卖的也不知道我在那个房间,只能一个一个的去找.
但是我给每一个房间都编上号,像这样
我说我在305号宿舍,送外卖的是不是唰的一下就找到我了
内存就是13栋宿舍楼,内存单元就是房间,内存这么大的一块儿空间,分成一个一个的内存单元,每一个内存单元都有一个地址,这个地址就是房间的编号,是不是就能很好的管理内存了
我们再来说一下地址线
我们的电脑有32位的,也有64位,这里指的是有32条地址线和64地址线,地址线通电就会产生脉冲,每一个地址线都有两种状态,也就是二进制里面的1/0
这里就说32位的电脑
这里有
32根的地址线
每根地址线都有1/0的选择
它的组合有:
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0001
0000 0000 0000 0000 0000 0000 0000 0010
…………
1111 1111 1111 1111 1111 1111 1111 1110
1111 1111 1111 1111 1111 1111 1111 1111
一共有223种,也就是
4,294,967,296种
所以有223个编号,对应223个地址
4,294,967,296byte
4,294,967,296÷1024=4,194,304kb
4,194,304÷1024=4,096MB
4,096÷1024=4GB
所以
32位的电脑可以访问4GB大小的空间
我们现在常见的都是
64位的电脑,类比上面,可以知道它可以访问很大的空间,它是有这个能力的
我们认定
1个地址管理1个字节的大小
但是为什么不是一个bit呢?
之前我们讲过计算机最小的单元是bit(比特位),1个字节=8个bit
我来解释一下
创建一个数据类型里面最小的字符类型
char a;,这个a的大小是一个字节,
如果我们一个地址只对应一个
bit,但是一个最小的char类型的变量a就占8个地址,是不是太浪费了
就像送快递,我在13栋305宿舍,你非得给我送到13栋305宿舍第5块瓷砖上,是不是没有必要
这样有什么用呢?
来看一下代码的运行过程
int main()
{
int a = 0;
&a;
return 0;
}
这里的
int a = 0;的意思就是向内存申请4个字节的空间来存放0,
&是取地址操作符(之前没有讲),它的作用是把a这个变量的地址给取出来
我们来调试一下
(如何调试看这一篇博客的问题三)
打开监视(在调试开始的时候才有)
调试->窗口->监视->输入监视的变量
看到没有,a被创建了,&a也把地址取了出来,它的地址是0x009dfa5c,这个地址里面存储了10这个值,
我们再打开内存(在调试开始的时候才有)
调试->窗口->内存
把
自动改为4
把a的地址0x009dfa5c填在里面,回车,就会查到这个地址
红框就是地址,橙框就是内存中的数据,紫框就是内存数据的文本分析(编译器想尝试分析一下你里面存的是什么东西,很明显,是不准确的)
来说一下橙框里面的
0a 00 00 00
这个是十六进制
a代表的就是存储的值10
你发现没有,红框里地址
0x009dfa5c下面的不是0x009dfa5d,而是0x009dfa60,相差3个地址
橙框里0a就是地址0x009dfa5c,后面的00 00 00分别是0x009dfa5d 0x009dfa5e 0x009dfa5f
这三个地址没有写,
我们开辟了
4个字节,分配了四个地址,为什么a的值存在第一个而不是后面呢?以后我们会讲到
之前我们存的是
a的值,那么我们怎么把&a取出来的地址存起来呢?
int main()
{
int a = 10;
int* p = &a;
return 0;
}
int* p就是指针变量p,跟之前讲的那些变量一样,都是变量,指针变量p可以把&a取出来的地址存起来
在int* p中p指向的就是a的地址,而*就是说明p是一个指针,int指的是p所指向a的地址所存放的类型是int类型
int main()
{
char a = 'w';
char* p = &a;
return 0;
}
char* p的char就是指针变量p所指向a的地址所存放的类型是char类型

我们每一次运行的时候,变量
a存的地址都是不一样的,而且地址我们是不能改的,编译器已经把地址给你分配好了,不能随便改,这一点要记住(用这个printf("%p",p);打印一下试试看,看看地址是不是在变化)
有一句话,在锤子眼里,什么都是钉子
指针变量眼里,你放在里面的都是地址,它只能用来存放地址
既然我们把这个
a的地址存在了指针变量p中,那么我们可以通过这个地址来找到它所指向的对象吗
我们用*p;来进行这个过程
这里的*叫解引用操作符,意思是通过指针变量p存放的地址,来找到p指向的对象,即*p就是a
总结一下
&和*这两个操作符,它们是一一对应的
&是取出a的地址,*是根据地址重新回到a,一来一去的
试一试:
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;
*p = 20;//这里的*p其实就相当于a了
//打印a的地址和a的值
printf("%p\n", p);//打印地址用%p
printf("%d\n", a);
return 0;
}
运行的结果:
008FFD9C
20
可以看到,最开始赋予a的值是10,但是把20赋予*p后,打印的a的值是20,所以就能看出来*p其实就是变量a了
指针变量的大小
之前我们用
sizeof计算了char,short,int,long,float,double的大小,分别是1,2,4,4-8,4,8
那么我们来计算一下指针变量的大小
int main()
{
printf("%zu\n", sizeof(char*));
printf("%zu\n", sizeof(short*));
printf("%zu\n", sizeof(int*));
printf("%zu\n", sizeof(long*));
printf("%zu\n", sizeof(float*));
printf("%zu\n", sizeof(double*));
return 0;
}
运行的结果:
4
4
4
4
4
4
为什么会是这样,它们指向的类型不是不一样吗?
不管创建什么类型的指针,都是在创建指针变量,指针变量是用来存放地址的
而指针变量的大小取决于一个地址存放的时候需要多大空间
在32位的机器上的地址有32个bit位,也就是4个byte
在64位的机器上的地址有64个bit位,也就是8个byte
我们刚才是在
32位平台上运行的,所以大小是4个字节
我们改一下,改成
x64,也就是64位的平台
再运行一下:
8
8
8
8
8
8
看到没有,指针变量的大小只跟在哪个平台上有关,在32位平台就是4个字节,在64位平台上就是8个字节
写指针变量有两种形式
int a = 10;
int* p = &a;
int *p = &a;
你可以把
*向左贴,也可以向右贴,这都是可以的,这个是写代码的习惯,各有优点。
比如,你看看这行代码
int* p1, p2, p3;
你认为
p1,p2,p3都是指针变量吗?
不,当然不是,这个*其实只给了p1,只有p1是指针变量,而p2,p3都只是跟着int,没有分配*,所以它俩都是整型
我们这样写
int *p1, p2, p3;
是不是能很好的理解了,
*只贴向p1,所以只有p1是指针变量
我们要把它们全部变成指针变量,就这样做
int *p1, *p2, *p3;
所以它们各有优点,看个人习惯
指针就学到这里吧,简单了解一下就行了
版权声明
本文为[每天都要学一点哦]所创,转载请带上原文链接,感谢
https://blog.csdn.net/iqrmshrt/article/details/124342840
边栏推荐
- Web Course Design - his system
- oracle 查询外键含有逗号分隔的数据
- The most understandable life cycle of dependency injection
- A set of combination boxing to create an idea eye protection scheme
- 为什么BI对企业这么重要?
- Data mining series (3)_ Data mining plug-in for Excel_ Estimation analysis
- 【VS Code】解决jupyter文件在vs code中显示异常的问题
- Course design of Database Principle -- material distribution management system
- 2022T电梯修理考试模拟100题及在线模拟考试
- Supersocket is Use in net5 - startup
猜你喜欢

Using swagger in. Net5

C language to achieve address book - (static version)

一套组合拳,打造一款 IDEA 护眼方案

可以接收多種數據類型參數——可變參數
![[Mysql] LEFT函数 | RIGHT函数](/img/26/82e0f2280de011636c26931a74e749.png)
[Mysql] LEFT函数 | RIGHT函数

xutils3修改了我提报的一个bug,开心

Xamarin effect Chapter 22 recording effect

Huawei mobile ADB devices connection device is empty

二进制文件版本控制工具选择难?看完这篇你会找到答案

Quartz. Www. 18fu Used in net core
随机推荐
It can receive multiple data type parameters - variable parameters
Configuration table and page information automatically generate curd operation page
Experiment 6 input / output stream
Preview of converting doc and PDF to SWF file
MySQL port is occupied when building xampp
A set of combination boxing to create an idea eye protection scheme
【VS Code】解决jupyter文件在vs code中显示异常的问题
2022A特种设备相关管理(电梯)上岗证题库及模拟考试
Build websocket server in. Net5 webapi
EasyUI's combobox implements three-level query
数据库表中不建索引,在插入数据时,通过sql语句防止重复添加(转载)
Establishing and traversing binary tree
JS recursive tree structure calculates the number of leaf nodes of each node and outputs it
[MySQL] left Function | Right Function
Oracle query foreign keys contain comma separated data
Batch download of files ---- compressed and then downloaded
C introduction of variable parameter params
可以接收多種數據類型參數——可變參數
2022 Shandong Province safety officer C certificate work certificate question bank and online simulation examination
Cefsharp stores cookies and reads cookies












