惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - Franky
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog
The GitHub Blog
The GitHub Blog
J
Java Code Geeks
F
Full Disclosure
V
V2EX
The Register - Security
The Register - Security
罗磊的独立博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
云风的 BLOG
云风的 BLOG
T
Troy Hunt's Blog
Microsoft Security Blog
Microsoft Security Blog
Help Net Security
Help Net Security
P
Privacy & Cybersecurity Law Blog
K
Kaspersky official blog
博客园 - 聂微东
Recorded Future
Recorded Future
I
Intezer
S
Schneier on Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
H
Hacker News: Front Page
SecWiki News
SecWiki News
M
MIT News - Artificial intelligence
Security Latest
Security Latest
Attack and Defense Labs
Attack and Defense Labs
A
About on SuperTechFans
aimingoo的专栏
aimingoo的专栏
宝玉的分享
宝玉的分享
T
Tenable Blog
B
Blog
N
News | PayPal Newsroom
P
Proofpoint News Feed
D
Docker
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
C
Cisco Blogs
A
Arctic Wolf
T
Threat Research - Cisco Blogs
I
InfoQ
Stack Overflow Blog
Stack Overflow Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
GbyAI
GbyAI
P
Palo Alto Networks Blog
Engineering at Meta
Engineering at Meta
Hugging Face - Blog
Hugging Face - Blog
Latest news
Latest news
Project Zero
Project Zero

机核

