A summary of the differences between Char *s and Char s[]

Source: Internet
Author: User
Tags array definition

There are many C procedures, in the communication with the new members of the project found that generally for Char *s1 and Char s2[] know there are misunderstandings (think no difference), resulting in sometimes "difficult to understand" error. A moment can not be said very clearly, the Internet also searched for some of the relevant articles found that some of the better, integrated a bit when the educational materials spare.

char *s1 = "Hello";
Char s2[] = "Hello";

"Location is very different"

Char *s1 is s1, and the pointer is to a chunk of memory, and the size of the memory area it points to can change at any time, and when the pointer points to a constant string, its contents cannot be modified or it will be error-free at run time.
Char s2[] s2 is an array corresponding to an area of memory, its address and capacity will not change in the lifetime, only the contents of the array can be changed

"Memory Model"
+-----+     +---+---+---+---+---+---+
S1: | *======> | H | e | l | l | o |\0 |
+-----+     +---+---+---+---+---+---+
+---+---+---+---+---+---+
S2: | H | e | l | l | o |\0 |
+---+---+---+---+---+---+

Scene one)
char *s1 = "Hello";
Char s2[] = "Hello";
S2=S1; Compile error
S1=S2; Ok

Analysis: S2 its address and capacity cannot be changed during the life cycle

Scene II)
Char s2[] = "Hello";
char *s1 = s2; The compiler did an implicit conversion actually for &S2
Or
Char *s1 = &s2;

Analysis: The above two pointer complex value is completely equivalent, because the compiler will do this implicit conversion is also easy to cause the beginner mistakenly think that Char *s and Char s[] is one thing.
The second type is used in some compilers to even report warning messages.

Scenario three)
char *s1 = "Hello";
Char s2[] = "Hello";
S1[0]= ' a '; X Run error (this sentence seems to be in some compiler without error, cause unknown origin)
S2[0]= ' a '; Ok

Analysis: The runtime will error, because the attempt to change the content of S1, because S1 points to a constant string, its content is not modifiable, so at run time will not pass. Instead, S2 points to a variable-area string that can be modified.

Scene four)
Let's assign a pointer pointer to an enhanced version of scenario two when using some of the functions with char** parameters.
Char *s1= "Hello";
Char s2[]= "Hello";
Char *s3=s2; ★ Pay attention to this sentence must be ★
Char **s4=&s3; S2 (char[]) takes two steps to complete the assignment
Char **s5=&s1; S1 (char*) only one step
printf ("s4=[%s]\n", *s4);//Print result: S4=[hello]
printf ("s5=[%s]\n", *s5);//Print result: S5=[hello]

Analysis: This example should say that the difference between char * and char is best reflected, but because of the lack of use, the newcomers need to be especially careful.

Here are some of the same places as Char *s1 and Char s2[] (the same compiler has implicitly changed char[):
1) exactly the same as the formal parameter
Such as:
void function (char *s1);
void function (char s1[]);

2) Only when the read is not modified
Such as:
Char *s1= "Hello";
Char s2[]= "Hello";
printf ("s1[1]=[%c]\n", s1[1]); S1[1]=[e]
printf ("s2[1]=[%c]\n", s2[1]); S2[1]=[e]
printf ("s1=[%s]\n", S1); S1=[hello]
printf ("s2=[%s]\n", S2); S2=[hello]

Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The following content is from the Internet, the author summarizes and summarizes.

1. Introduction of the problem

Problem Introduction:
During the internship, a previously default error was found, and the same char *c = "abc" and Char c[]= "ABC", the former changing its

The capacity program crashes, and the latter is completely correct.
Program Demo:
Test environment devc++
Code
#include <iostream>
using namespace Std;

Main ()
{
char *C1 = "abc";
Char c2[] = "ABC";
Char *c3 = (char*) malloc (3);
C3 = "ABC";
printf ("%d%d%s\n", &C1,C1,C1);
printf ("%d%d%s\n", &C2,C2,C2);
printf ("%d%d%s\n", &C3,C3,C3);
GetChar ();
}
Run results
2293628 4199056 ABC
2293624 2293624 ABC
2293620 4199056 ABC

Resources:
The first thing to figure out is the partitioning of the memory that the compiler occupies:
I. Preliminary knowledge-memory allocation of the program
The memory used by a program compiled by C + + is divided into the following sections
1. Stack (stack)-Automatically allocated by the compiler to release, store the function parameter value, local variable value and so on. It operates in a manner similar to

