如何在 C 中处理指针? [复制]

2024-03-17

我对 C 很陌生,在学习指针方面遇到了一些问题。我尝试了交换,这就是我能用它们做的所有事情:)我知道每个变量在内存单元中都有自己的地址(这是我的讲师告诉我们的),并且每个变量的值都可以通过转到其关联的地址来获取,然后获取其中存储的值。我见过一些函数头,例如:

int doSomething(char **hihi);

我的头很困惑。我知道指针也是一个变量,它只在其存储单元中存储地址信息。我读到它们与数组密切相关

arr = &arr[0];

这就是我对指针的了解,我想知道如何加深我对指针的了解。我搜索了网络,但找不到任何有用的涵盖指针的备忘单。我也想知道为什么它们如此重要,有没有什么方法可以在不使用的情况下了解实际发生的情况printf()打印他们的地址(p)和值(\*p)??


打印地址和值是查看它们的合理方法。但是,如果您可以启动并运行调试器,那就更好了,因为您可以更快地跟踪指针,观察它们在您单步执行时的变化,等等。

如果您熟悉 Windows 中的“快捷方式”或 Linux 文件系统中的软链接,那么在您开始使用时,将指针视为另一个对象(无论该对象是是一个结构体、一个内置类型、另一个指针等)。

快捷方式仍然是一个文件。它在磁盘驱动器上占用自己的空间,它引用另一个文件,并且可以修改它以引用与以前不同的文件文件。类似地,C 中的指针是一个占用内存的对象,包含另一个内存位置的地址,并且可以通过分配给它来更改为包含不同的地址。

一个区别是,如果您双击快捷方式,它的行为就好像您双击了它指向的内容一样。指针的情况并非如此 - 您始终必须使用“*”或“->”显式取消引用指针才能访问它指向的内容。另一个区别是,在 C 中使用指向某些内容的指针是很常见的。

至于行话,不幸的是你只需要学习它。 “int doSomething(char **hihi)”的意思是“一个名为 doSomething 的函数,它返回一个整数,并以一个指向 char 的指针作为参数”。关键的一点是“char ** hihi" 的意思是“一个指向字符的指针。我们将把指针指向字符的指针称为“hihi”。您说 hihi 的“类型”是 char**,而 *hihi 的“类型”(当您取消引用指针时得到的)是char*,**hihi 的类型是 char。

在 C 中,指向 char 的指针通常表示字符串(换句话说,它是指向以 NUL 结尾的数组中第一个字符的指针)。通常“char *”表示“字符串”,但并非必须如此。它可能只是意味着指向一个字符的指针。有点像 Windows 中 1 字节文件的快捷方式(无论如何,对于 FAT32),C 中指向 char 的指针实际上比它指向的东西大:-)

同样, char** 通常不仅意味着指向一个字符串指针的指针,还意味着指向一组字符串指针的指针。可能不会,但如果确实如此,那么下面的小图可能会有所帮助:



hihi
 ____            ____                     ________     _________      _______
|____|   -----> |____|  *hihi       ---> |___A____|   |___B_____|    |___C___|
                |____|  *(hihi+1)   ------------------^              ^
                |____|  *(hihi+2)   ---------------------------------|
                | ...|    etc.
  

hihi 指的是塔式块的工作,这是我表示指针数组的方式。正如您已经指出的,我可以写 hihi[0] 代替 *hihi,hihi[1] 代替 *(hihi+1),等等。

这是一个连续的内存块,其中每个指针大小的块都包含另一个内存块的地址(即,它“指向”),该内存块位于天知道在哪里,包含一个或多个字符。所以,hihi[0]是字符串A的第一个字符的地址,hihi[1]是字符串B的第一个字符的地址。

