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 ...
随机推荐
- Elasticsearch下载安装配置
下载地址 # elasticsearch https://www.elastic.co/cn/downloads/past-releases/elasticsearch-6-8-3 # kibana ...
- Redis灵魂11问
目录 说说redis都有哪些数据类型吧 Redis为什么快呢? 那为什么Redis6.0之后又改用多线程呢? 知道什么是热key吗?热key问题怎么解决? 什么是缓存击穿.缓存穿透.缓存雪崩? 缓存击 ...
- 设置 sudo 无需输入密码
* 设置 sudo 无需输入密码,如下:* [root@localhost ~]# visudo* 在"root ALL=(ALL) ALL"这一行下面,再加入一行:* 将原来的: ...
- 文心一言 VS 讯飞星火 VS chatgpt (209)-- 算法导论15.4 6题
六.设计一个 O(nlgn) 时间的算法,求一个 n 个数的序列的最长单调递增子序列.(提示:注意到,一个长度为 i 的候选子序列的尾元素至少不比一个长度为 i-1 候选子序列的尾元素小.因此,可以在 ...
- Mysql 增删改查语言系列
Mysql 数据语言系列 目录 Mysql 数据语言系列 一.数据定义语言 DDL 1 数据库规范 2 DDL 语言使用 2 创建视图 二. 数据操纵语言 DML 1 插入语法 2 更新语法 3 删除 ...
- vetur volar 是否可以共用,vue2 vue3项目 如何同时开发?
vetur volar 是否可以共用,vue2 vue3项目 如何同时开发? 先提问 以后再找答案 20220704 补答 vetur volar 不要一起装 vscode环境
- ACER 宏碁 笔记本无法进入 grub 引导 + 安全启动失败(security boot fail ) 解决办法
主要介绍让BIOS首先引导grub的方法 加一点:添加完新的启动选项以后,如果看不到添加的启动项,就先保存重启,再进 BIOS 就可以看到了 我是宏碁的笔记本,装了双系统.之前无意间进了一次 BIOS ...
- 【深度学习基础】基于Numpy的循环神经网络实现和反向传播训练
本文是<深度学习进阶:自然语言处理>.<神经网络与深度学习>和<动手学深度学习>的读书笔记.本文将介绍基于Numpy的循环神经网络的前向传播和反向传播实现,包括RN ...
- day22--Java集合05
Java集合05 11.HashSet课堂练习 11.1课堂练习1 定义一个Employee类,该类包括:private成员属性name,age 要求: 创建3个Employee对象放入HashSet ...
- 逆向通达信Level-2 续九 (无帐号打开itrend研究版)
此itrend研究版的版本比较旧. 本篇演示三图,用例进程同为0x4970. 1. itrend不支持脱机,游客登陆.没有帐号不能打开.现在以无帐号打开. 2. itrend支持高清,当打开主界面就会 ...