游戏性能旗舰最强之选,一加 Ace 6 至尊版国补到手价2999元起 6元钱自己更换电动车刹车线 《生化危机9:安魂曲》编剧Haris Orkin专访 摸金游戏?音乐游戏!暗区新赛季这把能弹的琴有何来历? 好评国产武侠SRPG《息风谷战略》免费DLC现已推出 | 机核 GCORES 碎片 《生化危机:安魂曲》将于5月实装首个免费更新内容 | 机核 GCORES 新锐东方游戏,谱写世界新章! 沉浸式恋爱视觉小说游戏《心象演算》免费试玩版现已正式上线 | 机核 GCORES 互动影游《代号三国:龙起》上线!穿越三国与曹操并肩、与佳人同行、与权谋博弈! 《老头收集梦想生活》,游戏酒桌会6,录音笔VOL.689 | 机核 GCORES 破界·共生——《白日梦:无限世界》五大核心游戏特点解析 价格已到史低,锐龙5 9600X/锐龙7 9700X正适合抄底 时间循环之旅即刻启程!《归环》一周目测试今日开启 热门在线韩游变魂游,洛奇衍生作能否打破“花瓶”魔咒? LG UltraGear evo 全新高端显示器系列:当“5K”遇见“AI”,不止强大,更懂热爱 反套路三国互动影游《代号三国:龙起》今日上线! 愿望单登记人数突破10万!备受瞩目的“女儿养成游戏” 《梦幻魔法公主》今日于Steam平台上线!限时八折优惠中 《黑神话:悟空》全球音乐会2026巡演将于4月29日12时开票 | 机核 GCORES “Snowguelike”生存肉鸽挖矿新作《蛙穿雪境》公布发售日期,5月7日正式上线 | 机核 GCORES 重塑移动办公、AI创作新境!全新华硕灵耀Air系列、ProArt 骁龙版震撼首发,创芯未来 均分88:《Saros》媒体评分汇总 | 机核 GCORES 上海烛龙公布合作遗迹探险游戏《吉时已到》首支预告片 | 机核 GCORES 首个独立游戏《萝薇日记》已上线Steam! 烛龙新IP《吉时已到》首曝,打造国内首款中式合作遗迹探险游戏 喜加一:《暗黑破坏神Ⅳ》国服现已开启限时免费领取本体活动 | 机核 GCORES 新版《生化危机》电影定于9月18日上映,官方网站现已上线 | 机核 GCORES 《冲就完事模拟器2》“星球大战”联动DLC正式宣布 | 机核 GCORES SteamController将于5月4日发售,售价99美元 | 机核 GCORES 事已至此,内存这么用也算省钱了,“2+1”非对称双通道应用实测 505游戏母公司现已收购《明末:渊虚之羽》IP | 机核 GCORES 基石 手动杂谈12|格斗游戏也能讲好故事 | 机核 GCORES I Love You Mr Snowball 我的向日葵小姐 会比GTA6先发售吗?最硬核的生存游戏《DAYZ》要推新DLC了 周记02:在2026遇到新怪谈 什么硬件,能让游戏Loading界面快速消失? | 机核 GCORES GadioSpec《百年风云世界杯》免费试听集 | 机核 GCORES 百年风云世界杯Vol.1丨足球崛起 | 机核 GCORES 100年前,一群人提前替我们经历了AI恐惧 | 机核 GCORES 《呼啸山庄》2026 ——一辆当代艺术的大卡车冲撞了我的大脑 手游《天穗之咲稻姬:日之香巡灵传》宣布将于7月27日停服 | 机核 GCORES 集结梦之队,征战世界杯,《最佳球会ONLINE》上线Steam 山水绝景随心拼 休闲建造游戏《千里山河录》Steam商店页公开 巫师帽、法袍、魔杖,为什么它们是影视、游戏里的法师必备三件套? 《无鞘信使》-第一章 复古风自动战斗肉鸽《终结之终结》Steam商店页面现已上线 电脑里有一款不破不立的MMO,录音笔VOL.688 | 机核 GCORES 《生化危机》30周年纪念周边发售,这次是真的“保护伞” 可靠耐用+AI全能,惠普战66 2025锐龙版深度体验 《时之书:无尽终章》关卡“大航海时代”全球首次公开 经典名作《乌龙派出所》改编经营模拟游戏《乌龙派出所~阿两的商店街物语~》正式宣布支持简体中文 明日开冲,解锁反套路三国互动影游《代号三国:龙起》即将上线 独立游戏《这是我的宝藏!》已发售~ 降低难度不是唯一解,无压力死亡也是好体验 Netflix官宣新片《普通人》:讲述韩国现代史上的权力风暴 《生化危机:安魂曲》全球销量现已突破700万份 《绝地鸭卫》PC版5月15日正式发售 亡妻回忆录?女性向情感叙事游戏《S-mail》现已正式发售 全新酷黑风格,酷睿Ultra 200S PLUS的高性价比搭档!七彩虹BATTLE-AX B860M-PLUS S WIFI7 V20 超级黑刃主板测评 胖狗 索尼发布了港台地区PS5产品价格调整公告,将于5月1日起实施 二次元怪猎+性感美女!《碧蓝幻想:无尽黄昏》开启Beta公测 这款怪谈类型中式恐怖游戏居然更新了?! 《百日战纪 -最终防卫学园-》改编漫画将于今年冬季开启连载 《如被附身,请致电我们》:匈牙利黑色幽默恐怖小说 《竹屿山房杂部卷五》(译文) 大树 超越引擎 摄影分享丨四月 碎片杂记vol.72 当老式FPS与老式动画技术碰撞出新时代的火花—《神探杰克鼠》 想做独游,如何避免首个项目就褒姒? 在线多人动作游戏《OCTOPinbs》将于5月12日上线Steam! 《酒鬼女神的酒诡》确定将于2026年登陆Steam 《CRYMELIGHT》将于11月5日(周四)正式发售!4月25日开始预购! 钢铁国度MKI部落Evolution,蛮兵部分 【钢铁国度】部落-Primal MK I,蛮兵部分 这是一个高中生用ai跑出来的作品,我自称他为物理神话 钢铁国度MKI部落Metamorphosis,蛮兵部分上 钢铁国度MKI部落Metamorphosis,蛮兵部分下 INDIE Live Expo于4月25日举办:首发9款新作,超200款独立游戏亮相 暗黑卡牌策略新作《魔忌:穷鼠啮狸》发布全新中文试玩版和发售预告片,4月30日正式上线在即 战锤40K长篇小说:变节者・苦难主宰(三)(全书完) 战锤40K长篇小说:变节者・苦难主宰(二) 战锤40K长篇小说:变节者・苦难主宰(一) 英语语言学习丨短语专题1:短语的特点 唯一的EVE战争 【少前同人】【M200】战术人形会梦见音乐会吗 【昏迷3】即将发售,前作主角悉数到场!“恶灵”宋老师化身可操控角色 业内人士:游戏公司“十有八九”使用生成式AI,包括卡普空 欢庆一周年:《光与影:33号远征队》全新纪念艺术图、超值折扣与免费更新同步上线 才刚刚开始呢 【抽奖】《星际卡车司机》推出免费大型更新,四折平史低折扣进行中 四人合作FPS游戏《佣兵猎手》抢先体验重大更新 1 现已上线 Raw Fury新作《深馅地牢 Deep Dish Dungeon》将于今秋加入 XGP 塔防幸存者游戏《魔怪来袭》推出首个 DLC 《饿狼传说:群狼之城》1周年纪念!新DLC“沃尔夫冈·克劳萨”今日参战 猫狗相伴 欢乐闯关 双人合作平台跳跃游戏《猫狗同行》上线Steam商店页 《同行:月球逃脱》(Together: Moon Escape)上线将于明日上线Steam
通过C语言入门计算机科学4:数组和指针
韩大 · 2024-11-04 · via 机核

