简体   繁体   English

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

[英]Difference between using character pointers and character arrays

Basic question. 基本问题。

char new_str[]="";

char * newstr;

If I have to concatenate some data into it or use string functions like strcat/substr/strcpy, what's the difference between the two? 如果我必须将一些数据连接到它或使用字符串函数如strcat / substr / strcpy,两者之间的区别是什么?

I understand I have to allocate memory to the char * approach (Line #2). 我知道我必须为char *方法分配内存(第2行)。 I'm not really sure how though. 我不太确定如何。

And const char * and string literals are the same? const char *和字符串文字是一样的吗?

I need to know more on this. 我需要了解更多。 Can someone point to some nice exhaustive content/material? 有人能指出一些不错的详尽内容/材料吗?

Please go through this article below: 请仔细阅读以下文章

Also see in case of array of char like in your case, char new_str[] then the new_str will always point to the base of the array. 另外,在你的情况下查看char数组,char new_str []然后new_str将始终指向数组的基数。 The pointer in itself can't be incremented. 指针本身不能递增。 Yes you can use subscripts to access the next char in array eg: new_str[3] ; 是的,您可以使用下标来访问数组中的下一个char,例如: new_str[3] ;

But in case of pointer to char, the pointer can be incremented new_str++ to fetch you the next character in the array. 但是在指向char的情况下,指针可以递增new_str++以获取数组中的下一个字符。

Also I would suggest this article for more clarity. 我还建议这篇文章更清晰。

The excellent source to clear up the confusion is Peter Van der Linden, Expert C Programming, Deep C secrets - that arrays and pointers are not the same is how they are addressed in memory. 消除混淆的最佳来源是Peter Van der Linden,专家C编程,Deep C机密 - 数组和指针的不同之处在于它们在内存中的处理方式。

With an array, 有阵列,

char new_str[];
the compiler has given the new_str a memory address that is known at both compilation and runtime, eg 0x1234, hence the indexing of the new_str is simple by using [] . 编译器给new_str一个在编译和运行时都知道的内存地址,例如0x1234,因此使用[]可以简单地索引new_str。 For example new_str[4] , at runtime, the code picks the address of where new_str resides in, eg 0x1234 (that is the address in physical memory). 例如new_str[4] ,在运行时,代码选择new_str所在的地址,例如0x1234(即物理内存中的地址)。 by adding the index specifier [4] to it, 0x1234 + 0x4, the value can then be retrieved. 通过向其添加索引说明符[4] ,0x1234 + 0x4,然后可以检索该值。

Whereas, with a pointer, the compiler gives the symbol 然而,使用指针,编译器给出符号

 char *newstr char * newstr 
an address eg 0x9876, but at runtime, that address used, is an indirect addressing scheme. 地址,例如0x9876,但在运行时,使用的地址是间接寻址方案。 Supposing that newstr was malloc'd 假设newstr是malloc'd
 newstr = malloc(10); newstr = malloc(10); 
, what is happening is that, everytime a reference in the code is made to use newstr, since the address of newstr is known by the compiler ie 0x9876, but what is newstr pointing to is variable. ,正在发生的是,每次代码中的引用都使用newstr,因为newstr的地址是编译器已知的,即0x9876,但newstr指向的是变量。 At runtime, the code fetches data from physical memory 0x9876 (ie newstr), but at that address is, another memory address (since we malloc'd it), eg 0x8765 it is here, the code fetches the data from that memory address that malloc assigned to newstr, ie 0x8765. 在运行时,代码从物理内存0x9876(即newstr)获取数据,但是在该地址是另一个内存地址(因为我们将它malloc),例如0x8765它在这里,代码从该内存地址获取数据malloc分配给newstr,即0x8765。

The char new_str[] and char *newstr are used interchangeably, since an zeroth element index of the array decays into a pointer and that explains why you could newstr[5] or *(newstr + 5) Notice how the pointer expression is used even though we have declared char *newstr , hence char new_str[]char *newstr可以互换使用,因为数组第0个元素索引衰减成指针 ,这解释了为什么你可以使用newstr[5]*(newstr + 5)注意指针表达式是如何使用的虽然我们已经宣布了char *newstr ,因此

 *(new_str + 1) = *newstr; *(new_str + 1) = * newstr; 
OR 要么
 *(new_str + 1) = newstr[1]; *(new_str + 1) = newstr [1]; 

In summary, the real difference between the two is how they are accessed in memory. 总之,两者之间的真正区别在于如何在内存中访问它们。

Get the book and read it and live it and breathe it. 得到这本书并阅读它,然后活着并呼吸它。 Its a brilliant book! 这是一本精彩的书! :) :)

