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

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

问题描述

我已经看了这么多线程和问题有关,并看了这么多的答案,但仍然有理解差异的困难,当你应该使用什么?

我认为当你需要存储的数据,你不知道它的大小,因为它是动态的,你应该使用的char *。
此外,我不知道,如果我是对的,但是从什么,如果你宣布一个char *我理解并赋予其文本的文字是这样的:
字符* CH =HI;
这是一个常量,你不能改变,如果你试图改变它,你会只点CH另一个分配的内存空间拿着新的字符串?
如果写这样说:
字符的 CH =的malloc(20);
那么你可以更改值
如果你这样做:
CHAR CH [] =HI;
的PCH = CH;
你可以改变藏汉因为你指向数组的价值观和阵列点为ch [0]

所有写在大胆是从阅读我的理解,虽然我可能是错的最多的东西,我刚才说的,这就是为什么我需要一个非常好的和简单的解释,所以我可以一劳永逸了解这些差异当我应该使用什么。

编辑:

 的#include<&stdio.h中GT;主要()
{
    CHAR CH [] =你好;
    字符* P1 = CH;
    字符* P2 = P1;
    字符* P3 = P1 *;
    的printf(CH:%S \\ n,CH);
    的printf(P1地址[%D]。价值为%s \\ n,P1,P1 *);
    的printf(P2地址[%D]。价值为%s \\ n,P2,P2 *);
    的printf(P3地址[%D]。价值为%s \\ n,P3,P3 *);
    返回0;
}


解决方案

最简单的答案是:


  

这里的不同之处在于

 的char * s =Hello World的;


  
  

将会把世界您好在存储器和制造的只读份
  是个指针,在作出这个内存中的任何写入操作
  非法。虽然这样做的:

 个char [] =Hello World的;


  
  

把文本字符串在只读存储器并复制字符串
  在堆栈上新分配的内存。从而使

  S [0] ='J';


  
  

合法的。


一个更详尽的解释应包括哪些部分记忆存储在,多少内存分配:

 例:分配类型:读/写:存储位置:使用的内存(字节):
===========================================================================================================
为const char *海峡=堆栈;静态只读code段6(5个字符加'\\ 0')
字符*海峡=堆栈;静态只读code段6(5个字符加'\\ 0')
字符*海峡=的malloc(...);动态读写堆量传递给MALLOC
焦炭海峡[] =堆栈;静态读写堆栈6(5个字符加'\\ 0')
STRGLobal的字符[10] =环球;静态读写数据段(R / W)10

参考



  1. 什么是用C个char []和char * S之间的区别?的,访问的2014年9月3日,<一个href=\"http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c\"><$c$c><http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c>

  2. 声明的字符串和分配的字符串之间的区别的,访问的2014年9月3日,<一个href=\"http://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string\"><$c$c><http://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>

修改


要解决这个问题的编辑,并与它发布的注释,我已经添加注释,你的解决方案:

 的#include&LT;&stdio.h中GT;诠释主(){
   CHAR CH [] =你好; /* 好;创建的6个字节数组存储
                         *'H','E','L','L','O','\\ 0'
                         * /
   字符* P1 = CH; /* 好;创建指向的指针
                         *你好字符串。
                         * /
   字符* P2 = P1; /* 好;创建第二个指针也
                         *点到Hello字符串。
                         * /
   字符* P3 = P1 *; / * BAD;您分配一个实际字符
                         *(* P1)的指针到char变量(P3);
                         *如果写成这可能是更直观
                         * 2线:
                         *字符* P3;
                         * P3 = P1 *; //坏
                         * /
   的printf(CH:%S \\ n,CH); /* 好 */
   的printf(P1地址[%D]。价值为%s \\ n,P1,P1 *); / *坏格式说明* /
   的printf(P2地址[%D]。价值为%s \\ n,P2,P2 *); / *坏格式说明* /
   的printf(P3地址[%D]。价值为%s \\ n,P3,P3 *); / *坏格式说明* /
   返回0;
}

