当前位置:网站首页>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]

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

边栏推荐
- Unit 12 associated serialization
- ToF相机从Camera2 API中获取DEPTH16格式深度图
- 第十单元 前后连调
- [ROS] Introduction to common tools in ROS (to be continued)
- EasyExcel 的使用
- 使用云GPU+pycharm训练模型实现后台跑程序、自动保存训练结果、服务器自动关机
- 第十一单元 序列化器
- (ROS) (03) CMakeLists. TXT, rounding
- Flask框架深入一
- How does Apache, the world's largest open source foundation, work?
猜你喜欢

Sentinel源码(四)(滑动窗口流量统计)
![[ROS] (06) ROS Communication - Topic Communication](/img/21/d79f2c4e246eb9ea39df9c7435bb36.png)
[ROS] (06) ROS Communication - Topic Communication
![[ROS]roscd和cd的区别](/img/a8/a1347568170821e8f186091b93e52a.png)
[ROS]roscd和cd的区别

paddleocr window10初体验

Implementation of redis distributed lock and watchdog

瑞吉外卖笔记——第08讲读写分离

Camera Hal(Hal3)层修改Preview流
![[ROS] Introduction to common tools in ROS (to be continued)](/img/ea/e390106f750bf697e62a3a296014d2.png)
[ROS] Introduction to common tools in ROS (to be continued)

Raft协议图解,缺陷以及优化

The specific operation process of cloud GPU (Hengyuan cloud) training
随机推荐
Programming Specifications - LiteOS
yolov5,yolov4,yolov3乱七八糟的
猜数字游戏,猜错10次关机(srand、rand、time)随机数生成三板斧(详细讲解!不懂问我!)
drf源码分析与全局捕获异常
Basic operations of 8583 sequential stack
Web Design (Beginners) [easy to understand]
paddle window10环境下使用conda安装
动手学ocr(一)
STM32(F407)—— 堆栈
瑞吉外卖笔记——第10讲Swagger
Paddle window10 environment using conda installation
Unit 13 Mixing in View Base Classes
run yolov5
Chapter6 visualization (don't want to see the version)
8576 Basic operations of sequential linear tables
Briefly write about the use and experience of PPOCRLabel
[ROS](06)ROS通信 —— 话题(Topic)通信
ToF相机从Camera2 API中获取DEPTH16格式深度图
yolov5 improvement (1) Add attention focus mechanism
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin [id ‘c