我个人认为,C 语言指针的难以掌握的原因有以下几个:

  1. 指针的声明符号—— * 星号同时也是“解引用”操作符。在不同的语句中的含义是不一样的。

  2. 指针是一种复合类型,它需要指定自己是属于“何种变量”的指针

  3. 指针是可以运算的,其数值的变化和指针类型有关。

  4. 程序员可以使用指针读写任何地址的内存,如果不了解程序对于内存的运作机制,可能会访问了一些无法预知结果的地址,造成各种进程退出导致的故障

指针、解引用、取地址

我们先用一个简单的例子来了解指针的最基本用法:

#include <stdio.h> int main() { int i = 10; int *p; p = &i; printf("var i addr: %llu, *p content: %d\n", p, *p); *p = 20; printf("var i now: %d\n", i); }

以下是程序的返回:

var i addr: 272537222788, *p content: 10 var i now: 20

指针这种类型的变量,含义是“指向某个变量地址的变量”,也就是说,指针变量的内容,是另外一个变量的内存地址。内存地址也是一个数字,在 64 位操作系统中,长度是 8 个字节。

注意指针是一个复合类型变量,也就是说,在声明的时候,除了 * 号外,必须在前面带上一个基本变量的类型,表示指针“指向”的变量是什么类型的。你可以选择 char\int\float 等,如果有一些情况下无法确定“指针的类型”,可以用 void * 来声明一个“通用类型”的指针。

在上面的代码里,int *p; 声明了一个“int 类型的指针” p 变量。而 p = &i 的功能是,把变量 i 的内存地址的值,写入到变量 p 里面去。这里的 & 符号的功能是“取地址操作符”,意思就是把某个变量的地址读取出来。

在后面的代码 printf() 代码中,我们尝试打印了指针变量 p 和 *p 的内容:

  • 我用了 %llu 作为占位符打印 p 的内容,因为 p 作为指针变量,长度是 64 位(8 个字节),比之前我们用的 int 类型变量的 4 个字节要大,所以使用了的 %llu 意思是按 long long unsigned 长无符号整数(8 个字节)的格式来打印 p 的内容。clang 编译的时候,会警告我们:变量 p 是一个指针类型变量,不是一个“长无符号整数”类型,怀疑我们可以写错了。另外一种常见的打印指针的占位符号是 %p,如果你用 %p 来打印指针,clang 就不会抱怨了。

  • 我也用了 %d 来打印 *p 的值。在这里 * 星号的作用是“解引用操作符”,功能是把后面的 p 的值,作为一个内存地址,然后去读取此内存地址中的值。由于 p 是“int 类型的指针”,所以 *p 的计算结果,就是一个 int 类型的值。于是可以用 %d 来打印。

解引用操作符 * 是操作指针指向内存的内容的符号,不但可以用来读取指定内存的值,同样可以用来把数据写入这块内存。后面的代码 *p = 20; 这一行,就是对 p 指向的内存,写入了数值 20。最随后的 printf() 代码中,我们可以看到变量 i 的值确实被改成了 20。

针对指针变量,有两个操作符很常见,需要了解清楚:

  • &:取地址操作符,表示取一个变量的地址。我们往往把这个操作的结果赋值给一个指针变量。

  • *:解引用操作符,表示获取一个指针(地址)所指向的内存的变量。我们常常用来读取指针指向变量的值,或者修改这个变量的值。需要注意的是:* 在变量声明的语句中表示“指针类型”而不是“解引用”的意思。

C 字符串

如果我们只是用 &* 来操作一个变量的指针,那么指针本身作用和变量没多少差别,看起来也没什么用处。但是,如果我们需要处理的不是一个变量,而是“一批”变量,指针就是一个很有用的工具了。而所谓的“一批变量”,最常见的就是字符串了。

