1

Is there any difference in assigning the address of string literal to a character pointer?

char *ptr = &"Hello";
printf("%s",ptr);

When I printed, it printed "Hello" correctly. Is this similar to assigning address of array to a pointer? Is there any use of assigning address this way? What does &"Hello" returns? Constant pointer to a character?

char a[]="Hi";
char *ptr2 = &a;

Also &a+1 will print the address that is just outside of array boundary. However we cannot use this to get the size of an array it looks. I tried to print array contents something like below, but it just prints one character.

for(i=0;i<((&a+1)-&a);i++)  printf("%c",*ptr2++);
Jon Wheelock
  • 263
  • 3
  • 16

2 Answers2

4
char *ptr = &"Hello";

This is not valid . Compiler will issue a warning .

Type of "Hello" is char[6] and type of &"Hello" is char(*)[6] . Declare and initialize ptr like this -

char (*ptr)[6] = &"Hello";     // ptr is pointer to array of char of size 6

In for loop , your condition -

i<((&a+1)-&a);   // it should be i<(*(&a+1)-a);

But don't do this as it invokes undefined behaviour.

To know more about it refer here.

Community
  • 1
  • 1
ameyCU
  • 16,489
  • 2
  • 26
  • 41
  • Noticed that compiler warning was disabled. Now I am getting the warning atleast. – Jon Wheelock Oct 12 '15 at 17:17
  • @JonWheelock Well ,you should always enable compiler warning :) – ameyCU Oct 12 '15 at 17:24
  • Also just for curiosity, how do I print the address (&a)+1 instead of &a+1? If I put parenthesis, it still prints the address value beyond the array boundary. For example in the code below, I want the last print statement to display 0028FF05 and not 0028FF10. Is adding constant to (ptr*)[] is not allowed? char a[] = "Hello World"; char (*ptrToEntireArray)[] = &a; printf("&ptrToEntireArray = %p\n",&a); printf("&ptrToEntireArray+1 = %p\n",(&a)+1); Results: &ptrToEntireArray = 0028FF04 &ptrToEntireArray+1 = 0028FF10 – Jon Wheelock Oct 14 '15 at 04:11
  • @JonWheelock Printing address beyond boundary is not a problem , but trying to read/ write will have undefined behaviour . So ,printing that address should not be any problem I think . – ameyCU Oct 14 '15 at 07:07
  • My question is: If printf ("%p",&a) prints 0028FF04, how can I print the address 0028FF05? Adding 1 will add size of entire array to the first address. I want to print the absolute address 0028FF05 using &a. Note that this is just for curiosity and not for using it in coding. Also is there any use of &a? – Jon Wheelock Oct 17 '15 at 11:48
  • @JonWheelock Make as pointer `p` point to `&a`and while printing print address of `p+1` . See here -https://ideone.com/PyagZG – ameyCU Oct 17 '15 at 11:56
  • I think I got the answer. It should be *(&a)+1 and prints correctly. But still not clear why (&a) +1 prints the address of (0028FF04 + size of entire array) even though there is a parenthesis. So inside printf, pointer arithmetic work differently!! – Jon Wheelock Oct 17 '15 at 12:10
  • @JonWheelock `*(&a)` is just `a` . And your expression evaulates to `a+1`. Just similar to mine . `&a` will create a pointer to array , thats why it does not work as expected . – ameyCU Oct 17 '15 at 12:13
  • Splitting works and I had tried. I was just trying to print without assigning &a to another pointer. – Jon Wheelock Oct 17 '15 at 12:13
  • @JonWheelock Yes , both of them are similar (but not excatly same ). If you wan to clarify on `a` , `&a` , `&a[0]` , read here -http://stackoverflow.com/questions/18361111/are-a-a-a-a0-a0-and-a00-identical-pointers – ameyCU Oct 17 '15 at 12:14
3
char *ptr = &"Hello";

Your compiler should have warned you about this. "Hello" is of type char[6] (the length of the string plus 1 for the terminating '\0' null character). So &"Hello" is of type char (*)[6], or pointer to array of 6 chars. There is no implicit conversion from that type to char*.

If you want a pointer to the string, drop the &:

const char *ptr = "Hello";

This takes advantage of the rule that an expression of array type (such as "Hello" is implicitly converted to a pointer to the array's first element. (This conversion isn't done if the array is the operand of a unary & or sizeof operator, or is a string literal used to initialize an array object.)

(I've added the const because it's safer; you can't legally modify the contents of a string literal, and the const reminds the compiler not to let you try. Thanks to Bathsheba for reminding me.) (Actually modifying the contents has undefined behavior. Long story.)

You'll note that ptr points to the first character of the string, not to the entire string. That's (probably) exactly what you want. In C, an array is usually manipulated via a pointer to its elements, not via a pointer to the entire array. Pointer arithmetic is used to traverse the array and access all its elements.

It's important to keep in mind that constructing a pointer to an array's initial element does not remember the array's size. You have to keep track of that yourself. If the array contains a string, you'll generally look for the terminating '\0', or use a function that does so. For other arrays, it's common to store the length separately. For example a function might take two arguments, the address of an array's initial element and an integer (size_t) holding the number of elements.

Suggested reading: Section 6 of the comp.lang.c FAQ.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631