The stack in the data structure.
2, heap area (heap)-Generally by the programmer assigned to release, if the programmer does not release, the end of the program may be recycled by the OS. Note it with the data

The heap in the structure is two different things, the distribution way is similar to the list, hehe.
3. Global zone (static zone)-the storage of global variables and static variables is placed in a block, initialized global variables and static

Variables in an area, uninitialized global variables, and uninitialized static variables in another contiguous area. After the program is completed by the system

Release.
4, literal constant area-the constant string is put here. Released by the system after the program is finished.
5. Program code Area
It was written by a predecessor, very detailed
Main.cpp
int a=0; Global initialization Zone
Char *p1; Global uninitialized Zone
Main ()
{
int b; stack
Char s[]= "ABC"; Stack
Char *p2; Stack
Char *p3= "123456"; 123456\0 in the constant area, p3 on the stack.
static int c=0;//Global (Static) initialization area
P1 = (char*) malloc (10);
P2 = (char*) malloc (20); Areas that are allocated 10 and 20 bytes are in the heap area.
strcpy (P1, "123456"); 123456\0 is placed in a constant area, the compiler may optimize it with the P3 to "123456" as a

Place.
}
Ii. theoretical knowledge of heaps and stacks
2.1 How to apply
Stack
Automatically assigned by the system. For example, declare a local variable in the function int b; The system automatically opens up space for B in the stack
Heap
Requires the programmer to apply himself and indicate the size of the malloc function in C
such as p1= (char*) malloc (10);
Using the new operator in C + +
such as p2= (char*) malloc (10);
But note that P1, p2 itself is in the stack.
2.2
Response of the system after application
Stack: As long as the remaining space of the stack is larger than the requested space, the system will provide memory for the program, otherwise it will report the exception prompt stack overflow.
Heap: First you should know that the operating system has a list of idle memory addresses, when the system receives the application of the program,
The linked list is traversed, looking for a heap node where the first space is larger than the requested space, and then removing the node from the list of idle nodes and

The space of the node is allocated to the program, and for most systems, the allocation is recorded at the first address in this memory space.

Small so that the DELETE statement in the code can properly free up the memory space. Also, because the size of the found heap node is not necessarily

is equal to the size of the application, the system will automatically re-put the extra part in the idle list.
2.3 Application Size Limits
Stack: Under Windows, the stack is the data structure to the low address extension, which is a contiguous area of memory. This sentence means the top of the stack.

