0

I am very much confused with pointers. If we create a pointer variable of type 'char', that is some thing like char *ch; and assign a character array to it. Then we can access each letter in the string by increasing the pointer (++ch).

char *ch;
char a[5]="hello";
*ch=a;
while(*ch) {
  printf("%c",*ch);
  ++ch;
}

This works perfectly fine. But I see many examples like,

struct example {
  char *ch;
};

int main() {
  struct example ex={"hello"};
  printf("%s",ex.ch);
}

I am pretty confused with this example like how directly assigning a string to a character pointer(instead of assigning the string to a variable and then assigning it to character pointer) can make it accessible. In the previous case, *ch points to the starting memory of the array "a". But in the second case to which memory does the pointer ch point to? Can anyone give me a clear explanation?

Cloud
  • 18,753
  • 15
  • 79
  • 153
Sparrow
  • 195
  • 2
  • 5
  • 15
  • a string literal is a character pointer. implementations can handle this differently, but its usually a pointer to a predefined character array somewhere in the text (executable) or read only memory. – Steve Cox Jul 14 '14 at 18:38
  • 1
    On the contrary, a string literal is a character array, which decays into a pointer when it must. – Cameron Jul 14 '14 at 18:40
  • 3
    `*ch=a` should be `ch=a`, right? – Sergey Kalinichenko Jul 14 '14 at 18:40
  • 1
    @SteveCox: No, it is not. A string literal corresponds to an object of type `char[N]`, where `N` is one greater than the length (to allow for the terminating `'\0'` null character). Like any expression of array type it is, in most but not all contexts, implicitly converted to a pointer to its first element. See section 6 of the [comp.lang.c FAQ](http://www.c-faq.com/). – Keith Thompson Jul 14 '14 at 18:40
  • the second example is like: char *ch="hello"; – dari Jul 14 '14 at 18:41
  • 1
    @Cameron sorry bud, but you're wrong, if string literals were character arrays then `(sizeof("Hello World")/sizeof(char))` would be 12, and its not – Steve Cox Jul 14 '14 at 18:41
  • Your first example is not perfectly fine. `ch` is uninitalized. Assigning to `*ch` is undefined behaviour. – chris Jul 14 '14 at 18:41
  • 2
    @SteveCox, It sure is 12. – chris Jul 14 '14 at 18:42
  • 3
    `char a[5]="hello";`. You didn't leave room for the null terminator. – indiv Jul 14 '14 at 18:43

3 Answers3

2

When you make this assignment

ch=a;

you are setting the pointer ch to the beginning of the character array a[] (note: the fact that the array remains null-terminated is a pure coincidence - your code has undefined behavior, because the sixth character '\0' at the end of "hello" is not copied into a five-character array). After the assignment ch becomes an "alias" to the C string stored inside the array a[], which means that you can use it with string manipulation and formatting routines.

Your second example is not an assignment, it is initialization:

struct example ex={"hello"};

Enclosed in curly braces is an initializer. C compiler will take each element (you've got only one, but there can be many) and assign it to the corresponding field of the struct. In this case, string literal "hello" is assigned to the ch member.

The rule for initializers is to assign the values in curly braces in declaration order. You have an opportunity to override it if you wish by using the designated initializer feature of C99:

struct example ex={ .ch = "hello"};
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

This code snippet

char *ch;
char a[5]="hello";
*ch=a;
while(*ch)
{
printf("%c",*ch);
++ch;

}

has undefined behaviour. That it would work fine you have to declare the character array either as

char a[6]="hello";

or char a[]="hello";

In this case the array indeed will have the terminating zero.

As for this code snippet

struct example
{
char *ch;
};
int main()
{
struct example ex={"hello"};
printf("%s",ex.ch);
}

then in this statement

struct example ex={"hello"};

the compiler at first places string literal "hello" in memory as a character array having type char[6] and then assign pointer to the first element of the array to data member ch of the structure.

The difference between these two declarations

char ch[] = "hello";

and

char *ch = "hello";

is that that in the first case a character array is created each element of which is initialized by corresponding character of the string literal that itself will not be stored in memory. In the second case the string literal will be stored in memory and pointer ch will contain the address of its first character.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0
char a[] = "hi";
char *ch = "hello";

Here a is a char array of size 3 bytes to store, 'h', 'i' and '\0'. 3 bytes of this memory is allocated in stack to keep the string.

Here ch is a pointer variable, which store a address of char, and size of ch is 4 bytes to store the address (size of pointer is compiler specific). Then "hello" is a constant string literal which will be in text segment of process memory as a read only data. And the address of the first byte is assigned to ch variable. 4 byte of memory is allocated for ch variable to store address in stack and 5 byte of memory is required in text segment to keep the string literal "hello".

For explanation in some other views read here.

Community
  • 1
  • 1
  • Assuming pointers will always be four or eight bytes is not a safe assumption. You might want to look through some of the examples [here](http://stackoverflow.com/questions/399003/is-the-sizeofsome-pointer-always-equal-to-four). – chris Jul 14 '14 at 18:56
  • ya sure. I just mentioned the info which is common in most of the compilers. Size of pointer and int is 2 bytes in Turbo C compiler on windows 32 bit machine. anyway I updated my answer. – finalsemester.co.in Jul 14 '14 at 19:02