为什么不能像 C 中的指针一样对待数组?

2023-12-20

我在 SO 上经常看到这个问题。也许没有那么多话......但是对于数组与指针的不同之处,人们一次又一次地感到困惑。所以我想我应该花点时间来问答一些关于这个问题的问题。

出于本次问答的目的,我们将假设使用 32 位系统,并且已声明以下内容:

char * ptr = "hello";
char arr[10] = "hello";
int iarr[10] = {0};

以下是我在 SO 上看到的困惑的问题列表。当我看到新的问题时,我会将其添加到我的问答列表中(其他人也可以随意添加,如果您发现任何错误,请纠正我!)

  1. 指针和数组不是本质上是一样的吗?
  2. 跟进:两者*(ptr) and *(arr), or ptr[0] and arr[0]给同样的东西,为什么?
  3. 怎么会arr and &arr是相同的值吗?
  4. 跟进:为什么我得到不同的值打印arr+1 vs &arr+1?

1) 指针不是数组。数组不是指针。不要那样想它们,因为它们是不同的。
我怎样才能证明这一点?想想它们在记忆中是什么样子的:

Our array arr is 10 characters long. It contains "Hello", but wait, that's not all! Because we have a statically declared array longer than our message, we get a bunch of NULL characters ('\0') thrown in for free! Also, note how the name arr is conceptually attached to the contiguous characters, (it's not pointing to anything). enter image description here

Next consider how our pointer would look in memory: enter image description here Note here we're pointing to a character array some place in read only memory.

所以虽然两者arr and ptr以相同的方式初始化,每个的内容/位置实际上是不同的。

这是关键点:
ptr是一个变量,我们可以将它指向任何东西,arr是一个常量,它将始终引用这 10 个字符的块。


2) The []是一个可以在地址上使用的“添加和引用”运算符。意思是arr[0]就等于说*(arr+0)。所以是的,这样做:

printf("%c %c", *(arr+1), *(ptr+1));

会给你一个“e e”的输出。不是因为数组是指针,而是因为数组的名称arr和一个指针ptr两者都恰好给了你一个地址。

#2 的要点:解引用运算符*以及添加和取消引用运算符[]不分别特定于指针和数组。这些运算符仅处理地址。


3)我没有一个非常简单的答案......所以让我们暂时忘记我们的字符数组,看看这个例子来解释:

int b;   //this is integer type
&b;      //this is the address of the int b, right?

int c[]; //this is the array of ints
&c;      //this would be the address of the array, right?

所以这是很可以理解的:

*c;   //that's the first element in the array

这行代码告诉你什么?如果我尊重c,然后我得到一个整数。这意味着简单c是一个地址。由于它是数组的开头,因此它是数组的地址,也是数组中第一个元素的地址,因此从值的角度来看:

c == &c;

4)让我暂时偏离主题……最后一个问题是地址算术混乱的一部分。我曾经看到一个关于 SO 的问题,暗示地址只是整数值......您需要了解在 C 中地址具有类型知识。也就是说:

iarr+1; //We added 1 to the address, so we moved 4 bytes
arr+1;  //we added 1 to the address, so we moved 1 byte

基本上是sizeof(int)是 4 并且sizeof(char)是 1。所以“向数组添加 1”并不像看起来那么简单。

那么现在回到问题,为什么arr+1不同于&arr+1?第一个是添加1 * sizeof(char)=1到地址,第二个是加1 * sizeof(arr)=10 到地址。

