char *和char []之间的区别

时间:2014-09-03 20:25:48

标签: c arrays string pointers char

我已经阅读了很多关于它的线索和问题并阅读了很多答案,但仍然难以理解差异以及何时应该使用什么?

我认为你应该在需要存储数据时使用char *而你不知道它的大小,因为它是动态的。 另外,我不确定我是否正确,但是如果你宣布一个字母*并为其分配一个如下字面文字,我将会理解: char * ch =" hi&#34 ;; 它是一个你无法改变的常数,如果你试图改变它,你只需将ch指向另一个分配的存储空间来保存新字符串? 如果这样写: char ch = malloc(20); 然后你可以改变价值 如果你这样做: char ch [] =" hi&#34 ;; char pch = ch; 您可以更改值,因为您指向数组并且数组指向ch [0]?

所有以粗体书写的是我对阅读的理解,虽然我可能对我刚才所说的大部分内容都错了,这就是为什么我需要一个非常好的简单解释所以我可以一次并且所有人都了解这些差异以及何时应该使用什么。

编辑:

#include <stdio.h>

main()
{
    char ch[] = "Hello";
    char *p1 = ch;
    char *p2 = p1;
    char *p3 = *p1;
    printf("ch : %s\n", ch);
    printf("p1 address [%d] value is %s\n", p1, *p1);
    printf("p2 address [%d] value is %s\n", p2, *p2);
    printf("p3 address [%d] value is %s\n", p3, *p3);
    return 0;
}

1 个答案:

答案 0 :(得分:14)

最直截了当的答案是:

  

这里的区别在于

char *s = "Hello world";
     

将Hello world放在内存的只读部分并制作   是指向它的指针,在这个内存上进行任何写操作   非法。在做的时候:

char s[] = "Hello world";
     

将文字字符串放在只读内存中并将字符串复制到   堆栈上新分配的内存。从而制作

s[0] = 'J';
     

合法的。

更长的解释将包括存储内存的段,以及分配的内存量:

Example:                       Allocation Type:     Read/Write:    Storage Location:   Memory Used (Bytes):
===========================================================================================================
const char* str = "Stack";     Static               Read-only      Code segment        6 (5 chars plus '\0')
char* str = "Stack";           Static               Read-only      Code segment        6 (5 chars plus '\0')
char* str = malloc(...);       Dynamic              Read-write     Heap                Amount passed to malloc
char str[] = "Stack";          Static               Read-write     Stack               6 (5 chars plus '\0')
char strGlobal[10] = "Global"; Static               Read-write     Data Segment (R/W)  10