在 C 语言当中,是没有“字符串”这个变量类型的。而绝大多数的其他编程语言,都有“字符串”类型,为什么 C 语言没有呢?我认为最基本的原因是:

C 语言的变量类型代表了一个特定的内存长度,字符串的长度是不固定的,所以没法给“字符串类型”一个长度设定。

那么 C 语言要处理的最常见的文件应该如何办呢?最简单的办法就是使用“数组”。所谓“数组”,其实就是一批变量,这些变量一般是连续存在的,也就是说在内存里面互相挨着的。我们要存放一段字符串“abc”的话,就声明三个 char 类型变量组成的数组,依次在数组中放入 'a' 'b' 'c' 三个值就好了。C 语言为数组提供了“下标”的方法来代表里面的每一个变量(又叫做元素),str[0] 表示第一个变量(元素),str[1] 表示第二个变量,依次类推。

然后,用“字符数组”的方式来存放字符串,还有一个问题需要解决:就是“字符串”长度该如何表示?由于我们可以声明一个 10 个元素的字符数组,仅仅存放 5 个字符的内容,如果没有办法知道,内容在第 6 个字符处结束,那么可能会让程序处理一些完全不需要的内容。C 语言为了解决这个问题,设计了一个直观但又坑爹的方法:

把字符变量中的数字 0,认为是字符串结束的符号。 数字 0 在 ASCII 编码表当中是 NUL 符号,被认为是“没有字符”的意思。

比如我们有一个字符数组 str[10],长度是 10 个字节,我们如果想存放字符串"abc",那么我们需要把 str[0] 写入 'a',str[1] 写入 'b',str[2] 写入 'c',str[4] 写入 0。这样我们从字符数组 str 的下标 0 开始读内容,一直读到第一个内容为 0 的元素为止,就是这个字符串的全部内容了,如果数组第 4 个元素以后还有内容,也被看成是没有意义的数据,直接被忽略掉。printf() 的占位符 %s 就是根据这个规矩进行工作的。下面这个例子就说明 C 字符串是怎么使用的,所以程序中打印的结果,只有 “abc”,而后面的“defghi”都不会显示:

#include <stdio.h> int main() { char str[10] = {'a', 'b', 'c', 0, 'd', 'e', 'f', 'g', 'h', 'i'}; printf("str: %s ptr: %p\n", str, str); }

运行结果:str: abc ptr: 0000004C584FFECE

上面说了 C 字符串的方案,但是和“指针”又有什么关系呢?是不是作者逐渐忘记了标题?——并不是,在上面的 printf() 代码中,有一个 %p 的占位符,打印的是字符数组变量 str,可以看到打印出来一个地址信息。实际上一个数组变量,如果不带下标的话,就是这个数组的第一个元素的指针。

之所以 C 语言如此设计,正是因为指针往往用来操作一个数组。如果我们有两块代码,都需要使用同一个数组,那么使用这个数组的第一个元素的地址,比起把数组复制来复制去要效率搞的多。下面我们可以看一下数组的写法,和指针的写法是如何对应的。

#include <stdio.h> int main() { char *str = "abc"; printf("str: %s ptr: %p\n", str, str); for (int i = 0; i < 4; i++) { printf("str[%d]: %c|%c\n", i, str[i], *(str+i)); } }

以上程序的运行结果:

str: abc ptr: 00007FF78EC07320 str[0]: a|a str[1]: b|b str[2]: c|c str[3]: |

这段程序的 char* str = "abc"; 这一行,其中 "abc" 定义了一个字符数组,内容是 {'a', 'b', 'c', 0},而 char* str 的指针内容,指向了 "abc" 这个字符数组的第一个元素。

程序后面的 for 循环,运行了四次,每次都通过下标操作,显示了 str[0]...str[1] 的内容,这里可以看到,就算 str 不是一个字符数组变量,但还是能通过下标[i]的写法来读取数组的元素内容。

而后面的*(str+i)这段,表示的是:用 str 的值(地址)加上 i,这样就指向了数组第 i 个元素的内存,然后用 * 解引用操作符读取了对应内存的值。上面的这个过程,其实和用下标的写法 str[i] 是等价的。C 语言中的所有数组的功能,是可以使用指针来完成所有操作的。

C 语言的变量就是一块内存,其实数组也是一块内存,数组的长度表示这块内存可以分成多少段(元素)来访问,数组的类型表示每段(元素)的长度是多少。