Gal*_*axy 4 c pointers c-strings literals
据我了解,以下代码的工作原理如下:
char* cptr = "Hello World";
Run Code Online (Sandbox Code Playgroud)
"Hello World"存在于.rodata程序记忆的部分.字符串文字"Hello World"返回一个指向字符串基址的指针,或者所谓的"数组"中第一个元素的地址,因为字符在内存中顺序排列,它将是'H'.这是我的小图,因为我可视化存储在内存中的字符串文字:
0x4 : 'H'
0x5 : 'e'
0x6 : 'l'
0x6 : 'l'
0x7 : 'o'
0x8 : ' '
0x9 : 'W'
0xa : 'o'
0xb : 'r'
0xc : 'l'
0xd : 'd'
0xe : '\0'
Run Code Online (Sandbox Code Playgroud)
所以上面的声明变成:
char* cptr = 0x4;
Run Code Online (Sandbox Code Playgroud)
现在cptr指向字符串文字.我只是在编写地址.
0xa1 : 0x4
Run Code Online (Sandbox Code Playgroud)
现在这段代码如何工作?
char cString[] = "Hello World";
Run Code Online (Sandbox Code Playgroud)
我假设在前面的情况下"Hello World"也降级为'H'和0x4的地址.
char cString[] = 0x4;
Run Code Online (Sandbox Code Playgroud)
我在=初始化char数组时使用的是重载赋值运算符.据我所知,仅在C字符串的初始化时,它会将char-by-char从给定的基址开始复制到C字符串中,直到它在复制的最后一个char时命中'\ 0'.它还为所有字符分配足够的内存.因为重载运算符实际上只是函数,我认为它的内部实现类似于strcpy().
我希望有一位经验丰富的C程序员确认我对这段代码如何工作的假设.这是我对字符串文字中的字符复制到其中后的C字符串的可视化:
0xb4 : 'H'
0xb5 : 'e'
0xb6 : 'l'
0xb6 : 'l'
0xb7 : 'o'
0xb8 : ' '
0xb9 : 'W'
0xba : 'o'
0xbb : 'r'
0xbc : 'l'
0xbd : 'd'
0xbe : '\0'
Run Code Online (Sandbox Code Playgroud)
再一次,地址是任意的,重点是堆栈中的C字符串与.rodata内存中的字符串文字不同.
我想做什么?我正在尝试使用char指针暂时保存字符串文字的基址,并使用相同的char指针(字符串文字的基址)来初始化C字符串.
char* cptr = "Hello World";
char cString[] = cptr;
Run Code Online (Sandbox Code Playgroud)
我假设"Hello World"评估它的基地址,0x4.所以这段代码应该是这样的:
char* cptr = 0x4;
char cString[] = 0x4;
Run Code Online (Sandbox Code Playgroud)
我认为它应该没有什么不同,char cString[] = "Hello World";因为"Hello World"评估它的基地址,这就是存储在char指针中的内容!
但是,gcc给了我一个错误:
error: invalid initializer
char cString[] = cptr;
^
Run Code Online (Sandbox Code Playgroud)
您对内存布局的理解或多或少是正确的.但是你遇到的问题是C中的初始化语义之一.
=此处声明中的符号不是赋值运算符.相反,它是语法,为正在实例化的变量指定初始化程序.在一般情况下,T x = y;是不一样的T x; x = y;.
有一种语言规则,可以从字符串文字初始化字符数组.(在此上下文中,字符串文字不会"评估为其基址").有不该阵列能够从一个指针旨在被复制到数组中的元素被初始化的语言规则.
为什么这样的规则?"历史原因".
| 归档时间: |
|
| 查看次数: |
560 次 |
| 最近记录: |