The character pointer takes the address of what

I read that:

char a[] = "string"; 

there is a: "string"

then

 char *ptr = "string" 

there is ptr: [__] ---> "string"

I'm a little confused. One thing I know is that pointers always store an address. In the case of a character pointer, what address does it store? What this block represents (the block that I pointed to the line). This is the starting address of the string.

And in the case of an array? How can I clearly distinguish between a char pointer and a char array?

+5
source share
7 answers

Charts can help.

 char *ptr = "string"; +-------+ +----------------------------+ | ptr |--------->| s | t | r | i | n | g | \0 | +-------+ +----------------------------+ char a[] = "string"; +----------------------------+ | s | t | r | i | n | g | \0 | +----------------------------+ 

Here ptr is a variable that contains a pointer to some (constant) data. You can subsequently change the memory address it points to by assigning a new ptr value, for example ptr = "alternative"; , but you cannot legally modify the contents of an array containing "string" (it is officially readonly or const , and attempting to change it may cause your program to crash or otherwise break things unexpectedly).

In contrast, a is the constant address of the first byte of 7 bytes of data, which is initialized to the value "string" . I did not show any storage for the address, because, unlike the pointer variable, there is no part of the removable memory that contains the address. You cannot change the memory address pointed to by a ; he always points to the same space. But you can change the contents of the array (for example, strcpy(a, "select"); ).

When you call the function, the difference disappears:

 if (strcmp(ptr, a) == 0) …string is equal to string… 

The strcmp() function accepts two pointers to constant char data (therefore, it does not modify what was given to it for verification), and both ptr and a tags are passed as pointer values. There is a good argument for the fact that only pointers are passed to the function - never arrays - even if the function is written using the notation of the array.

However, and this is important, arrays (outside parameter lists) are not pointers. Among other reasons, it is argued that:

  • sizeof(a) == 7
  • sizeof(ptr) == 8 (for 64-bit) or sizeof(ptr) == 4 (32-bit).
+4
source

In the case of a character pointer, what address does it store? What this block represents (the block that I pointed to the line). This is the starting address of the string.

These blocks are WORD or DWORD (depending on architecture), the contents of this block are a memory address, a random location determined at compile time. This memory address is the address of the first character of the string.

In practice, the difference is how much memory the stack uses.

For example, when programming for microcontrollers, where very little memory is allocated for the stack, it is of great importance.

 char a[] = "string"; // the compiler puts {'s','t','r','i','n','g', 0} onto STACK char *b = "string"; // the compiler puts just the pointer onto STACK // and {'s','t','r','i','n','g',0} in static memory area. 

Perhaps this will help you understand.

 assert(a[0] == 's'); // no error. assert(b[0] == 's'); // no error. assert(*b == 's'); // no error. b++; // increment the memory address, so points to 't' assert(*b == 's'); // assertion failed assert(*b == 't'); // no error. 
+2
source

char a[] = "string"; initializes the value of a char array called a with the value string . And size a .

char *a = "string"; creates an unnamed static char array somewhere in memory and returns the address of the first element of this unnamed array in a .

In the first, a stores the address of the first element of the array. Therefore, when we index something like [4], it means β€œtake” the 4th element after the start of the object with the name a.

In the second, a[4] means β€œtake” the 4th element after the object that points to.

And for your last question:

A char array is a "block" of adjacent elements of type char. The char pointer is a reference to an element of type char.

Due to pointer arithmetic, a pointer can be used to simulate (and access) an array.

Perhaps these 3 links help make the difference clearer:

http://c-faq.com/decl/strlitinit.html

http://c-faq.com/aryptr/aryptr2.html

http://c-faq.com/aryptr/aryptrequiv.html

+2
source

You may find it useful to think:

 char * a = "string"; 

as well as:

 char SomeHiddenNameYouWillNeverKnowOrSee[] = "string"; /* may be in ReadOnly memory! */ char * a = &SomeHiddenNameYouWillNeverKnowOrSee[0]; 
+1
source

Have you ever tried to open some executabe file with a text editor? It just looks like garbage, but in the middle of the garbage you can see some readable lines. These are all lettering strings defined in your program.

 printf("my literal text"); char * c = "another literal text"; // should be const char *, see below 

If your program contains the above code, you can find my literal text and another literal text in the binary code of the program (in fact, it depends on the details of the binary format, but it often works). If you are a Linux / Unix user, you can also use the strings command to do this.

By the way, if you write the code above, C ++ compilers will give a warning (g ++ say: warning: deprecated conversion from string constant to 'char*' , because such strings are not of type char * , but const char [] (const char array), which decays to const char * when assigned to a pointer.

This also applies to C compilers, but the above error is so common that this warning is usually turned off. gcc does not even include in -Wall, you must explicitly enable it through -Wwrite-strings . Warning warning: initialization discards 'const' qualifier from pointer target type .

It just reminds you that you are theoretically not allowed to change literal texts with pointers.

An executable file can load such lines in read-only parts in the memory of a data segment. If you try to change the contents of a string, this may result in a memory error. Also, the compiler is allowed to optimize literal text storage, for example, by merging identical strings. The pointer simply contains an address in memory (read-only) where literals will be loaded.

On the other hand,

char c[] = "string"; is a simple syntactic sugar for char c[7] = {'s', 't', 'r', 'i', 'n', 'g', 0}; If you execute sizeof(c) in your code, it will be 7 bytes (the size of the array, not the size of the pointer). This is an array on the stack with an initializer. Internally, the compiler can do it anyway when it likes to initialize an array. It can be character constants loaded one by one into the array, or it can include memcpy of some hidden string literal. The fact is that you do not have the opportunity to tell the difference with your program and find out where the data came from. Only the result matters.

By the way, a bit confusing thing is that if you define a function parameter of type char c[] , it will not be an array, but an alternative syntax for char * c .

+1
source

In your example, ptr contains the address of the first char in the string.

As for the difference between a char array and a string, in terms of C there is no difference other than the fact that, by convention, what we call a β€œstring” is a char array, where the final char is NULL to end the string.

i.e. even if we have an array of char with 256 potential elements, if the first (0th) char is zero (0), then the string length is 0.

Consider the str variable, which is a 5-character char array containing the string 'foo' .

 *ptr => str[0] 'f' str[1] 'o' str[2] 'o' str[3] \0 str[4] .. 

A char * ptr to this array will refer to the first element (index = 0), and the fourth element (index = 3) will be empty, indicating the end of the line. The fifth element (index = 4) will be ignored using string processing procedures that take into account zero limiter.

0
source

If you ask what it contains in each case, then:

 char a[] = "string"; // a is a pointer. // It contains the address of the first element of the array. char *a = "string"; // Once again a is a pointer containing address of first element. 

As rnrneverdies explained in his answer, the difference is where the elements are stored.

-1
source

Source: https://habr.com/ru/post/1202198/


All Articles