【问题标题】:Difference between char* and char[]char* 和 char[] 的区别
【发布时间】:2011-11-25 17:09:36
【问题描述】:

我知道这是一个非常基本的问题。我对以下内容为什么以及如何不同感到困惑。

char str[] = "Test";
char *str = "Test";

【问题讨论】:

标签: c++


【解决方案1】:

我们来看看以下几种声明字符串的方式:

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 声明字符串似乎是最好的方法!它以最少的堆栈内存完成这项工作。

【讨论】:

  • name0 我相信这里应该只是一个字符。现在它可能被解释为 int 然后向下转换为 char。
【解决方案2】:

从 C++11 开始,第二个表达式现在无效,必须写:

const char *str = "Test";

标准的相关部分是附录C第1.1节:

更改:字符串文字变为 const

字符串字面量的类型从“char数组”更改为“数组” const char。” char16_t 字符串文字的类型从 “一些整数类型的数组”到“const char16_t 的数组”。的类型 char32_t 字符串文字从“一些整数类型的数组”更改 到“const char32_t 数组”。宽字符串文字的类型是 从“wchar_t 数组”更改为“const wchar_t 数组”。

基本原理:这样可以避免调用不适当的重载函数, 它可能期望能够修改其参数。

对原始特征的影响:改变定义明确的特征的语义。

【讨论】:

  • 假设 char* 是函数char* fun() 的返回类型?现在返回类型或返回值的规范会有变化吗?
  • @AjaySinghNegi 绝对是。您需要返回一个const char*
【解决方案3】:

区别在于使用的堆栈内存。

例如,在为堆栈分配的内存很少的微控制器编程时,会产生很大的不同。

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.

【讨论】:

  • 这仅适用于微控制器吗?如果不是,那么黑白静态内存区和堆栈有什么区别?
  • 即使您不是为微控制器编程,但担心内存使用情况,这也适用。微控制器的堆栈内存通常比您的计算机少。
【解决方案4】:

一个指针可以重新指向别的东西:

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'

递增指针的最后一个示例表明,您可以轻松地遍历字符串的内容,一次一个元素。

【讨论】:

    【解决方案5】:

    一个是指针,一个是数组。它们是不同类型的数据。

    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
    

    【讨论】:

    • 这是新的东西,所以什么时候存储在不需要由NULL字符终止的指针中?
    • @Stack Overflow ponter 存储为占用 4 个字节的地址。较长的字符串将返回为 sizeof array 20 sizeof pointer 4
    【解决方案6】:

    第一个

    char str[] = "Test";
    

    是一个由五个字符组成的数组,使用值 "Test" 加上空终止符 '\0' 进行初始化。

    第二个

    char *str = "Test";
    

    是指向文字字符串"Test"的内存位置的指针。

    【讨论】:

    • 不确定,但它是 5 个字符的数组。 {'T', 'e', 's', 't', '\0'}.
    • @PeterOlson 您说的是指向内存位置的指针。这是否意味着 ptr 存储“测试”的起始地址?我清楚地知道指针只能存储地址而“测试”不是地址。
    • @StackOverflow 是的,一个指针指向起始地址,然后你可以通过开始地址(指向字母T)找到字符串,直到空终止符到达。
    • @PeterOlson 这是否意味着文字“Test”存储在内存中的某个位置并以'\0'和指向“Test”的'T'的ptr终止?如果是,“Test”驻留在哪个内存中?
    【解决方案7】:

    "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 个字节。

    【讨论】:

    • 你不能修改字符串文字,它们是不可变的;这样做是未定义的行为。
    • strp[0] = 'W'; 调用未定义的行为,因为它试图修改常量字符串。
    • 在数组中我们可以修改内容,但不能在指针的情况下。请修正你的答案是错误的。有人可能会在阅读此 @Tim 时学到错误的东西
    【解决方案8】:
    char str[] = "Test";
    

    chars的数组,用“Test”中的内容初始化,而

    char *str = "Test";
    

    是指向文字(const)字符串“Test”的指针。

    它们之间的主要区别在于第一个是数组,另一个是指针。数组拥有它的内容,它恰好是"Test" 的副本,而指针只是引用字符串的内容(在这种情况下是不可变的)。

    【讨论】:

    • 为什么char* str常用str表示字符串。 str[] 不是更好吗?
    • @Ajan: str[] 是一个静态大小的数组,用于复制字符串。如果您需要一个副本-仅在假装修改字符串时才需要-,那么数组会更好。否则,最好使用指向文字字符串的指针。
    • @Ajan:它们不都表示常量,允许字符串文字绑定到非 const 指针只是为了支持旧版 C。文字应始终由 const 指针引用以避免潜在的未定义行为。
    • 好的,这就解释了为什么我得到warning: deprecated conversion from string constant to ‘char*’
    • @K-ballo 如果 strchar *str = "Test"; 中的指针,那么这是否意味着文字“Test”存储在内存中的某个位置?
    猜你喜欢
    • 2013-03-22
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 2017-04-02
    • 2014-10-28
    • 2011-12-14
    • 1970-01-01
    相关资源
    最近更新 更多