char * 和 char[] 的区别 [英] The difference between char * and char[]

查看:13
本文介绍了char * 和 char[] 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've read so many threads and questions about it and read so many answers but STILL having difficulties understanding the differences and when you should use what ?

我认为当您需要存储数据并且您不知道它的大小时应该使用 char*,因为它是动态的.另外,我不确定我是否正确,但根据我的理解,如果您声明一个 char* 并为其分配一个像这样的文字:字符 *ch = "嗨";这是一个您无法更改的常量,如果您尝试更改它,您只需将 ch 指向另一个分配的存储新字符串的内存空间?如果这样写:char ch = malloc(20);然后你可以改变值如果你这样做:char ch[] = "你好";字符 pch = ch;您也可以更改值,因为您指向数组并且数组指向 ch[0] ?

I think you should use char* when you need to store data and you don't know the size of it because it's dynamic. Also I'm not sure if i'm right but from what I've understand if you declare a char* and assign it a literal text like this : char *ch = "hi"; it's a constant that you can't change and if you do try to change it you'll just point ch to another allocated memory space holding the new string ? If write it this way : char ch = malloc(20); then you can change the value and if you do this : char ch[] = "hi"; char pch = ch; you can change the values aswell because you point to the array and the arrays points to ch[0] ?

所有用粗体字写的都是我的阅读理解,虽然我可能对我刚才所说的大部分内容都错了,这就是为什么我需要一个非常好的和简单的解释,这样我才能一劳永逸地理解差异以及什么时候应该使用什么.

All the is written in bold is my understanding from reading, although I'm probably wrong about most of the stuff I just said and that's why I need a REALLY GOOD and simple explanation so I could once and for all understand the differences and when I should use what.

#include <stdio.h>

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

推荐答案

最直接的答案是:

这里的区别在于

char *s = "Hello world";

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

will place Hello world in the read-only parts of the memory and making s a pointer to that, making any writing operation on this memory illegal. While doing:

char s[] = "Hello world";

将文字字符串放入只读内存并将字符串复制到堆栈上新分配的内存.从而使

puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus making

s[0] = 'J';

合法的.

更冗长的解释将包括内存存储在哪些段中,以及分配了多少内存:

A more lengthy explanation would include what segments the memory is stored in, and how much memory is allocated:

Example:                       Allocation Type:     Read/Write:    Storage Location:   Memory Used (Bytes):
===========================================================================================================
const char* str = "Stack";     Static               Read-only      Code segment        6 (5 chars plus '')
char* str = "Stack";           Static               Read-only      Code segment        6 (5 chars plus '')
char* str = malloc(...);       Dynamic              Read-write     Heap                Amount passed to malloc
char str[] = "Stack";          Static               Read-write     Stack               6 (5 chars plus '')
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>
  1. What is the difference between char s[] and char *s in C?, Accessed 2014-09-03, <https://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c>
  2. Difference between declared string and allocated string, Accessed 2014-09-03, <https://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>

编辑

为了解决问题中的编辑以及随之而来的评论,我在您的解决方案中添加了注释:

To address the edit in the question and the comment issued with it, I've added notes to your solution:

#include <stdio.h>

int main() {
   char ch[] = "Hello"; /* OK; Creating an array of 6 bytes to store
                         * 'H', 'e', 'l', 'l', 'o', ''
                         */
   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
", ch);   /* OK */
   printf("p1 address [%d] value is %s
", p1, *p1);  /* Bad format specifiers */
   printf("p2 address [%d] value is %s
", p2, *p2);  /* Bad format specifiers */
   printf("p3 address [%d] value is %s
", p3, *p3);  /* Bad format specifiers */
   return 0;
}

所以,三个主要错误.

  1. 您正在将 char 值分配给 pointer-to-char 变量.你的编译器应该警告你这一点.(char *p3 = *p1).
  2. 根据您的编译器,您可能必须使用指针 %p 格式说明符来打印地址,而不是 %d(整数)格式说明符.
  3. 您正在使用带有 char 数据类型的字符串 %s 说明符(即:printf("%s", 'c') 错误).如果要打印单个字符,则使用 %c 格式说明符,并且匹配的参数应该是一个字符(即:'c'、char b 等).如果要打印整个字符串,则使用 %s 格式说明符,并且参数是 pointer-to-char.
  1. You are assigning a char value to a pointer-to-char variable. Your compiler should be warning you about this. (char *p3 = *p1).
  2. Depending on your compiler, you may have to use the pointer %p format specifier to print out an address rather than the %d (integer) format specifier.
  3. You are using the string %s specifier with a char data type (ie: printf("%s", 'c') is wrong). If you are printing a single character, you use the %c format specifier, and the matching argument should be a character (ie: 'c', char b, etc). If you are printing an entire string, you use the %s format specifier, and the argument is a pointer-to-char.

示例

#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', '' };   // An array of characters with a trailing NULL charcter; THIS IS A C-STYLE STRING
   // You could also replace the '' 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 '' is added automatically for you

   printf("%s
", myString);        // OK; Prints a string stored in a variable
   printf("%s
", "Ducks rock!");   // OK; Prints a string LITERAL; Notice the use of DOUBLE quotes, " "
   printf("%s
", cString);         // OK; Prints a string stored in a variable

   printf("%c
", c);               // OK; Prints a character
   printf("%c
", *pC);             // OK; Prints a character stored in the location that pC points to
   printf("%c
", '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
", c);               // WRONG; Is attempting to print a character as a string, similar
                                    // to what you are doing.
   printf("%s
", *pC);             // WRONG; Is attempting to print a character as a string. This is
                                    // EXACTLY what you are doing.
   printf("%s
", cArray);          // WRONG; cArray is a character ARRAY, not a C-style string, which is just
                                    // a character array with the '' 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', ''
                         */
   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
", ch);   /* OK */
   printf("p1 address [%p] value is %s
", p1, p1);  /* Fixed format specifiers */
   printf("p2 address [%p] value is %s
", p2, p2);  /* Fixed format specifiers */
   printf("p3 address [%p] value is %s
", 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

这篇关于char * 和 char[] 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