The maximum capacity of the site and stack is pre-defined, under Windows, the stack size is 2M (and some say 1M, in short, a compilation

If the requested space exceeds the remaining space on the stack, the overflow will be prompted. Therefore, the space that can be obtained from the stack

Smaller.
Heap: A heap is a data structure that extends to a high address, and is a discontinuous area of memory. This is because the system is stored in a linked list of free memory ground

is not contiguous, and the traversal direction of the list is from the low address to the high address. The size of the heap is limited by the effectiveness of the computer

Virtual memory. Thus, the space of the heap is more flexible and relatively large.
2.4 Comparison of application efficiency:
Stack: Automatically allocated by the system, faster. But programmers can't control it.
Heap: Is the memory allocated by new, the general speed is slow, and prone to memory fragmentation, but the most convenient to use.
In addition, under Windows, the best way is to use virtual alloc to allocate memory, he is not in the heap, nor in the stack, but directly in the

Memory in the address space of the process, although it is most inconvenient to use. But the speed is fast, also the most flexible.
2.5 Storage contents in stacks and stacks
Stack: When a function is called, the first stack is the next instruction in the main function (the next executable statement in the function call statement)

Address, and then the parameters of the function, in most C compilers, the arguments are in the right-to-left stack, and then the local variable in the function

Amount Note that static variables are not in the stack.
When the function call is finished, the local variable is first out of the stack, then the parameter, and the last stack pointer points to the first saved address, which is the primary

The next instruction in the function, the program continues to run from that point.
Heap: The size of a heap is typically stored in a heap at the head of a pile. The concrete contents of the heap are arranged by the programmer.
2.6 Comparison of access efficiency
Char s1[]= "AAAAAAAAAAAAAAA";
Char *s2= "BBBBBBBBBBBBBBBBB";
AAAAAAAAAAA is assigned at run time;
And BBBBBBBBBBB is determined at compile time;
However, in subsequent accesses, the array on the stack is faster than the string that the pointer points to (for example, a heap).
Like what:
#include
Voidmain ()
{
Char a=1;
Char c[]= "1234567890";
Char *p= "1234567890";
A = c[1];
A = p[1];
Return
}
The corresponding assembly code
10:A=C[1];
004010678A4DF1MOVCL,BYTEPTR[EBP-0FH]
0040106a884dfcmovbyteptr[ebp-4],cl
11:A=P[1];
0040106D8B55ECMOVEDX,DWORDPTR[EBP-14H]
004010708A4201MOVAL,BYTEPTR[EDX+1]
004010738845fcmovbyteptr[ebp-4],al
The first reads the elements in the string directly into the register CL, while the second one reads the pointer value into edx, based on

EdX reads the characters, apparently slowly.
2.7 Summary:
The difference between heap and stack can be seen in the following analogy:
Use stacks like we eat in a restaurant, just order (apply), pay, and eat (use), eat enough to go, don't bother

Cutting vegetables, washing vegetables and other preparation work and washing dishes, brush pots and other finishing work, his advantage is quick, but the freedom is small.
The use of the heap is like a DIY dish that you like to eat, more trouble, but more in line with their own tastes, and great freedom.

Self-Summary:
char *C1 = "abc"; in fact, first in the literal constant area is allocated a piece of "ABC", then assign an address on the stack to C1 and point to

This block address, and then change the constant "ABC" will naturally crash

Char c2[] = "abc", in fact the place where ABC allocates memory is not the same as the above, and can be
4199056
2293624 See, is completely two places, inferred 4199056 is in the constant area, and 2293624 is in the stack area

2293628
2293624
2293620 This output shows that three pointers are allocated to the stack area and are from high address to low address

2293620 4199056 ABC sees that the compiler will C3 optimize the "ABC" to the constant area


Continue thinking:
Code:
#include <iostream>
using namespace Std;

Main ()
{
char *C1 = "abc";
Char c2[] = "ABC";
Char *c3 = (char*) malloc (3);
*C3 = "ABC"//error
strcpy (C3, "abc");
C3[0] = ' g ';
printf ("%d%d%s\n", &C1,C1,C1);
printf ("%d%d%s\n", &C2,C2,C2);
printf ("%d%d%s\n", &C3,C3,C3);
GetChar ();
}
Output:
2293628 4199056 ABC
2293624 2293624 ABC
2293620 4012976 GBC
As a comment, the subsequent changes will crash.
Visible strcpy (C3, "ABC"), ABC is assigned in another place, and can be changed, and the reference document above is not necessarily,

And I can not determine which area 4012976 is, may have to pass the length of the area, I hope that the expert continued in-depth explanation, thank you

2. An example

[CPP]View Plaincopyprint?
  1. int *ip = new int;
  2. char s[] = "ABCD";
  3. char* p = "ABCD";
  4. cout<<ip<<endl;
  5. cout<<*ip<<endl;
  6. cout<<&ip<<endl;
  7. s = p; Error C2440: ' = ': cannot convert from ' char * ' to ' char '
  8. //Is s not a pointer to the first character?
  9. cout << S <<endl;  //It is true that the word output is abcd!
  10. cout << *s <<endl;  //But the output of this sentence is a!
  11. cout << &s <<endl;
  12. cout << (s+1) <<endl;
  13. cout << & (s+1) <<endl;//error C2102: ' & ' requires L-value
  14. cout << * (s+1) <<endl;
  15. cout << &s[1] <<endl;
  16. cout << P <<endl;
  17. cout << *p <<endl;
  18. cout << &p <<endl;
  19. cout << (p+1) <<endl;
  20. cout << & (p+1) <<endl;//error C2102: ' & ' requires L-value
  21. cout << * (p+1) <<endl;
  22. cout << &p[1] <<endl;


Output:

Related explanations:

Char[] is an array definition, char* is a pointer definition, you can look at their differences and it will help you.
1 pointer and array differences

(1) pointer and array assignment

An array is a contiguous memory space, and the identifier of the array itself (that is, commonly known as the array name) represents the entire array, and sizeof can be used to get the size of the memory space occupied by the array (note that it is not the number of array elements, but the size of the array that occupies the memory space, in bytes). Examples are as follows:

#include <stdio.h>

int main (void)
{
Char a[] = "Hello";
int b[] = {1, 2, 3, 4, 5};

printf ("A:%d\n", sizeof (a));
printf ("B Memory Size:%d bytes\n", sizeof (b));
printf ("B Elements:%d\n", sizeof (b)/sizeof (int));

return 0;
}



The array A is a character type, and the following string actually occupies 6 bytes (note that there is finally an end to the ID string). From the back, sizeof (b) can see how to get the memory space occupied by the array, how to get the number of elements of the array. As for how much the int data type allocates memory space, it is compiler-dependent. GCC defaults to an int type that allocates 4 bytes of memory space.

(2) Allocation of space

There are two different situations here.

First, if it is global and static
char *p = "Hello";
This is defined as a pointer to "Hello" inside the Rodata section, which can be placed into the string pool by the compiler. The key word in the assembly is. Ltorg. This means that strings in the string pool can be shared, which is also a measure of compiler optimizations.
Char a[] = "Hello";
This is defined as an array that is allocated in a writable data block and is not placed into a string pool.

Second, if it's a partial
char *p = "Hello";
This is defined as a pointer to "Hello" inside the Rodata section, which can be placed into the string pool by the compiler. The key word in the assembly is. Ltorg. This means that strings in the string pool can be shared, which is also a measure of compiler optimizations. In addition, the address of the function can be returned, that is, the pointer is a local variable, but the content it points to is global.
Char a[] = "Hello";
This is defined by an array, allocated on the stack, initialized by the compiler. (The short time is filled directly with the instruction, long time from the Global string table copy), will not be placed into the string pool (as before, may be copied from the string pool). Note that its address should not be returned.

The following conclusions have been drawn from the cout study:
1, for numeric pointers such as int *p=new int; Then Cout<<p will only output the value of this pointer, not the content that the pointer points to.
2, for the character pointer into char *p= "SDF F"; then cout<<p will output the data that the pointer points to, i.e. SDF F

============================================================================

If you do not understand, there are also tall wood on the water to explain this:

Here char ch[]= "ABC"; indicates that CH is a one-dimensional array sufficient to hold the initial value of the string and the null character '/0 ', you can change the characters in the array, but the char itself is an immutable constant. char *pch = "ABC"; If the PCH is a pointer, its initial value points to a string constant, and then it can point to another location, but if you try to modify the contents of the string, the result is indeterminate.     ___           ___      ______ch: |abc\0 |    PCH: | ----->  |abc\0 |     ___           ___      ______char Charray[100];charray[i] is equivalent to * (charray+i) and the pointer is different in that the   Charray is not a variable   cannot be assigned to another   in fact I[charray]  is also equivalent to * (Charray+i)

Therefore, it is summarized as follows:

1. char[] p indicates that p is an array pointer, equivalent to a const pointer, which is not allowed to be modified. But the array contents that the pointer points to are allocated on top of the stack and can be modified.

2. Char * PP indicates that PP is a variable pointer that allows modification of it, which can point to other places, such as PP = P is also possible. For *pp = "abc"; in this case, because of compiler optimizations, the ABC is generally stored in the constant area, and then the PP pointer is a local variable, stored in the stack, so in the function return, it is allowed to return the address (actually point to a constant address, string constant area); char[] P is a local variable, and when the function ends, the contents of the array that exist on the stack are destroyed, so the return P address is not allowed.

At the same time, as can be seen from the above example, cout does exist some laws:

1, for numeric pointers such as int *p=new int; Then Cout<<p will only output the value of this pointer, not the content that the pointer points to.
2, for the character pointer into char *p= "SDF F"; then cout<<p will output the data that the pointer points to, i.e. SDF F

So, like & (P+1), because p+1 points to an address, not a pointer, the fetch operation cannot be performed.

&P[1] = &p + 1, which is actually the string content starting from p+1.

Analyze the above program:

*PP = "ABC";

p[] = "ABC";

*PP points to the first character in a string.

cout << pp; The string that returns the start of the PP address: ABC

cout << p; A string that returns the start of the P address: ABC

cout << *p; Returns the first character: a

cout << * (p+1); Returns a second character: b

cout << &p[1];//Returns a string starting with the second character: BC

A summary of the differences between Char *s and Char s[]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.