是什么让字符 * 成为字符数组
What makes a char * an array of chars?
通常,如果您执行以下操作:
int * i = &someint;
它只是一个指向变量的指针。
但是,当你这样做时
char * str = "somestring";
它会自动将其转换为数组。是指针在执行此操作,还是只是初始化语法的语法糖?
不,字符串文字"somestring"
已经是一个字符数组,几乎可以肯定是由编译器创建的。
该语句的作用是将str
设置为指向第一个字符。如果你要看一下底层汇编程序代码,它可能看起来像:
str314159: db "somestring", 0 ; all string literals here.
: : : :
load r0, str314159 ; get address of string
stor r0, -24[sp] ; store it into local var str.
在很多情况下,数组将衰减到指向该数组的第一个元素的指针(有一些有限的例外,例如在执行sizeof
时(。
举例来说,下面的 C 代码:
#include <stdio.h>
int main (void) {
char *somestr = "Hello";
puts (somestr);
return 0;
}
当使用 gcc -S
编译以生成 x86 程序集时,给我们(删除了不相关的 cruft(:
.LC0:
.string "Hello"
.text
.globl main
.type main, @function
main:
pushl %ebp ; Standard set up of stack frame,
movl %esp, %ebp ; aligning and making
andl $-16, %esp ; room for
subl $32, %esp ; local variables.
movl $.LC0, 28(%esp) ; Load address of string in to somestr.
movl 28(%esp), %eax ; Call puts with that variable.
movl %eax, (%esp)
call puts
movl $0, %eax ; Set return code.
leave ; Tear down stack frame and return.
ret
您可以看到第一个字符 .LC0
的地址确实加载到 somestr
变量中。而且,虽然可能不是很明显.string
但确实会创建一个以 NUL 字符结尾的字符数组。
它不是指向变量的指针。 它是指向内存中某个位置的指针。 您正在创建一个变量并将其存储在某个内存位置,然后将指针指向该位置。 它适用于数组的原因是数组的元素背靠背存储在内存中。 指针指向数组的开头。
char * str
是指向字符的指针。将字符串分配给字符指针时,它指向字符串的第一个字符,而不是整个字符串。如果指针递增,您可以看到它指向字符串中的第二个字符。打印字符指针时,cout 对象将打印该字符并继续打印字符,直到看到空字符 (\0(。
#include <iostream>
using namespace std;
int main()
{
char *s = "something";
cout << "before :" << s << endl;
s++;
cout << "after :" << s << endl;
}
此程序打印:
~/cpp: ./stringarray
before :something
after :omething
int * i = &someint;
除了其他评论,一般来说,我们可以说它是指向大小位置(int(的指针。因此,当我们访问"i"内部的值时。即 *i,检索 sizeof(int( 内存位置。此外,算术计算以相同的方式完成。即,递增指针 i+1 , 递增 + sizeof (int(。因此,检索到的数据的大小取决于变量的"数据类型"。
您使用的"通常"一词是这里问题的重要组成部分。
我认为可能使这种混乱的部分原因是许多需要char *
的函数正在寻找 c 样式字符串(即以 null 结尾的字符数组(。这就是他们想要的。你可以编写一个只看字符的函数。
类似地,您可以编写一个函数,该函数采用 int* 并将其视为以 null 结尾的数组,这并不常见。这是有充分理由的,因为如果您想要值 0 怎么办?在 C 样式字符串(用于显示而不是二进制数据(中,您永远不会想要 0。
#include <iostream>
const int b_in_data[]={50,60,70,80,0};
int Display (const int * a)
{
while ( *a != 0){
std::cout << *a; ++a;
}
}
int main()
{
int a[]={20,30,40,0};
// or more like char* = something because compiler is making string literal for you
// probably somewhere in data section and replacing it with its address
const int *b = b_in_data;
Display(a);
Display(b);
return 0;
}
C 样式字符串只是选择终止而不是传递大小,B 样式字符串传递大小代替。 整数数组通常不以 null 结尾,但可以终止。归结为"正常"。
人们所说str
不是一个数组,而只是一个指向字符的指针("某物"的第一个,所以s(。然而,有 2 种语法糖
1-"something"
初始化包含所有字符的内存块,并在末尾添加