【问题标题】:Difference between using character pointers and character arrays使用字符指针和字符数组的区别
【发布时间】:2010-12-20 22:06:51
【问题描述】:

基本问题。

char new_str[]="";

char * newstr;

如果我必须将一些数据连接到其中或使用 strcat/substr/strcpy 之类的字符串函数,这两者有什么区别?

我知道我必须为 char * 方法(第 2 行)分配内存。不过我不太确定。

而 const char * 和字符串字面量是一样的吗?

我需要了解更多。有人可以指出一些很好的详尽内容/材料吗?

【问题讨论】:

标签: c++ c pointers character


【解决方案1】:

在内存分配方面区分它们:

// With char array, "hello" is allocated on stack
char s[] = "hello";

// With char pointer, "hello" is stored in the read-only data segment in C++'s memory layout.
char *s = "hello";

// To allocate a string on heap, malloc 6 bytes, due to a NUL byte in the end
char *s = malloc(6);
s = "hello";

【讨论】:

    【解决方案2】:
    char new_str[]="abcd";  
    

    这指定大小为 5 个字节的字符数组(字符串)(每个字符一个字节加上一个空终止符)。所以它将字符串'abcd'存储在内存中,我们可以使用变量new_str来访问这个字符串。

    char *new_str="abcd";  
    

    这指定了一个字符串“abcd”存储在内存中的某个位置,并且指针 new_str 指向该字符串的第一个字符。

    【讨论】:

      【解决方案3】:

      消除混淆的最佳来源是 Peter Van der Linden,专家 C 编程,深度 C 的秘密 - 数组和指针不一样是它们在内存中的寻址方式。

      使用数组,

      char new_str[];
      编译器已经给 new_str 一个在编译和运行时都知道的内存地址,例如0x1234,因此使用[] 对new_str 进行索引很简单。例如new_str[4],在运行时,代码会选择new_str所在的地址,例如0x1234(即物理内存中的地址)。通过将索引说明符[4] 添加到它,0x1234 + 0x4,然后可以检索该值。

      而对于指针,编译器给出符号

      char *newstr
      一个地址,例如0x9876,但在运行时,使用的地址是间接寻址方案。假设 newstr 是 malloc 的即0x9876,但newstr 指向的是可变的。在运行时,代码从物理内存 0x9876(即 newstr)获取数据,但在该地址是另一个内存地址(因为我们对其进行了 malloc),例如 0x8765 它就在这里,代码从该内存地址获取数据malloc 分配给newstr,即0x8765。

      char new_str[]char *newstr 可以互换使用,因为 数组的第零个元素索引会衰减为指针,这就解释了为什么您可以使用 newstr[5]*(newstr + 5)即使我们声明了char *newstr,也会使用指针表达式,因此

      *(new_str + 1) = *newstr;
      *(new_str + 1) = newstr[1];

      总之,两者的真正区别在于它们在内存中的访问方式。

      拿起这本书,读它,生活它,呼吸它。这是一本精彩的书! :)

      【讨论】:

      • 附带说明:C 具有可交换表达式,例如 4 + 3 与 3 + 4 相同。在指针中也是如此,*(new_str + 1) 与 * 相同(1 + new_str) 顺便说一下是 1[new_str]。那是个玩笑,在网络上的其他地方被引用,可能是为了甩掉某人。 IT 很少在生产中使用,还没有在某个地方看到它!
      【解决方案4】:

      请转至下方this article

      另见 char 数组的情况,如您的情况 char new_str[] 那么 new_str 将 始终 指向数组的底部。指针本身不能递增。是的,您可以使用下标访问数组中的下一个字符,例如:new_str[3];

      但如果是指向 char 的指针,指针可以递增 new_str++ 以获取数组中的下一个字符。

      为了更清楚,我建议this article

      【讨论】:

      • 两个链接现在都失效了:(
      【解决方案5】:

      这是一个字符数组:

      char  buf [1000];
      

      因此,例如,这是没有意义的:

      buf = &some_other_buf;
      

      这是因为buf虽然具有指针类型的特性,但已经指向了唯一对它有意义的地方。

      char *ptr;
      

      另一方面,ptr 只是一个指针,可能指向某个地方。大多数情况下,它是这样的:

      ptr = buf;              // #1:  point to the beginning of buf, same as &buf[0]
      

      或者这个:

      ptr = malloc (1000);    // #2:  allocate heap and point to it
      

      或:

      ptr = "abcdefghijklmn"; // #3:  string constant
      

      对于所有这些,*ptr 都可以写入——除了某些编译环境将字符串常量定义为不可写入的第三种情况。

      *ptr++ = 'h';          // writes into #1: buf[0], #2: first byte of heap, or
                             //             #3 overwrites "a"
      strcpy (ptr, "ello");  // finishes writing hello and adds a NUL
      

      【讨论】:

        【解决方案6】:

        第一个的类型是char[1],第二个是char *。不同的类型。

        在 C 中使用 malloc 或在 C++ 中使用 new 为后者分配内存。

        char foo[] = "Bar";  // Allocates 4 bytes and fills them with
                             // 'B', 'a', 'r', '\0'.
        

        这里的大小是从初始化字符串中隐含的。

        foo 的内容是可变的。您可以更改foo[i],例如i = 0..3。

        如果你这样做了:

        char *foo = "Bar";
        

        编译器现在在只读内存中分配一个静态字符串“Bar”并且无法修改。

        foo[i] = 'X';  // is now undefined.
        

        【讨论】:

        • 嗯。不。 foo 是不可变的。你不能改变 foo.您可以更改 foo 的元素,是的,但是您不能将 foo 更改为 bar,例如如果 bar 也是一个 char 数组。
        【解决方案7】:

        不同的是,一个是指针,另一个是数组。例如,您可以使用 sizeof() 数组。你可能有兴趣偷看here

        【讨论】:

          【解决方案8】:

          如果您在标签上使用 C++,那么您确实应该使用 C++ 字符串,而不是 C char 数组。

          string 类型使操作字符串变得更加容易。

          如果你因为某种原因被char 数组卡住了,那一行:

          char new_str[] = "";
          

          分配 1 个字节的空间并在其中放入一个空终止符。它与以下内容略有不同:

          char *new_str = "";
          

          因为这可能会给你一个不可写内存的引用。声明:

          char *new_str;
          

          它自己给你一个指针,但它没有指向它。如果它是函数本地的,它也可以有一个随机值。

          人们倾向于做的事情(在 C 而不是 C++ 中)是这样的:

          char *new_str = malloc (100); // (remember that this has to be freed) or
          char new_str[100];
          

          以获得足够的空间。

          如果你使用str...函数,你基本上负责确保char数组中有足够的空间,以免你在调试代码时得到各种奇怪而奇妙的练习。如果您使用真正的 C++ 字符串,则为您完成了很多繁重的工作。

          【讨论】:

            【解决方案9】:

            如果您使用 C++,为什么不使用 std::string 来满足您的所有字符串需求?尤其是处理串联的任何事情。这样可以避免很多问题。

            【讨论】:

              猜你喜欢
              • 2012-02-04
              • 1970-01-01
              • 2015-08-19
              • 1970-01-01
              • 2013-12-16
              • 2015-08-12
              • 2011-06-26
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多