如果 hihi 不指向数组,而只是指向单个指针,那么塔楼就是平房。同样,如果 *hihi 不指向字符串,只指向一个字符,那么细长的块就是一个正方形。您可能会问,“我怎么知道塔楼有多少层?”。这在 C 编程中是一件大事 - 通常函数文档会告诉你(它可能会说“1”,或“12”,或“足以完成你告诉我要做的事情”,否则你会通过楼层数作为额外参数,否则文档会告诉您该数组是“NULL 终止的”,这意味着它将继续读取,直到看到地址/值 NULL,然后停止。main 函数实际上执行以下两个操作:第二件事和第三件事 - argc 包含参数的数量,and为了安全起见,argv 是以 NULL 结尾的。

因此,每当您看到指针参数时,您都必须查看该函数的文档,以了解它是否需要指向数组的指针,如果是,则该数组必须有多大。如果你不小心这一点,你将创建一种称为“缓冲区溢出”的错误,其中一个函数需要一个指向大数组的指针,你给它一个指向小数组的指针,它会在末尾乱写乱画你给它的东西并开始破坏记忆。

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

如何在 C 中处理指针? [复制] 的相关文章

随机推荐

  • h2o.glm 与 R 中的线性回归的 glm 不匹配

    我一直在将 H2O ai 版本 3 10 3 6 与 R 结合使用 我正在努力用 h2o glm 复制 glm 的结果 我期望得到完全相同的结果 在这种情况下 根据均方误差进行评估 但我发现 h2o 的准确性一定更差 由于我的模型是高斯模型
  • 使用 CSS 影响 iframe 内的 div 样式

    是否可以仅使用 CSS 来更改驻留在页面 iframe 内的 div 的样式 你需要 JavaScript 它与在父页面中执行此操作相同 只是您必须在 JavaScript 命令前加上 iframe 的名称 请记住 同源策略适用 因此您只能
  • Java中JTextArea的自动动态扩展/收缩

    我首先创建一个特定大小的 JTextArea 用户可以在其中添加文本 但如果文本太长 垂直或水平 则会被截断 我希望 JTextArea 自动扩展或收缩 用于删除文本 我将来可能允许用户更改字体和字体大小 因此如果我可以避免使内容增加 减少
  • C# 和 WPF - 使用 SecureString 作为客户端 HTTP API 密码

    在编写 WPF 应用程序时 PasswordBox将输入的密码存储为SecureString 这完全有道理 但是 我想通过 HTTP API 发送密码 并且HttpClientPostAsync 似乎接受表单编码数据的字符串 我知道其他人也
  • CheckedListBox - 通过文本搜索项目

    我有一个CheckedListBox绑定到一个DataTable 现在我需要以编程方式检查一些项目 但我发现SetItemChecked 方法仅接受项目索引 有没有一种实用的方法可以在不知道项目索引的情况下通过文本 标签获取项目 注意 我对
  • 无法在 Linux 上安装 sqldf

    我在 Linux 上运行 R 版本 2 14 1 当我尝试安装 sqldf 时 install packages sqldf dependencies TRUE 我收到以下错误 这些错误导致从终端运行命令 就像使用 Rcmdr UI 一样
  • mongoDB 错误:错误:无法连接到 [localhost:27017]

    我正在尝试安装habitrpg https github com busterroni habitrpg在本地 但我在输入后不断收到 mongoDB 错误node src seed js Error failed to connect to
  • C# Mono Linux - 抓取全局剪贴板的内容

    我试图简单地从剪贴板 抓取 文本并将其放入变量中 我在做这件事时遇到了很多麻烦 我尝试过使用 Gtk Clipboard Get Gdk Atom Intern PRIMARY true 到目前为止 我的代码只是将 Gtk Clipboar
  • youtube-api removeEventListener 不工作

    我可以很好地添加事件 addEventListener onStateChange handleStateChange 但当尝试删除该事件时 却没有 removeEventListener onStateChange handleState
  • 获取当前位置div的ID

    我有n个 section 在一个页面中 每个页面都提供了 id 例如 page1 page2 在顶部我放置了 2 个按钮 即 上一个 和 下一个 当按下上一个按钮时 它将滚动到上一个 section 与下一个类似 section 按 下一步
  • JAX-WS - 添加 SOAP 标头

    我正在尝试创建一个独立的客户端来使用一些网络服务 我必须将我的用户名和密码添加到 SOAP 标头中 我尝试添加凭据 如下所示 OTSWebSvcsService service new OTSWebSvcsService OTSWebSvc
  • Facebook 应用程序请求通知未显示在移动网络应用程序的 Facebook iOS 应用程序中

    我有一个配置为 Facebook 画布应用程序的 Facebook 应用程序以及一个包含网站和移动网站 URL 的网站 当应用程序发送应用程序请求 邀请 时 它们仅显示在桌面浏览器中的收件人通知中 而不显示在 Facebook iOS 应用
  • Firebase DatabaseReference 按指定值过滤

    假设我有这个 firebase JSON 结构 我需要获取属性 from 等于 this 的所有问题 我知道我可以使用 Volley 来创建 StringRequest 并从我的 questions json 中获取所有值 然后 在客户端
  • 如何让服务帐户只能访问一个存储桶(Google Cloud)?

    如何提供服务帐号只能访问一个桶 如果你以防万一想再给一个第3方服务访问您的private bucket 问题是默认的 服务帐户 可以访问所有存储桶 但我不知道如何将其限制为仅限一个存储桶 是否可以通过仪表板或仅通过控制台来实现此目的 如果可
  • 向样式组件添加过渡

    我在 React 中有以下组件 const Button styled div width 30px height 30px position absolute right 2em top 50 transform translateY 5
  • 使用秒表分析 .NET 应用程序

    似乎没有免费的 NET 性能分析器可以逐行进行分析 因此 我正在考虑使用秒表进行分析 免费即自由 即许可证包括商业应用程序 编辑 为了回应那些告诉我 购买分析器 的人 我愿意 但如果我能花那么多钱 我会把它花在其他东西上 我试图让我的老板相
  • 如何仅循环 select() 的 fd_set 结果中的活动文件描述符?

    所以在我当前的服务器实现中 目前是这样的 void loop step 1 clear set fd set readfds while true step 1 FD ZERO readfds step 2 loop through soc
  • Node.js UDP (dgram) 处理 DNS 解析错误

    我正在使用 Node 的内置数据报 UDP 套接字进行简单的 UDP 发送 http nodejs org docs v0 3 1 api dgram html http nodejs org docs v0 3 1 api dgram h
  • Django 从注释计数中排除

    我有以下申请 from django db import models class Worker models Model name models CharField max length 60 def str self return se
  • 如何在 C 中处理指针? [复制]

    这个问题在这里已经有答案了 我对 C 很陌生 在学习指针方面遇到了一些问题 我尝试了交换 这就是我能用它们做的所有事情 我知道每个变量在内存单元中都有自己的地址 这是我的讲师告诉我们的 并且每个变量的值都可以通过转到其关联的地址来获取 然后