这就是为什么即使它们都“只加 1”,它们也会给出不同的结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么不能像 C 中的指针一样对待数组? 的相关文章

  • 为什么 int8_t 和用户通过 cin 输入显示奇怪的结果[重复]

    这个问题在这里已经有答案了 一小段代码让我发疯 但希望你能阻止我跳出窗外 看这里 include
  • 通过 $_SESSION 从一个脚本发送到另一个脚本期间数据丢失

    我正在尝试将一个充满属性的对象从一个 PHP 发送到另一个 PHP SESSION object obj where obj是一个用 foreach 循环指定的对象 foreach array of objects as obj SESSI
  • ClickOnce 应用程序错误:部署和应用程序没有匹配的安全区域

    我在 IE 中使用 FireFox 和 Chrome 的 ClickOnce 应用程序时遇到问题 它工作正常 异常的详细信息是 PLATFORM VERSION INFO Windows 6 1 7600 0 Win32NT Common
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 单个对象的 Monogame XNA 变换矩阵?

    我读过一些解释 XNA Monogame 变换矩阵的教程 问题是这些矩阵应用于 SpriteBatch Begin matrix 这意味着所有 Draw 代码都将被转换 如何将变换矩阵应用于单个可绘制对象 就我而言 我想转换滚动背景 使其自
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 如何区分用户点击链接和页面自动重定向?

    拥有 C WebBrowser control http msdn microsoft com en us library system windows forms webbrowser aspx在我的 WinForms 应用程序中 并意识
  • 为什么 Google 测试会出现段错误?

    我是 Google Test 的新手 正在尝试提供的示例 我的问题是 当我引入失败并设置GTEST BREAK ON FAILURE 1 或使用命令行选项 GTest 将出现段错误 我正在考虑这个例子 https code google c
  • 使用接口有什么好处?

    使用接口有什么用 我听说它用来代替多重继承 并且还可以用它来完成数据隐藏 还有其他优点吗 哪些地方使用了接口 程序员如何识别需要该接口 有什么区别explicit interface implementation and implicit
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • 在 Visual Studio 2010 中从 Fortran 调用 C++ 函数

    我想从 Fortran 调用 C 函数 为此 我在 Visual Studio 2010 中创建了一个 FORTRAN 项目 之后 我将一个 Cpp 项目添加到该 FORTRAN 项目中 当我要构建程序时出现以下错误 Error 1 unr
  • C# HashSet 只读解决方法

    这是示例代码 static class Store private static List
  • C# 中的合并运算符?

    我想我记得看到过类似的东西 三元运算符 http msdn microsoft com en us library ty67wk28 28VS 80 29 aspx在 C 中 它只有两部分 如果变量值不为空 则返回变量值 如果为空 则返回默
  • CMake 无法确定目标的链接器语言

    首先 我查看了this https stackoverflow com questions 11801186 cmake unable to determine linker language with c发帖并找不到解决我的问题的方法 我
  • AES 128 CBC 蒙特卡罗测试

    我正在 AES 128 CBC 上执行 MCT 如中所述http csrc nist gov groups STM cavp documents aes AESAVS pdf http csrc nist gov groups STM ca
  • “接口”类似于 boost::bind 的语义

    我希望能够将 Java 的接口语义与 C 结合起来 起初 我用过boost signal为给定事件回调显式注册的成员函数 这非常有效 但后来我发现一些函数回调池是相关的 因此将它们抽象出来并立即注册所有实例的相关回调是有意义的 但我了解到的
  • 如何在非控制台应用程序中查看 cout 输出?

    输出到调试窗口似乎相当繁琐 我在哪里可以找到cout如果我正在编写非控制台信息 则输出 Like double i a b cout lt lt b lt lt endl I want to check out whether b is z
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a
  • 如何从 ODBC 连接获取可用表的列表?

    在 Excel 中 我可以转到 数据 gt 导入外部数据 gt 导入数据 然后选择要使用的数据源 然后在提供登录信息后 它会给我一个表格列表 我想知道如何使用 C 以编程方式获取该列表 您正在查询什么类型的数据源 SQL 服务器 使用权 看

