C语言字符数组的初始化研究
2013-03-31 22:16
260 查看
有一天一个朋友问了我一个很有意思的问题。他问我如果用C代码在一个函数里面写一行字符串初始化代码,如“char str[]="hello world",那么该字符串是如何被初始化的呢?
开始我不以为然,立刻回答:该字符串应该是程序在运行时,通过立即数寻址直接写入堆栈中的嘛。结果该朋友反问了一句:真的吗?我隐约觉得不对劲,等回来我写了段代码看看它到底是怎么初始化的。
代码(test.c)如下:
那么所有编译器都是这样做的吗?因为通过立即数寻址的方式也是可以对字符串进行初始化的,问题有没有编译器是这样做的呢?下面是我在另外一台机器上运行的结果,源代码用的还是test.c。
第15-17行显示,在4.6版本的GCC里面是通过立即数寻址来完成字符串的初始化的。1819043176和1870078063表示的含义下面的表格解释的很清楚,因为这台测试的机器是小端机器,所以在读字符串的时候是从右往左读的。
从上面两个列子可以看出采用什么方式初始化字符串是根据编译器的不同而不同的,可以通过立即数寻址的方式实现,也可以通过基址寻址的方式实现。
开始我不以为然,立刻回答:该字符串应该是程序在运行时,通过立即数寻址直接写入堆栈中的嘛。结果该朋友反问了一句:真的吗?我隐约觉得不对劲,等回来我写了段代码看看它到底是怎么初始化的。
代码(test.c)如下:
int main(int argc, char *argv[]){ char str[]="hello world"; str[1]='a'; return 0; }然后gcc -S test.c,生成test.s文件,内容如下,去掉了一些无关紧要的部分:
.file "test.c" .section .rodata .LC0: .string "hello world" .text .globl main .type main, @function main: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: movl %edi, -20(%rbp) movq %rsi, -32(%rbp) movq .LC0(%rip), %rax movq %rax, -16(%rbp) movl .LC0+8(%rip), %eax movl %eax, -8(%rbp) movb $97, -15(%rbp) movl $0, %eax leave ret .LEFDE1: .ident "GCC: (GNU) 4.1.2 20080704 (Red Hat 4.1.2-44)" .section .note.GNU-stack,"",@progbits结果出乎我的意料,第16-19行汇编代码清楚的告诉我们,该编译器是在常量存储区(.rodata)里面先生成一个"hello world"的字符串,然后再初始化str数组时分两次将该字符串拷贝到堆栈中。
那么所有编译器都是这样做的吗?因为通过立即数寻址的方式也是可以对字符串进行初始化的,问题有没有编译器是这样做的呢?下面是我在另外一台机器上运行的结果,源代码用的还是test.c。
.file "test.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl %edi, -20(%rbp) movq %rsi, -32(%rbp) movl $1819043176, -16(%rbp) movl $1870078063, -12(%rbp) movl $6581362, -8(%rbp) movb $97, -16(%rbp) movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (GNU) 4.6.2 20111027 (Red Hat 4.6.2-1)" .section .note.GNU-stack,"",@progbits
第15-17行显示,在4.6版本的GCC里面是通过立即数寻址来完成字符串的初始化的。1819043176和1870078063表示的含义下面的表格解释的很清楚,因为这台测试的机器是小端机器,所以在读字符串的时候是从右往左读的。
十进制 | 十六进制 | 对应ASCII字符串 |
1819043176 | 6C6C6568 | lleh |
1870078063 | 6F77206F | ow o |
6581362 | 646C72 | dlr |
相关文章推荐
- C语言之字符数组的初始化
- C语言字符数组初始化
- C语言中二维字符数组的定义和初始化
- C语言中二维字符数组的定义和初始化
- C语言的字符数组(字符串)的定义与初始化
- C语言指针问题,初始化,赋值,以及字符数组,字符串常量等问题
- C语言中字符数组的初始化与赋值
- C语言中字符数组的初始化与赋值
- C语言字符数组的初始化
- C语言字符数组的初始化
- C语言中二维字符数组的定义和初始化
- C语言中strlen求字符串长度,求字符数组长度(空字符,数字0,字符0,数组部分初始化)
- C语言 字符数组初始化方式总结
- C语言字符数组的初始化
- C语言字符数组的定义与初始化
- C语言字符数组的初始化
- C语言中字符数组和字符串定义和初始化的问题
- C语言结构体数组内带字符数组初始化和赋值
- C语言字符数组的初始化
- C语言中strlen求字符串长度,求字符数组长度(空字符,数字0,字符0,数组部分初始化)