我是计算机科学专业一年级的学生,我们将C编程语言作为我们的主题之一。既然这是我第一次接触任何编程语言,请原谅我对基础知识的绝对了解。
因此,我试图理解一个简单的 Hello World 程序,尤其是它在内部的工作方式。该程序是这样的:
#include <stdio.h>
void main() {
printf("Hello World!\n");
}
尽管我通过Google找到了大量有关该主题的在线资源,例如:
https://www.daniweb.com/programming/software-development/threads/448766/gdb-debugger-problem和http://osteras.info/personal/2013/10/11/hello-world-analysis.html等。
这些非常令人难以置信,我仍然试图一一理解。目前,我停留在该部分(在我引用的大多数资源中)说
printf
函数,基本上是内部调用
_IO_puts
现在它如何一直到达那里,这是我仍在尝试理解的东西,而这并不是我对这个问题的看法。
我担心的是,当我抬起 _IO_puts 功能时,它显示如下内容:
int _IO_puts (const char *str)
从这里拍摄: https://code.woboq.org/userspace/glibc/libio/ioputs.c.html
所以我的假设是,需要传递给上述函数的所有内容都是字符串。但是,当我查看GDB代码时,我看到它显示了这样的内容:
_IO_puts (str=0x555555554d60 "Hello World!")
现在我的问题是,上面的 str = 0x555555554d60 是什么?
答案 0 :(得分:0)
现在我的问题是,上面的str = 0x555555554d60是什么?
C语言通过传递字符串的第一个字符的地址来传递字符串。字符串的结尾由内存中的零字节标记。大概0x555555554d60是此时虚拟内存中“ Hello World!\ 0”的第一个字符的地址。
答案 1 :(得分:0)
str=0x555555554d60 "Hello World!"
就是gdb
打印此参数的方式。它确实尝试在其打印输出中包含您可能会有所帮助的所有信息。 此打印输出受原始代码的C语法启发 ,但到目前为止,它并不是正确的C代码。
str=
自变量在编译后的代码中没有名称。但是gdb
可以推断原始C代码中的变量名称。由于通常为变量赋予名称以使其含义更容易理解,因此gdb
告诉您此特定变量称为str
。
=0x555555554d60
所涉及的变量是一个指针,因此它包含一个内存地址。 gdb
告诉您这是传递给函数的地址。
"Hello World!"
因为自变量是char*
,并且char*
通常用于传递字符串,所以gdb
有助于添加字节{{ 1}}存储在传递的地址后面。即'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0
精确地存储在地址'H'
处,0x555555554d60
在'e'
处再找到一个字节,依此类推,直到编译器找到终止的{{1} }地址0x555555554d61
处的字节。
它将打印此信息,以便您可以一目了然:“啊,是的,它正在将地址0
作为参数0x555555554d6c
传递给函数,而该参数恰好是内存中的字符串0x555555554d60
。