基本问题。
char new_str[]="";
char * newstr;
如果我必须将一些数据连接到它或使用字符串函数如strcat / substr / strcpy,两者之间的区别是什么?
我知道我必须为char *方法分配内存(第2行)。我不太确定如何。
const char *和字符串文字是一样的吗?
我需要了解更多相关信息。有人能指出一些不错的详尽内容/材料吗?
答案 0 :(得分:9)
清除混乱的最佳来源是Peter Van der Linden,专家C编程,Deep C机密 - 数组和指针不同,它们是如何在内存中处理的。
使用数组
char new_str[];,编译器为new_str提供了编译和运行时都知道的内存地址,例如: 0x1234,因此使用
[]
可以简化new_str的索引。例如new_str[4]
,在运行时,代码选择new_str
所在的地址,例如[4]
。 0x1234(即物理内存中的地址)。通过向其添加索引说明符char new_str[]
,0x1234 + 0x4,可以检索该值。
然而,使用指针,编译器会给符号
char *newstr一个地址,例如0x9876,但在运行时,使用的地址是间接寻址方案。假设newstr是malloc'd
newstr = malloc(10);,正在发生的事情是,每次代码中的引用都使用newstr,因为newstr的地址是编译器已知的,即0x9876,但是newstr指向的是什么是可变的。在运行时,代码从物理内存0x9876(即newstr)获取数据,但是在该地址是另一个内存地址(因为我们将它malloc),例如0x8765它在这里,代码从该内存地址获取数据malloc分配给newstr,即0x8765。
char *newstr
和newstr[5]
可互换使用,因为数组的第零个元素索引衰减为指针,这解释了为什么你可以*(newstr + 5)
或char *newstr
注意指针表达式的使用方式,即使我们已声明*(new_str + 1)
,因此
*(new_str + 1)
= *newstr;
或{{1}} = newstr[1];
总之,两者之间的真正区别在于如何在内存中访问它们。
拿到书并阅读并活着并呼吸它。这是一本精彩的书! :)
答案 1 :(得分:8)
请通过以下this article:
另外,在你的情况下看char的数组,char new_str []然后new_str 总是指向数组的基数。指针本身不能递增。是的,您可以使用下标来访问数组中的下一个字符,例如:new_str[3]
;
但是在指向char的情况下,指针可以递增new_str++
以获取数组中的下一个字符。
另外,我建议this article更清晰。
答案 2 :(得分:6)
这是一个字符数组:
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
答案 3 :(得分:2)
区别在于一个是指针,另一个是数组。例如,您可以使用sizeof()数组。您可能对偷看here
感兴趣答案 4 :(得分:1)
第一个的类型是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.
答案 5 :(得分:1)
如果您正在使用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 ++字符串,那么很多工作都是为您完成的。
答案 6 :(得分:0)
char new_str[]="abcd";
这指定了一个大小为5个字节的字符数组(一个字符串)(每个字符一个字节加上一个空终止符)。因此它将字符串'abcd'存储在内存中,我们可以使用变量new_str来访问该字符串。
char *new_str="abcd";
这指定字符串'abcd'存储在内存中的某个位置,指针new_str指向该字符串的第一个字符。
答案 7 :(得分:0)
在内存分配方面区分它们:
// 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";
答案 8 :(得分:-2)
如果您使用的是c ++,为什么不使用std::string来满足您的所有字符串需求?特别是处理串联的任何事情。这样可以避免许多问题。