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 ...
随机推荐
- day04---虚拟主机网络配置的三种模式介绍
课程大纲 补充:安装系统过程中 分区的知识 1.虚拟软件使用方法 2.操作系统网络配置 3.虚拟主机网络设置 4.操作系统远程连接 5.远程连接排错思路 补充:安装系统过程中 分区的知识 1.企业常见 ...
- java+mysql学生信息管理系统
实现:mysql+eclipse(idea设置之后也可运行)+jdk8 功能: 管理员:管理登+管理员注册 学生:添加学生信息+删除学生信息+修改学生信息+查询学生信息+学生列表展示 界面展示: 详情 ...
- 【LeetCode动态规划#09】完全背包问题实战,其二(零钱兑换和完全平方数--求物品放入个数)
零钱兑换 力扣题目链接(opens new window) 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能 ...
- [Node] nvm 安装 node 和 npm
Node JS 安装 安装 node version manager (nvm) Windows: https://github.com/coreybutler/nvm-windows/release ...
- 【Azure Redis 缓存】VM 里的 Redis 能直接迁移到 Azure Cache for Redis ? 需要改动代码吗?
问题描述 原来部署在VM 里的 Redis 能直接迁移到 Azure Cache for Redis? 需要改动代码吗? 问题解答 以上问题需要从两个方面来解答. 第一:VM中Redis的数据转移到 ...
- 【Azure Redis 缓存】Redis的指标显示CPU为70%,而Service Load却达到了100%。这两个指标意义的解释及如何缓解呢?
问题描述 为什么Redis的指标显示CPU为70%,而Service Load却达到了100%, 如何来解释这两个指标,以及如何来缓解这样的情况呢? 问题回答 CPU指标:该值表示的是用于 Redis ...
- 【风控算法】二、SQL->Python->PySpark计算KS,AUC及PSI
KS,AUC 和 PSI 是风控算法中最常计算的几个指标,本文记录了多种工具计算这些指标的方法. 生成本文的测试数据: import pandas as pd import numpy as np i ...
- 摆脱鼠标操作 vscode-vim-use-readme.md
vscode-vim 学习笔记 梳理下自己定义的快捷键 Normal模式返回 ESC capsLock 双击shift ctrl+[ jj ctrl+c (这个键比较特殊 用习惯y的话,考虑这个) 一 ...
- Prometheus常用exporter及其常用监控指标
node-exporter常用监控指标 CPU相关指标: node_cpu_seconds_total{mode="idle"}:CPU空闲时间(秒)的总和.这是评估CPU使用率的 ...
- Android设备上运行live555的推流程序
在live555使用NDK21编译出arm64-v8a和armeabi-v7a中我们编译出了v8a和v7a的可执行文件 我们可以使用testH264VideoStreamer程序进行推流 我们将tes ...