<强>参考


  1. C中的char s []和char * s有什么区别?,访问日期2014-09-03,<https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c>
  2. 声明字符串与已分配字符串之间的区别,已访问2014-09-03,<https://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>
  3. 修改


    要解决问题中的修改以及随之发布的评论,我已在您的解决方案中添加了注释:

    #include <stdio.h>
    
    int main() {
       char ch[] = "Hello"; /* OK; Creating an array of 6 bytes to store
                             * 'H', 'e', 'l', 'l', 'o', '\0'
                             */
       char *p1 = ch;       /* OK; Creating a pointer that points to the
                             * "Hello" string.
                             */
       char *p2 = p1;       /* OK; Creating a second pointer that also
                             * points to the "Hello" string.
                             */
       char *p3 = *p1;      /* BAD; You are assigning an actual character
                             * (*p1) to a pointer-to-char variable (p3);
                             * It might be more intuitive if written in
                             * 2 lines:
                             * char* p3;
                             * p3 = *p1; //BAD
                             */
       printf("ch : %s\n", ch);   /* OK */
       printf("p1 address [%d] value is %s\n", p1, *p1);  /* Bad format specifiers */
       printf("p2 address [%d] value is %s\n", p2, *p2);  /* Bad format specifiers */
       printf("p3 address [%d] value is %s\n", p3, *p3);  /* Bad format specifiers */
       return 0;
    }
    

    所以,三个主要错误。

    1. 您正在为char变量分配pointer-to-char值。您的编译器应该警告您这一点。 (char *p3 = *p1)。
    2. 根据您的编译器,您可能必须使用指针%p格式说明符来打印地址而不是%d(整数)格式说明符。
    3. 您正在使用带有%s数据类型的字符串char说明符(即:printf("%s", 'c')错误)。如果要打印单个字符,则使用%c格式说明符,匹配参数应为字符(即:&#39; c&#39;,char b等)。如果要打印整个字符串,则使用%s格式说明符,参数为指向char的指针
    4. <强>实施例


      #include <stdio.h>
      
      int main(void) {
         char c = 'H';                    // A character
         char* pC = &c;                   // A pointer to a single character; IS NOT A STRING
         char cArray[] = { 'H', 'e', 'l', 'l', 'o' };   // An array of characters; IS NOT A STRING
         char cString[] = { 'H', 'e', 'l', 'l', 'o', '\0' };   // An array of characters with a trailing NULL charcter; THIS IS A C-STYLE STRING
         // You could also replace the '\0' with 0 or NULL, ie:
         //char cString[] = { 'H', 'e', 'l', 'l', 'o', (char)0 };
         //char cString[] = { 'H', 'e', 'l', 'l', 'o', NULL };
         const char* myString = "Hello world!"; // A C-style string; the '\0' is added automatically for you
      
         printf("%s\n", myString);        // OK; Prints a string stored in a variable
         printf("%s\n", "Ducks rock!");   // OK; Prints a string LITERAL; Notice the use of DOUBLE quotes, " "
         printf("%s\n", cString);         // OK; Prints a string stored in a variable
      
         printf("%c\n", c);               // OK; Prints a character
         printf("%c\n", *pC);             // OK; Prints a character stored in the location that pC points to
         printf("%c\n", 'J');             // OK; Prints a character LITERAL; Notice the use of SINGLE quotes, ' '
      
         /* The following are wrong, and your compiler should be spitting out warnings or even not allowing the
          * code to compile. They will almost certainly cause a segmentation fault. Uncomment them if you
          * want to see for yourself by removing the "#if 0" and "#endif" statements.
          */
      #if 0
         printf("%s\n", c);               // WRONG; Is attempting to print a character as a string, similar
                                          // to what you are doing.
         printf("%s\n", *pC);             // WRONG; Is attempting to print a character as a string. This is
                                          // EXACTLY what you are doing.
         printf("%s\n", cArray);          // WRONG; cArray is a character ARRAY, not a C-style string, which is just
                                          // a character array with the '\0' character at the end; printf
                                          // will continue printing whatever follows the end of the string (ie:
                                          // random memory, junk, etc) until it encounters a zero stored in memory.
      #endif
         return 0;
      }
      

      代码清单 - 建议的解决方案


      #include <stdio.h>
      
      int main() {
         char ch[] = "Hello"; /* OK; Creating an array of 6 bytes to store
                               * 'H', 'e', 'l', 'l', 'o', '\0'
                               */
         char *p1 = ch;       /* OK; Creating a pointer that points to the
                               * "Hello" string.
                               */
         char *p2 = p1;       /* OK; Creating a second pointer that also
                               * points to the "Hello" string.
                               */
         char *p3 = p1;       /* OK; Assigning a pointer-to-char to a 
                               * pointer-to-char variables.
                               */
         printf("ch : %s\n", ch);   /* OK */
         printf("p1 address [%p] value is %s\n", p1, p1);  /* Fixed format specifiers */
         printf("p2 address [%p] value is %s\n", p2, p2);  /* Fixed format specifiers */
         printf("p3 address [%p] value is %s\n", p3, p3);  /* Fixed format specifiers */
         return 0;
      }
      

      示例输出


      ch : Hello
      p1 address [0x7fff58e45666] value is Hello
      p2 address [0x7fff58e45666] value is Hello
      p3 address [0x7fff58e45666] value is Hello