C 语言指针完全指南:创建、解除引用、指针与数组关系解析
C 语言中的指针
创建指针
我们可以使用引用运算符 &
获取变量的内存地址:
int myAge = 43; // 一个 int 变量
printf("%d", myAge); // 输出 myAge 的值 (43)
printf("%p", &myAge); // 输出 myAge 的内存地址 (0x7ffe5367e044)
指针是一个将另一个变量的内存地址作为其值的变量。
指针变量指向一个数据类型(如 int
)的相同类型,并使用 *
运算符创建。您正在使用的变量的地址被分配给指针:
int myAge = 43; // 一个 int 变量
int* ptr = &myAge; // 一个名为 ptr 的指针变量,存储 myAge 的地址
// 输出 myAge 的值 (43)
printf("%d\n", myAge);
// 输出 myAge 的内存地址 (0x7ffe5367e044)
printf("%p\n", &myAge);
// 使用指针输出 myAge 的内存地址 (0x7ffe5367e044)
printf("%p\n", ptr);
示例解释:
- 创建一个名为
ptr
的指针变量,指向一个int
变量 (myAge
)。请注意,指针的类型必须与您正在使用的变量的类型匹配(本例中为int
)。 - 使用
&
运算符将myAge
变量的内存地址存储并分配给指针。 - 现在,
ptr
存储了myAge
的内存地址值。
解除引用
在上面的示例中,我们使用指针变量来获取变量的内存地址(与 &
引用运算符一起使用)。
您还可以通过使用 *
运算符(取消引用运算符)获取指针指向的变量的值:
int myAge = 43; // 变量声明
int* ptr = &myAge; // 指针声明
// 引用:使用指针输出 myAge 的内存地址 (0x7ffe5367e044)
printf("%p\n", ptr);
// 解除引用:使用指针输出 myAge 的值 (43)
printf("%d\n", *ptr);
请注意,*
符号在这里可能会让人困惑,因为它在我们的代码中做了两件事:
- 当用于声明 (
int* ptr
) 时,它会创建一个指针变量。 - 当不用于声明时,它充当取消引用运算符。
值得注意:在 C 语言中声明指针变量有两种方法:
int* myNum;
int *myNum;
关于指针的注意事项:
- 指针是 C 语言区别于其他编程语言(如 Python 和 Java)的一大特点。
- 它们在 C 语言中很重要,因为它们允许我们操作计算机内存中的数据。这可以减少代码量并提高性能。如果您熟悉像列表、树和图这样的数据结构,您应该知道指针对于实现它们特别有用。有时您甚至必须使用指针,例如在处理文件时。
- 但是要小心; 指针必须谨慎处理,因为有可能损坏存储在其他内存地址的数据。
C 语言中的指针和数组
您也可以使用指针访问数组。
考虑以下整数数组
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", myNumbers[i]);
}
结果:
25
50
75
100
让我们尝试打印每个数组元素的内存地址,而不是打印每个数组元素的值:
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++) {
printf("%p\n", &myNumbers[i]);
}
结果:
0x7ffe70f9d8f0
0x7ffe70f9d8f4
0x7ffe70f9d8f8
0x7ffe70f9d8fc
请注意,每个元素的内存地址的最后一位数字都不同,增加了 4。
这是因为 int
类型的大小通常为 4 个字节,请记住:
// 创建一个 int 变量
int myInt;
// 获取一个 int 的内存大小
printf("%lu", sizeof(myInt));
结果:4
因此,从上面的“内存地址示例”中,
您可以看到编译器为每个数组元素预留了 4 个字节的内存,这意味着整个数组占用 16 个字节(4 * 4)的内存存储空间:
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 数组的大小
printf("%lu", sizeof(myNumbers));
结果:16
指针与数组的关系
好的,那么指针和数组之间有什么关系呢?好吧,在 C 语言中,数组的名称实际上是指向数组第一个元素的指针。
感到困惑?让我们试着更好地理解这一点,并再次使用上面的“内存地址示例”。
第一个元素的内存地址与数组的名称相同:
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 数组的内存地址
printf("%p\n", myNumbers);
// 获取第一个数组元素的内存地址
printf("%p\n", &myNumbers[0]);
结果:
0x7ffe70f9d8f0
0x7ffe70f9d8f0
这基本上意味着我们可以通过指针来操作数组!
怎么操作呢?由于 myNumbers
是指向 myNumbers
中第一个元素的指针,因此您可以使用 *
运算符来访问它:
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 中第一个元素的值
printf("%d", *myNumbers);
结果:25
要访问 myNumbers
中的其他元素,您可以增加指针/数组(+1、+2 等):
int myNumbers[4] = {25, 50, 75, 100};
// 获取 myNumbers 中的第二个元素的值
printf("%d\n", *(myNumbers + 1));
// 获取 myNumbers 中的第三个元素的值
printf("%d", *(myNumbers + 2));
// 等等..
结果:
50
75
或者循环遍历它:
int myNumbers[4] = {25, 50, 75, 100};
int *ptr = myNumbers;
int i;
for (i = 0; i < 4; i++) {
printf("%d\n", *(ptr + i));
}
结果:
25
50
75
100
您也可以使用指针更改数组元素的值:
int myNumbers[4] = {25, 50, 75, 100};
// 将第一个元素的值改为 13
*myNumbers = 13;
// 将第二个元素的值改为 17
最后
为了方便其他设备和平台的小伙伴观看往期文章:
微信公众号搜索:Let us Coding
,关注后即可获取最新文章推送
看完如果觉得有帮助,欢迎 点赞、收藏、关注
C 语言指针完全指南:创建、解除引用、指针与数组关系解析的更多相关文章
- Perl解除引用:从引用还原到数据对象
使用引用可以指向数据对象,这似乎很简单. @name1=qw(longshuai wugui); @name2=qw(xiaofang tuner); $ref_name=\@name1; push ...
- 【C语言入门教程】4.5 指针变量的定义与引用
指针变量是包含内存地址的变量.一般的变量直接包含一个特定的值,而指针变量包含的是某一特定数据类型的内存地址.普通变量直接引用其中的值,指针变量则间接引用所指向内存地址中的值.指针变量在使用前需要声明与 ...
- C语言学习笔记 (002) - C++中引用和指针的区别(转载)
下面用通俗易懂的话来概述一下: 指针-对于一个类型T,T*就是指向T的指针类型,也即一个T*类型的变量能够保存一个T对象的地址,而类型T是可以加一些限定词的,如const.volatile等等.见下图 ...
- perl5 第十二章 Perl5中的引用/指针
第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用 子程序模板七.数组与子程序八.文件句 ...
- JVM 平台上的各种语言的开发指南
JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...
- C语言学习书籍推荐《C语言接口与实现:创建可重用软件的技术》下载
<C语言接口与实现:创建可重用软件的技术>概念清晰.实例详尽,是一本有关设计.实现和有效使用C语言库函数,掌握创建可重用C语言软件模块技术的参考指南.书中提供了大量实例,重在阐述如何用一种 ...
- Java中“指针”的解释以及对“引用”的理解
Java中"指针"的解释以及对"引用"的理解 初学Java面对对象编程,对于一些概念还真的有点难以理解,主要是因为不由自主的联系到以前学过的C语言知识,时不时的 ...
- Go 语言:如何利用好 TDD 学习指针并了解 Golang 中的 error 处理
我们在上一节中学习了结构体(structs),Go语言:利用 TDD 驱动开发测试 学习结构体.方法和接口 它可以组合与一个概念相关的一系列值. 你有时可能想用结构体来管理状态,通过将方法暴露给用户的 ...
- R 语言编码风格指南
R 语言是一门主要用于统计计算和绘图的高级编程语言.这份 R 语言编码风格指南旨在让我们的 R代码更容易阅读.分享和检查.以下规则系与 Google 的 R 用户群体协同设计而成. 概要: R编码风格 ...
- 来自 Google 的 R 语言编码风格指南
来自 Google 的 R 语言编码风格指南R 语言是一门主要用于统计计算和绘图的高级编程语言. 这份 R 语言编码风格指南旨在让我们的 R 代码更容易阅读.分享和检查. 以下规则系与 Google ...
随机推荐
- 苹果工程师对iOS线程开发的那点事津津乐道
pthread,Thread总结 pthread: 通用的多线程API 使用方法 // 1. 创建线程: 定义一个pthread_t类型变量 pthread_t thread; // 2. 开启线程: ...
- 用Docker发布网站时,自动下载Directory.Build.props及其Import的文件
为Blazor网站项目,"添加Docker支持" 这时,网站项目根目录下会新增Dockerfile. 里面文字内容如下 #See https://aka.ms/customizec ...
- 【Azure App Service】同一个App Service下创建多个测试站点的方式
问题描述 在一个App Service中,部署多个应用,每个应用相互独立,类似与IIS中在根目录下创建多个子应用的情况. 问题解答 可以的.通过App Service Configuration页面, ...
- C++ STL //vector容器存放内置数组
1 //STL初始 2 // 3 //vector容器存放内置数组 4 5 #include <iostream> 6 #include <string> 7 #include ...
- 10 个解放双手的 IDEA插件,少些冤枉代码(第三弹)
大家好,我是小富- 好久没发这种实用贴了,最近用到了一些能提升工作效率的IDEA插件,给小伙伴们分享一下.相信我,我分享的这些插件,都是实实在在能解决实际开发场景中痛处的. 以往的两篇IDEA插件分享 ...
- Spring 知识点
Spring Spring 是什么? Spring为了解决企业级应用的复杂性而创建,简化开发. 如下简化: 基于POJO的轻量级和最小侵入性编程: 以IoC(控制反转).DI(依赖注入)和面向接口实现 ...
- matting tool by cs - 视频扣绿幕 1.4 - 软件推荐
本地软件,还没用,先留个档,试试 第一个下载还套了个广告壳,醉了,但是能用 https://www.123pan.com/s/X3jA-POMQv 这个装了,是原版,没套壳 https://pan.b ...
- 基于python的生理电信号采集的数据转换和处理软件
一 前记 团队开发了几款生物电信号采集系统,可数据处理和转换工具刚开始用的都是matlab.这对一些客户来说,使用门槛还是有些高了.开发一套配套的软件,满足广大用户的需求,已经是迫在眉睫的事情了.最近 ...
- Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
有个需要是需要在安装包安装初始化时安装 Microsoft Visual c++ 2013 Redistributable 也就是判断软件安装前需不需要运行 vcredist_x64.exe 和 VC ...
- 记录一次运行vue项目一直不成功的经历
参考:https://blog.csdn.net/qq_17162169/article/details/115718002 如果前端项目一直起不来,直接删除扩展文件夹试试 // npm安装vue y ...