- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写一个简单的c程序来打印字符串数组中字符串的地址。程序如下:
#include <stdio.h>
int main(void)
{
char *words[] = {"hello", "cruel", "world"};
int count = sizeof(words) / sizeof(char*);
int i;
for(i = 0; i < count; i++){
printf("address: %p\n", (words+i));
printf("address: %p\n", &(words[i])); //<- why does this work?
printf("address: %p\n", words[i]); //<- not the same as first print?
printf("---\n");
}
return 0;
}
和输出:
address: 0x7fff043110f0
address: 0x7fff043110f0
address: 0x4006b4
---
address: 0x7fff043110f8
address: 0x7fff043110f8
address: 0x4006ba
---
address: 0x7fff04311100
address: 0x7fff04311100
address: 0x4006c0
---
现在我是这样理解的:words
是一个指向指针的指针,指向这个数组数组的首地址。
那么words[i]
是一个指向字符数组的指针,words[0]
指向“hello”的首地址,words[ 1]
指向“残酷”的首地址。
现在我尝试以不同的方式打印出字符串的地址。
第一种方法是有意义的:(指向words
的指针按一个指针的大小递增,然后我将其打印出来,将其格式化为指针)
在第二个中,我认为应该发生的情况:words[i]
返回指向索引单词的指针,并在其上使用 &
运算符返回地址。但我不清楚 %p
如何用于第一个打印语句中的指针类型和第二个语句中的地址类型。
对我来说有意义的是,如果第三个打印语句给出了第二个打印语句的输出。 ( (words+i)
和 words[i]
在指针上下文中是相同的?)
请有人帮我解决这个问题。谢谢
最佳答案
编译 C 代码时,您会得到一个二进制文件。无需讨论太多细节(即我正在简化),它由不同部分中的一些代码和一些数据组成,即 .code
部分和 .data
部分。思考 .data
部分中的内容会有所帮助。
char *words[] = {"hello", "cruel", "world"};
这会在您的 .data
部分中创建一些数据,您的编译器可能会以不同的方式执行此操作,但我使用 1 字节表示 char
,使用 4 字节表示指针:
0x00000000 'h' 'e' 'l' 'l' 'o' 0 ? ? <- Data for the "hello" string
0x00000008 'c' 'r' 'u' 'e' 'l' 0 ? ? <- etc.
0x00000010 'w' 'o' 'r' 'l' 'd' 0 ? ? <- etc.
左边的数字是数据部分内的十六进制地址。我已在 8 字节边界上对齐每个字符串,您的编译器可能会以不同的方式执行此操作,这就是我选择的方式。请注意,字符串以 nil 字节终止,问号表示下一位数据开始之前的两个附加(未初始化)字节(由我的对齐决策引起)。
如果你的数组是全局的,你也会得到这个数组:
0x00000018 0x00000000 <- 4-byte pointer to "hello" string
0x0000001C 0x00000008 <- 4-byte pointer to "cruel" string
0x00000020 0x00000010 <- 4-byte pointer to "world" string
在您的代码中,它不是全局的,而是在您输入函数时在堆栈上临时创建的。这就是为什么您看到的地址与字符串数据的地址有很大不同。我将假装它是一个全局的解释并使用上面的地址。
不用担心这里第一个指针的值实际上是NULL
。这些值会在运行的程序中发生变化,具体取决于程序所链接的其他 .data
以及程序加载到内存中的位置。重点是,我在这里用来解释的值是相对于您的 .data
部分的。
现在words
正如你所说,一个指向指针的指针。 words
的值为 0x00000018
- 它指向数组的开头(见上文)。
int count = sizeof(words) / sizeof(char*);
sizeof(words)
是 12(看上面的数据),sizeof(char*)
是 4,所以 count 是 3。
现在这是您需要了解的有关 C 中指针算术的内容:
编译器知道所指向的内容的大小,并且加法以该大小的倍数进行。考虑到words + i
- 编译器知道words指向一个指针,并且指针的大小是4,因此因为words
等于0x00000018
, words + 1
等于 0x0000001C
。
现在 words[i]
与 *(words + i)
相同 - 这意味着 (words + i)
的内容。当i = 1
时(words + i)
将是0x0000001C
,并且查看数据部分,该地址的内容(编译器知道是一个 4 字节指针)是 0x00000008
。这是一个指向“cruel”
字符串的指针。
您的另一个实验是使用 &words[i]
- 这与 words + i
相同,它是数组中元素的地址,而不是它的内容指向。
由于words
数组中的指针指向char
,因此words[2][1]
将按如下方式计算:
// First get words[2]
char *words2 = *(words + 2) <- Contents of 0x00000020 as char*
// words2 now holds 0x00000010 - the address of the "world" string
char result = *(words2 + 1)
// result now holds 'o'
请注意,其中 words
是指向指针的指针,上面的 words2
是指向 char
的指针,因此 words2 + 1
code> 是 0x00000011
- 它添加了 1,因为 sizeof(char)
是 1。0x00000011
的内容是 'o '
。如果您想要该 'o'
字符的地址,您可以执行 &words[2][1]
并得到 0x00000011
。
关于c - 了解指针数组语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29886538/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!