随机推荐

  • 标准 C++14 委员会草案是否公开?

    截至上周六 http isocpp org blog 2013 04 trip report iso c spring 2013 meeting 今天下午在英国布里斯托尔 ISO C 标准委员会通过了 通用 lambda 动态数组 C99
  • cuda 推力中的 fp16 支持

    我无法在推力 cuda 模板库中找到有关 fp16 支持的任何信息 甚至路线图页面也没有任何相关信息 https github com thrust thrust wiki Roadmap https github com thrust t
  • R如何安装指定版本的bioconductor包?

    我想使用的当前版本的软件包在生物导体上失败 然而 旧版本曾经可以工作 我想知道如何安装特定版本的生物导体包 提前致谢 在我的例子中 该软件包称为biomaRt 失败的版本是2 34 2 而2 34 0是成功的 重要更新 今年是2022年 我
  • Jersey:@PathParam,带逗号到 List

    我想用这种模式调用我的网络服务 resource 1 2 3 在我的类中 我想将参数绑定到对象列表 Path resource public class AppWS GET Path params public Response get P
  • 如何消除使用 randomForest 运行预测的“外部函数调用中的 NA/NaN/Inf (arg 7)”

    我对此进行了广泛的研究 但没有找到解决方案 我已经清理了我的数据集 如下所示 library raster impute mean lt function x replace x is na x is nan x is infinite x
  • Stack Overflow 与支持 JavaScript 的横幅配合使用效果最佳

    我试图模仿该网站的 Javascript 要求横幅 并且如果允许 启用 javascript 则隐藏以下 div 但我在页面加载时看到它的闪现 一瞥 div Craftystuff com works best with JavaScrip
  • 对正则表达式中的反斜杠感到困惑[重复]

    这个问题在这里已经有答案了 我对正则表达式中的反斜杠感到困惑 在正则表达式中 有特殊含义 例如 d表示十进制数字 如果在反斜杠前面添加反斜杠 则这种特殊含义就会丢失 在里面正则表达式指南 https docs python org 3 ho
  • 如何删除回收站中路径过长的文件夹或文件?

    我有一个程序可以删除并复制一些具有长路径的文件夹或文件 当长度 gt MAX PATH 时 在这个程序中我使用前缀 这使我可以删除具有长路径的文件夹或文件 但仅限于简单的功能Delete 我需要删除回收站中的文件 为此我需要使用SHFile
  • 如何在IntelliJ IDEA中选择配置文件?

    当我打开 Spring 配置文件并下拉选择配置文件时 为什么 IntelliJ IDEA 会打开一条消息 如果我选择关闭链接 为什么它不再出现 当您在配置文件弹出窗口中单击 关闭 时 它会更改设置并禁用所有 spring 上下文的面板 因此
  • sympy.plotting.plot 奇怪的 xlabel 位置

    当在 sympy 的绘图语句中将 xlabel 设置为字符串值时 标签将放置在图形的最右侧 如果程序中未设置标签 并且我单击复选标记并在那里设置标签 则它位于 X 轴的中间 这是一个例子 from sympy import sin from
  • 使用 PHP 客户端发布 Google+ 时刻时出现 401 未经授权的访问

    我试图使用 API 在 google 中发布一段时间 创建一个简单的示例 但收到 401 错误 我正在关注 Silvano Luciani 的脚步https plus google com SilvanoLuciani posts 2kMX
  • Angular 双花括号内的函数调用

    这是我在 Kendo UI 中的热图代码 div params compare h percentChange h current unit div Its works perfectly fine what the h current u
  • 通过 AJAX 传递图像[重复]

    这个问题在这里已经有答案了 基本上我想在提交表单时使用ajax传递图像文件并检索图像并通过电子邮件将其作为附件文件发送 这是form
  • 将 org.dom4j.Document 转换为 org.w3c.dom.Document 和 XML 签名时出现问题

    我有一些已经使用的课程DOM4J http dom4j sourceforge net 读取 XML 文件并提供 数据的 getter 方法 现在 我需要添加检查 XML 数字的可能性 签名 使用 org w3c dom 并遵循http j
  • GRPC 服务器响应延迟

    首先 是否有人对 GRPC 客户端 服务器实现与 websocket protobuf 客户端 服务器实现之间的吞吐量 延迟进行了性能比较 或者至少是类似的东西 为了实现这一目标 我正在尝试示例 JAVA helloworld grpc 客
  • Android 上现在已弃用 HttpEntity,有什么替代方案吗?

    随着 Android 5 1 的发布 所有 Apache http 内容似乎都已被弃用 看文档是没有用的 他们都说 This class was deprecated in API level 22 Please use openConne
  • 带有背景图像且无文本的 XHTML 锚链接

    是否有可能有锚链接 里面没有文字 有背景图像和固定尺寸 并且仍然有利于搜索引擎优化 CSS 示例 a display block width 50px height 20px background image url images back
  • HttpClient 无法在 Android 上运行

    我正在制作 Xamarin Forms 应用程序 它应该从 api 获取 JSON 然后允许显示它 到目前为止我的代码 public async void jsonDownload connect await downloadData pu
  • 用 C 语言写入十六进制(字节)

    我必须将十六进制字节写入文件 但遇到问题 例如 如果我有 unsigned char a 0x0 我使用 fwrite 写入文件 FILE fp fopen file txt wb fwrite a sizeof unsigned char
  • 为什么不能像 C 中的指针一样对待数组?

    我在 SO 上经常看到这个问题 也许没有那么多话 但是对于数组与指针的不同之处 人们一次又一次地感到困惑 所以我想我应该花点时间来问答一些关于这个问题的问题 出于本次问答的目的 我们将假设使用 32 位系统 并且已声明以下内容 char p