当你用char
指针创建一个字符串时,它是如何工作的?
char *name = "ben";
这是'隐藏'指针算法吗?
答案 0 :(得分:8)
因为数组会自动衰减指针。这是单向转换。
在这种特殊情况下会发生的情况是,编译器将匿名数组"ben"
放入可执行文件的可能只读数据部分(通常.rodata
name
3}}),然后在运行时为变量{{1}}分配该数组中第一个字节的地址。
答案 1 :(得分:6)
没有任何隐藏的指针算术,但我怀疑你想要一个更详细的答案。
如果你有一个功能:
void foo() {
char * bar = "Hello World";
}
实际上有两块内存可供使用:
bar
变量。当程序调用{{1}}时,它会分配足够的堆栈空间(32位为4个字节)来容纳此内存位置,并将其初始化为实际数据的位置。每次有趣foo()
时都会发生这种情况。此外,如果稍后在函数中执行如下语句:
foo()
您没有将数据“Hello World”更改为“Good bye”。你实际上只是在数据段中有一个第3块内存,其中包含“Good bye”(仍在编译时分配),然后当该行执行时指针(bar)被设置到该位置。
创建“字符串”(字符数组)的另一种方法是:
bar = "Good bye";
与第一个相同(尽管如此)。在这个方法中,你仍然有两个变量,除了你关注的实际数据(“Hello World”+空字节)在程序堆栈上被分配和初始化。
您可以通过运行void foo() {
char bar[] = "Hello World";
}
然后阅读gcc -S test.c
来查看已编译程序集中的差异。
在某些时候,您需要查看C's string functions。
使用这些函数时要记住的关键是他们根本不知道你的字符数组有多长,他们根据第一个空字符的位置(一个标记值)来计算出来。
答案 2 :(得分:4)
这是'隐藏'指针算法吗?
没有。它是明确的,面对面的指针算法。这就是*
的含义。指针。
答案 3 :(得分:4)
C中的字符串只是位于内存中的相邻字节,以n隐式'\ 0'字节结尾。通过写char * p =“string”,您只需将此序列中第一个字节的地址加载到p。
现在,对于您的确切问题,您提供的代码将在程序的静态内存中将此“ben”字符串分配为四个字节“b”,“e”,“n”和“\ 0”。这意味着字符串不会在堆中动态分配或在堆栈上自动分配。它将存储在已编译和链接的程序映像的静态部分中。然而,指针变量'name'将是一个自动分配的堆栈变量,它将保存字符串第一个字节的地址。
答案 4 :(得分:0)
字符串只是一个字符数组,可以写成:
char name[] = "ben";
答案 5 :(得分:0)
name只是指向第一个内存地址的指针,在本例中为“b”(或者在帖子标题的情况下为“h”)。在末尾插入一个空字符以表示字符串的结尾。所以不是指针算术。
答案 6 :(得分:0)
当你声明一个这样的字符串时,它是一个初始化的常规变量,指向字符串表中的地址(可执行文件的只读部分)。它与字符数组之间的区别在于数组是在堆栈外声明的,因此是可写的。你不应该试图修改像这样的常量字符串,这就是为什么它们应该被声明为'const',所以编译器会保护你自己。最好在编译时捕获它,而不是想知道为什么会出现seg错误。