所以,三大错误。


  1. 您正在分配字符值到指针到字符变量。你的编译器应该警告你这一点。 (的char * P3 = P1 * )。

  2. 根据您的编译器,你可能需要使用指针%P 格式说明打印出一个地址,而不是%d个(整数)格式说明。

  3. 您正在使用字符串%S 说明与字符数据类型(例如:的printf(%S,'C')是错误的)。如果要打印单个字符,使用%C 格式说明,以及匹配的参数应该是一个字符(即:'C',焦炭B,等等)。如果要打印整个字符串,可以使用%S 格式说明,以及参数是一个指针到字符

例子


 的#include&LT;&stdio.h中GT;诠释主要(无效){
   焦C ='H'; // 一个人物
   字符* PC =和C; //一个指向单个字符;不是字符串
   CHAR CARRAY [] = {'H','E','L','L','O'}; //字符数组;不是字符串
   字符CString的[] = {'H','E','L','L','O','\\ 0'}; //用尾随NULL字符内的字符数组;这是一个C样式的字符串
   //你也可以用0或NULL,即取代'\\ 0':
   //字符CString的[] = {'H','E','L','L','O',(字符)0};
   //字符CString的[] = {'H','E','L','L','O',NULL};
   为const char * MyString的=世界,你好! // C风格的字符串;在'\\ 0'为你自动添加   的printf(%S \\ N的myString); // 好;打印存储在变量字符串
   的printf(%S \\ n,鸭子石头!); // 好;打印字符串;注意使用双引号,
   的printf(%S \\ n,CString的); // 好;打印存储在变量字符串   的printf(%C \\ n,C); // 好;打印字符
   的printf(%C \\ n,* PC); // 好;打印的字符存储在PC指向的位置
   的printf(%C \\ N,J); // 好;打印字符文字;注意使用单引号,''   / *以下是错误的,你的编译器应该被吐出的警告,甚至不允许
    * code编译。他们几乎肯定会导致段错误。如果取消注释他们你
    *希望通过删除#如果0和#endif风格的语句来看到自己。
    * /
#如果0
   的printf(%S \\ n,C); //错误的;被试图打印字符作为字符串,类似
                                    //你在做什么。
   的printf(%S \\ n,* PC); //错误的;被试图打印字符作为字符串。这是
                                    //正是你在做什么。
   的printf(%S \\ n,CARRAY); //错误的; CARRAY是一个字符数组,而不是C风格的字符串,这仅仅是
                                    //一个字符数组,并在最后的'\\ 0'字符;的printf
                                    //将继续打印,不管后面的字符串的结尾(例如:
                                    //随机存储器,垃圾等),直到遇到存储在存储器中的零。
#万一
   返回0;
}

code清单 - 建议的解决方案


 的#include&LT;&stdio.h中GT;诠释主(){
   CHAR CH [] =你好; /* 好;创建的6个字节数组存储
                         *'H','E','L','L','O','\\ 0'
                         * /
   字符* P1 = CH; /* 好;创建指向的指针
                         *你好字符串。
                         * /
   字符* P2 = P1; /* 好;创建第二个指针也
                         *点到Hello字符串。
                         * /
   字符* P3 = P1; /* 好;分配一个指针到字符到
                         *指针到字符变量。
                         * /
   的printf(CH:%S \\ n,CH); /* 好 */
   的printf(P1地址[%P]值%S \\ n,P1,P1); / *固定格式说明符* /
   的printf(P2地址[%P]值%S \\ n,P2,P2); / *固定格式说明符* /
   的printf(P3地址[%P]值%S \\ n,P3,P3); / *固定格式说明符* /
   返回0;
}

示例输出


  CH:你好
P1地址[0x7fff58e45666]值是你好
P2地址[0x7fff58e45666]值是你好
P3地址[0x7fff58e45666]值是你好

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 ?

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.

EDIT :

#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;
}

解决方案

The most straightforward answer is:

The difference here is that

char *s = "Hello world";

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';

legal.

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 '\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

References


  1. What is the difference between char s[] and char *s in C?, Accessed 2014-09-03, <http://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, <http://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>

Edit


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', '\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;
}

So, three major bugs.

  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.

Examples


#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;
}

Code Listing - Proposed Solution


#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;
}

Sample Output


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天全站免登陆