当前位置:网站首页>C语言——一级指针初识
C语言——一级指针初识
2022-08-02 14:02:00 【iccoke】
指针的定义
C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里,数据对象是指存储在内存中的一个指定数据类型的数值或字符串,它们都有一个自己的地址,而指针便是保存这个地址的变量。也就是说:指针是一种保存变量地址的变量。
指针的大小只和操作系统有关,在86位操作系统下的指针大小位四个字节,在64位操作系统下为八个字节
例如我们想用函数封装的形式来实现一个两数交换的功能
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int a = 1;
int b = 2;
swap(a, b);
printf("%5d%5d", a, b);
}那么这个函数会打印出 a b的值为多少呢
我们运行这个程序,得到结果
可以看到,a为1,b为2,显然两者并没有发生交换,main函数内部没有问题,那么问题就出在了swap函数中,我们输入的参数是元素 a,b。他们的值分别为1,2,在函数内部完成交换后,swap函数的类型为void,因此没有返回值,也就是说在执行完这个交换功能之后,开辟的内存空间就消失了,那么交换后的值也没有保存到a,b当中,通俗的来说就是main函数和swap函数自己干了自己的事,两者用了两块地方,之间除了参数没有别的联系。
那么修改的办法就显而易见了,我们需要让main函数和swap函数共同使用一块内存空间,这样即使swap函数执行完之后,交换后的值已经保存到a,b当中,从而完成了a,b交换的功能。那么我们如何让这两个函数访问同一个内存空间呢,这里我们就要用到指针。

我们通常这样定义指针
int *p=&a
*代表了这是一个指针变量,其指向的是int类型变量a的地址
我们通过访问p就可以得到a的地址,从而就可以实现在同一个内存空间上完成对a的相关操作
在具体应用指针之前,我们还要了解一个重要的概念——解引用
"*"的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,"解"就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为"解引用"。也就是说,解引用是返回内存地址中对应的对象。
比如int a=10; int *p=&a; 前文说到,p指向了int类型变量a的地址,那么*p就指向了int类型变量a的值
也就是说 *p=10
接下来我们就可以使用指针完成上述操作了,那么联系这两个函数的是形式参数和实际参数,因此我们就要在这里就行修改
void swap(int* p, int* q) {
int temp;
temp = *p;
*p = *q;
*q = temp;
}
int main() {
int a = 10;
int b = 20;
swap(&a, &b);
printf("%5d%5d", a, b);
}可以看到我们传入的实际参数为a,b的地址,然后用指针变量接收,再在函数内部解引用,再进行交换操作,从而完成了函数功能的实现

这里就正确实现了函数功能
接下来就涉及到了当指针指向的数据存入内存中时,它是一种怎么样的形式呢
我们这里就要了解一个新的知识点,Windows数据存储的小端模式
比如说十进制数20在内存中以上16进制存储的,同时是四个字节,那么他在内存中的应该是以
00000014存储的,但是实际上,它在内存中是以14000000存储的
这是为什么呢,首先main函数会开辟一个栈,然后从高地址往低地址

又因为存储方式是小端存储
数据的低位放在低地址空间,数据的高位放在高地址空间
简记:小端就是低位对应低地址,高位对应高地址
读取数据的时候是从低地址开始读取,所以在内存中显示出来的是14000000
最后要说的就是关于指针的运算
p + n ——>
p向高地址偏移 n*sizeof(元素类型)
int *p = arr; //&arr[0]
p+1 //&arr[1] <=> p+1
*(p+1) -> arr[1]
p+3 -> &arr[3]
*(p+3) -> arr[3]

加括号的原因是*与+的优先级问题
这里还涉及到了*号的各种用法

边栏推荐
- c语言用scanf出错不安全的解决办法
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第十二章)
- chapter6可视化(不想看版)
- Flask上下文,蓝图和Flask-RESTful
- 跑yolov5又出啥问题了(1)p,r,map全部为0
- verilog学习|《Verilog数字系统设计教程》夏宇闻 第三版思考题答案(第九章)
- drf序列化器-Serializer
- What's wrong with running yolov5 (1) p, r, map are all 0
- (ROS) (03) CMakeLists. TXT, rounding
- 【ROS】工控机的软件包不编译
猜你喜欢
随机推荐
深度学习框架pytorch快速开发与实战chapter4
Unit 8 Middleware
yolov5改进(一) 添加注意力集中机制
jwt(json web token)
ftp常用命令详解_iftop命令详解
Sentinel源码(三)slot解析
第八单元 中间件
Briefly write about the use and experience of PPOCRLabel
8576 Basic operations of sequential linear tables
使用云GPU+pycharm训练模型实现后台跑程序、自动保存训练结果、服务器自动关机
Chapter6 visualization (don't want to see the version)
Flask上下文,蓝图和Flask-RESTful
第十一单元 序列化器
drf view component
Unit 11 Serializers
ToF相机从Camera2 API中获取DEPTH16格式深度图
Creating seven NiuYun Flask project complete and let cloud
How to solve mysql service cannot start 1069
C语言sizeof和strlen的区别
Flask request application context source code analysis









