[英]Difference between char* and char[]
我知道这是一个非常基本的问题。 我很困惑为什么以及以下内容有何不同。
char str[] = "Test";
char *str = "Test";
char str[] = "Test";
是一个chars
数组,用“Test”中的内容初始化,而
char *str = "Test";
是指向文字(常量)字符串“Test”的指针。
它们之间的主要区别在于第一个是数组,另一个是指针。 数组拥有它的内容,它恰好是"Test"
的副本,而指针只是指向字符串的内容(在这种情况下是不可变的)。
不同之处在于使用的堆栈内存。
例如,当为微控制器编程时,为堆栈分配的内存很少,这会产生很大的不同。
char a[] = "string"; // the compiler puts {'s','t','r','i','n','g', 0} onto STACK
char *a = "string"; // the compiler puts just the pointer onto STACK
// and {'s','t','r','i','n','g',0} in static memory area.
一个指针可以重新指向别的东西:
char foo[] = "foo";
char bar[] = "bar";
char *str = foo; // str points to 'f'
str = bar; // Now str points to 'b'
++str; // Now str points to 'a'
增加指针的最后一个示例表明您可以轻松地迭代字符串的内容,一次一个元素。
一种是指针,一种是数组。 它们是不同类型的数据。
int main ()
{
char str1[] = "Test";
char *str2 = "Test";
cout << "sizeof array " << sizeof(str1) << endl;
cout << "sizeof pointer " << sizeof(str2) << endl;
}
输出
sizeof array 5
sizeof pointer 4
首先
char str[] = "Test";
是一个包含五个字符的数组,使用值"Test"
加上空终止符'\\0'
初始化。
第二
char *str = "Test";
是指向文字字符串"Test"
的内存位置的指针。
从 C++11 开始,第二个表达式现在无效,必须写成:
const char *str = "Test";
该标准的相关章节是附录C第1.1节:
更改:字符串文字常量
字符串文字的类型从“字符数组”更改为“常量字符数组”。 char16_t 字符串文字的类型从“某种整数类型的数组”更改为“const char16_t 的数组”。 char32_t 字符串文字的类型从“某种整数类型的数组”更改为“const char32_t 的数组”。 宽字符串文字的类型从“wchar_t 数组”更改为“const wchar_t 数组”。
基本原理:这避免了调用不合适的重载函数,该函数可能期望能够修改其参数。
对原始特征的影响:更改为明确定义的特征的语义。
"Test"
是一个包含五个字符(4 个字母,加上空终止符)的数组。
char str1[] = "Test";
创建 5 个字符的数组,并将其命名为str1
。 您可以随意修改该数组的内容,例如str1[0] = 'B';
char *str2 = "Test";
创建 5 个字符的数组,不命名它,并创建一个名为str2
的指针。 它将str2
设置为指向该 5 个字符的数组。 您可以按照指针随意修改数组,例如str2[0] = 'B';
或*str2 = 'B';
. 您甚至可以重新分配该指针指向其他地方,例如str2 = "other";
.
数组是引号中的文本。 指针只是指向它。 你可以用它们做很多类似的事情,但它们是不同的:
char str_arr[] = "Test";
char *strp = "Test";
// modify
str_arr[0] = 'B'; // ok, str_arr is now "Best"
strp[0] = 'W'; // ok, strp now points at "West"
*strp = 'L'; // ok, strp now points at "Lest"
// point to another string
char another[] = "another string";
str_arr = another; // compilation error. you cannot reassign an array
strp = another; // ok, strp now points at "another string"
// size
std::cout << sizeof(str_arr) << '\n'; // prints 5, because str_arr is five bytes
std::cout << sizeof(strp) << '\n'; // prints 4, because strp is a pointer
对于最后一部分,请注意 sizeof(strp) 将因架构而异。 在 32 位机器上,它将是 4 个字节,在 64 位机器上它将是 8 个字节。
我们来看看以下几种声明字符串的方式:
char name0 = 'abcd'; // cannot be anything longer than 4 letters (larger causes error)
cout << sizeof(name0) << endl; // using 1 byte to store
char name1[]="abcdefghijklmnopqrstuvwxyz"; // can represent very long strings
cout << sizeof(name1) << endl; // use large stack memory
char* name2 = "abcdefghijklmnopqrstuvwxyz"; // can represent very long strings
cout << sizeof(name2) << endl; // but use only 8 bytes
我们可以看到使用 char* variable_name 声明字符串似乎是最好的方法! 它以最少的堆栈内存来完成这项工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.