Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences between arrays, pointers and strings in C

Just have a question in mind that troubles me.

I know pointers and arrays are different in C because pointers store an address while arrays store 'real' values.

But I'm getting confused when it comes to string.

char *string = "String";

I read that this line does several things :

An array of chars is created by the compiler and it has the value String.

Then, this array is considered as a pointer and the program assigns to the pointer string a pointer which points to the first element of the array created by the compiler.

This means, arrays are considered as pointers.

So, is this conclusion true or false and why ?

If false, what are then the differences between pointers and arrays ? Thanks.

like image 758
user5491 Avatar asked Jun 04 '15 15:06

user5491


2 Answers

A pointer contains the address of an object (or is a null pointer that doesn't point to any object). A pointer has a specific type that indicates the type of object it can point to.

An array is a contiguous ordered sequence of elements; each element is an object, and all the elements of an array are of the same type.

A string is defined as "a contiguous sequence of characters terminated by and including the first null character". C has no string type. A string is a data layout, not a data type.

The relationship between arrays and pointers can be confusing. The best explanation I know of is given by section 6 of the comp.lang.c FAQ. The most important thing to remember is that arrays are not pointers.

Arrays are in a sense "second-class citizens" in C and C++. They cannot be assigned, passed as function arguments, or compared for equality. Code that manipulates arrays usually does so using pointers to the individual elements of the arrays, with some explicit mechanism to specify how long the array is.

A major source of confusion is the fact that an expression of array type (such as the name of an array object) is implicitly converted to a pointer value in most contexts. The converted pointer points to the initial (zeroth) element of the array. This conversion does not happen if the array is either:

  • The operand of sizeof (sizeof array_object yields the size of the array, not the size of a pointer);

  • The operand of unary & (&array_object yields the address of the array object as a whole); or

  • A string literal in an initializer used to initialize an array object.

    char *string = "String";

To avoid confusion, I'm going to make a few changes in your example:

const char *ptr = "hello";

The string literal "hello" creates an anonymous object of type char[6] (in C) or const char[6] (in C++), containing the characters { 'h', 'e', 'l', 'l', 'o', '\0' }.

Evaluation of that expression, in this context, yields a pointer to the initial character of that array. This is a pointer value; there is no implicitly created pointer object. That pointer value is used to initialize the pointer object ptr.

At no time is an array "treated as" a pointer. An array expression is converted to a pointer type.

Another source of confusion is that function parameters that appear to be of array type are actually of pointer type; the type is adjusted at compile time. For example, this:

void func(char param[10]);

really means:

void func(char *param);

The 10 is silently ignored. So you can write something like this:

void print_string(char s[]) {
    printf("The string is \"%s\"\n", s);
}
// ...
print_string("hello");

This looks like just manipulating arrays, but in fact the array "hello" is converted to a pointer, and that pointer is what's passed to the print_string function.

like image 92
Keith Thompson Avatar answered Oct 15 '22 11:10

Keith Thompson


So, is this conclusion true or false and why ?

Your conclusion is false.

Arrays and pointers are different. comp.lang.c FAQ list · Question 6.8 explains the difference between arrays and pointers:

An array is a single, preallocated chunk of contiguous elements (all of the same type), fixed in size and location. A pointer is a reference to any data element (of a particular type) anywhere. A pointer must be assigned to point to space allocated elsewhere, but it can be reassigned (and the space, if derived from malloc, can be resized) at any time. A pointer can point to an array, and can simulate (along with malloc) a dynamically allocated array, but a pointer is a much more general data structure.

When you do

char *string = "String";  

and when a C compiler encounters this, it sets aside 7 bytes of memory for the string literal String. Then set the pointer string to point to the starting location of the allocated memory.

enter image description here

When you declare

char string[] = "String";    

and when a C compiler encounters this, it sets aside 7 bytes of memory for the string literal String. Then gives the name of that memory location, i.e. the first byte, string.

enter image description here

So,

  • In first case string is a pointer variable and in second case it is an array name.
  • The characters stored in first case can't be modified while in array version it can be modified.

This means arrays is not considered as pointers in C but they are closely related in the sense that pointer arithmetic and array indexing are equivalent in C, pointers and arrays are different.

like image 37
haccks Avatar answered Oct 15 '22 11:10

haccks