This is a character array: 这是一个字符数组:

char  buf [1000];

So, for example, this makes no sense: 所以,例如,这没有任何意义:

buf = &some_other_buf;

This is because buf , though it has characteristics of type pointer, it is already pointing to the only place that makes sense for it. 这是因为buf虽然具有类型指针的特性,但它已经指向唯一有意义的地方。

char *ptr;

On the other hand, ptr is only a pointer, and may point somewhere. 另一方面, ptr只是一个指针,可能指向某个地方。 Most often, it's something like this: 大多数情况下,它是这样的:

ptr = buf;              // #1:  point to the beginning of buf, same as &buf[0]

or maybe this: 或者这个:

ptr = malloc (1000);    // #2:  allocate heap and point to it

or: 要么:

ptr = "abcdefghijklmn"; // #3:  string constant

For all of these, *ptr can be written to—except the third case where some compiling environment define string constants to be unwritable. 对于所有这些,* 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

The difference is that one is a pointer, the other is an array. 区别在于一个是指针,另一个是数组。 You can, for instance, sizeof() array. 例如,您可以使用sizeof()数组。 You may be interested in peeking here 您可能有兴趣在这里偷看

The type of the first is char[1], the second is char *. 第一个的类型是char [1],第二个是char *。 Different types. 不同种类。

Allocate memory for the latter with malloc in C, or new in C++. 使用C中的malloc或C ++中的new来为后者分配内存。

char foo[] = "Bar";  // Allocates 4 bytes and fills them with
                     // 'B', 'a', 'r', '\0'.

The size here is implied from the initializer string. 此处的大小隐含在初始化字符串中。

The contents of foo are mutable. foo的内容是可变的。 You can change foo[i] for example where i = 0..3. 您可以更改foo[i] ,例如i = 0..3。

OTOH if you do: OTOH,如果你这样做:

char *foo = "Bar";

The compiler now allocates a static string "Bar" in readonly memory and cannot be modified. 编译器现在在只读内存中分配一个静态字符串“Bar”,不能修改。

foo[i] = 'X';  // is now undefined.

If you're using C++ as your tags indicate, you really should be using the C++ strings, not the C char arrays. 如果您正在使用C ++作为标记指示,那么您确实应该使用C ++字符串,而不是C char数组。

The string type makes manipulating strings a lot easier. string类型使得操作字符串变得更加容易。

If you're stuck with char arrays for some reason, the line: 如果由于某种原因你坚持使用char数组,那么该行:

char new_str[] = "";

allocates 1 byte of space and puts a null terminator character into it. 分配1个字节的空间并将空终结符字符放入其中。 It's subtly different from: 它与以下内容略有不同:

char *new_str = "";

since that may give you a reference to non-writable memory. 因为那可能会给你一个不可写内存的引用。 The statement: 该声明:

char *new_str;

on its own gives you a pointer but nothing that it points to. 它自己给你一个指针,但没有指向它。 It can also have a random value if it's local to a function. 如果它是函数的局部值,它也可以具有随机值。

What people tend to do (in C rather than C++) is to do something like: 人们倾向于做什么(在C而不是C ++中)是这样做的:

char *new_str = malloc (100); // (remember that this has to be freed) or
char new_str[100];

to get enough space. 获得足够的空间。

If you use the str... functions, you're basically responsible for ensuring that you have enough space in the char array, lest you get all sorts of weird and wonderful practice at debugging code. 如果你使用str...函数,你基本上负责确保你在char数组中有足够的空间,以免你在调试代码时得到各种奇怪和奇妙的练习。 If you use real C++ strings, a lot of the grunt work is done for you. 如果您使用真正的C ++字符串,那么很多工作都是为您完成的。

char new_str[]="abcd";  

This specifies an array of characters (a string) of size 5 bytes (one byte for each character plus one for the null terminator). 这指定了一个大小为5个字节的字符数组(一个字符串)(每个字符一个字节加上一个空终止符)。 So it stores the string 'abcd' in memory and we can access this string using the variable new_str. 所以它将字符串'abcd'存储在内存中,我们可以使用变量new_str访问该字符串。

char *new_str="abcd";  

This specifies a string 'abcd' is stored somewhere in the memory and the pointer new_str points to the first character of that string. 这指定字符串'abcd'存储在内存中的某处,指针new_str指向该字符串的第一个字符。

To differentiate them in the memory allocation side: 要在内存分配方面区分它们:

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

If you're in c++ why not use std::string for all your string needs? 如果您使用的是c ++,为什么不使用std :: string来满足您的所有字符串需求? Especially anything dealing with concatenation. 特别是处理串联的任何事情。 This will save you from a lot of problems. 这样可以避免许多问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM