使用字符指针和字符数组之间的区别

基本问题。

char new_str[]=""; char * newstr; 

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

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

const char *和字符串文字是一样的吗?

我需要了解更多。 有人能指出一些不错的详尽内容/材料吗?

请仔细阅读以下文章 :

另外,在你的情况下看char的数组,char new_str []然后new_str将始终指向数组的基数。 指针本身不能递增。 是的,您可以使用下标访问数组中的下一个char,例如: new_str[3] ;

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

我还建议这篇文章更清晰。

澄清困惑的最佳来源是Peter Van der Linden,专家C编程,Deep C机密 – 数组和指针不同,它们是如何在内存中处理的。

有arrays,

  char new_str []; 

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

然而,使用指针,编译器给出符号

  char * newstr 

地址,例如0x9876,但在运行时,使用的地址是间接寻址方案。 假设newstr是malloc’d

  newstr = malloc(10); 

,正在发生的是,每次代码中的引用都使用newstr,因为newstr的地址是编译器已知的,即0x9876,但newstr指向的是变量。 在运行时,代码从物理内存0x9876(即newstr)获取数据,但在该地址是另一个内存地址(因为我们将它malloc),例如0x8765它在这里,代码从该内存地址获取数据malloc分配给newstr,即0x8765。

char new_str[]char *newstr可以互换使用,因为数组第0个元素索引衰减成指针 ,这解释了为什么你可以使用newstr[5]*(newstr + 5)注意指针表达式是如何使用的虽然我们已经宣布了char *newstr ,因此

  *(new_str + 1) = * newstr; 

要么

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

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

得到这本书并阅读它,然后活着并呼吸它。 这是一本精彩的书! 🙂

这是一个字符数组:

 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 

区别在于一个是指针,另一个是数组。 例如,您可以使用sizeof()数组。 您可能有兴趣在这里偷看

如果您正在使用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 ++字符串,那么很多工作都是为您完成的。

第一个的类型是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。

OTOH,如果你这样做:

 char *foo = "Bar"; 

编译器现在在只读内存中分配一个静态字符串“Bar”,不能修改。

 foo[i] = 'X'; // is now undefined. 
 char new_str[]="abcd"; 

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

 char *new_str="abcd"; 

这指定字符串’abcd’存储在内存中的某处,指针new_str指向该字符串的第一个字符。

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

 // 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"; 

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