-3

https://i.stack.imgur.com/7Fgkp.jpg output)this the link for image of output

my code ---->

#include <stdio.h>
 
const int MAX = 5;
 
int main () {

   char *names[] = {
      "Zara Ali",
      "Hina Ali",
      "Nuha Ali",
      "Sara Ali",
      "Zara Ali"
   };
   
   int i = 0;

   for ( i = 0; i < MAX; i++) {
      printf("Value of *names[%d] = %c char\n", i, *names[i] );
   }
  
   for ( i = 0; i < MAX; i++) {
      printf("Value of *(names+%d) = %d\n", i, *(names+i) );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of names[%d] = %d\n", i, names[i] );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of *(names+%d) = %s\n", i, *(names+i) );
   }
   for ( i = 0; i < MAX; i++) {
      printf("Value of names[%d] = %s\n", i, names[i] );
   }
   
 
   
   printf("Value of names = %d\n",names );
   printf("Value of names+1 = %d\n",names+1 );
   return 0;
}

when value of names and names[0] is not same. where can i learn this topic properly. the problem is "i don't know that .. which variable is storing which adress or value".

alinsoar
  • 15,386
  • 4
  • 57
  • 74
Sahil
  • 13
  • 6
  • 2
    Please just include any code in the question, avoid images of code or links, really hard to reproduce. – alex01011 Sep 19 '21 at 00:54
  • 1
    Welcome to stackoverflow.com. Please take some time to read [the help pages](http://stackoverflow.com/help), especially the sections named ["What topics can I ask about here?"](http://stackoverflow.com/help/on-topic) and ["What types of questions should I avoid asking?"](http://stackoverflow.com/help/dont-ask). Also please take the [tour] and read about [ask] good questions. Lastly please read [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/), and learn how to ***[edit]*** your questions to improve them. – Some programmer dude Sep 19 '21 at 00:56
  • 1
    By the way, for any array (or pointer) `names` and index `i`, the expression `*(names + i)` is *exactly* equal to `names[i]`. Also, when using an array without index, like e.g. `names` then it will *decay* to a pointer to its first element. So `names` is the same as `&names[0]`. – Some programmer dude Sep 19 '21 at 00:58
  • @Someprogrammerdude (names and names+1) the difference between their addresses is 8... why not 9. Value of names[0] = 4196188 Value of names[1] = 4196197 is it address? or something else. and here the difference is 9 – Sahil Sep 19 '21 at 01:22
  • @Sahil You have an array of pointers. The size (in *bytes*) of each element is the size of `char *`, i.e. `sizeof(char *)`. That the size of a pointer is `8` tells me that you're on a 64 bit system, where each pointer is 64 bits, or 8 bytes. – Some programmer dude Sep 19 '21 at 08:54
  • As for the pointers themselves, all literal strings (like `"Zara Ali"`) are stored as (read-only) *array* of characters, *including the null-terminator*. So if you have a string of 8 characters (like `"Zara Ali"` that's 8 characters plus the null terminator, making it 9 in total. – Some programmer dude Sep 19 '21 at 09:06

2 Answers2

1

First of all, the following line is wrong:

printf("Value of names = %d\n",names );

Using the %d format specifier is not the correct way to print a pointer. Although it may work on most 32-bit platforms (on which pointers normally have a size of 4), it will most certainly not work properly on 64-bit platforms (on which pointers normally have a size of 8).

The correct way to print a pointer is using the %p format specifier and by casting the pointer to void*:

printf( "Value of names = %p\n", (void*)names );

On most platforms, the cast to void* is not necessary, so you can probably safely omit it (even if ISO C formally requires the cast).

As already pointed out in the comments section, writing names[i] is, by definition, equivalent to writing *(names+i).

The reason why the difference between names and names+1 is 8 is because in both expressions, the array names decays to a pointer to its first element, i.e. to &names[0]. Incrementing a pointer by 1 does not increase the address by 1, but rather makes it point to the next element. Since each element of the array names is a pointer and seems to have a size of 8 on your platform (you seem to be on a 64-bit platform with 64-bit pointers), the address is incremented by 8 when you increment the pointer by 1.

In your picture, you seem to also be asking why the difference between *(names+0) and *(names+1) is 9. The expression *(names+0) is equivalent to names[0], which is a pointer to the string literal "Zara Ali". The expression *(names+1) is equivalent to names[1], which is a pointer to the string literal "Hina Ali". So both of these expressions represent addresses of string literals, i.e. addresses of where the compiler is storing a certain string literal. Where compilers store string literals is up to the compiler to decide and compilers may behave differently. However, in this case, it seems that the compiler decided to store both string literals next to each other in memory. The string literal "Zara Ali" has a length of 9 (including the null terminating character), so that explains why the difference in the addresses is 9.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
0

Pictures will help:

      char *                char
+–––+                +–––+
|   | names[0] ––––> |'Z'| names[0][0]
+–––+                +–––+
|   | names[1] ––+   |'a'| names[0][1]
+–––+            |   +–––+
 ...             |    ...
                 |   +–––+
                 |   |'i'| names[0][7]
                 |   +–––+
                 |   | 0 | names[0][8]
                 |   +–––+
                 |
                 |   +–––+
                 +-> |'H'| names[1][0]
                     +–––+
                     |'i'| names[1][1]
                     +–––+
                      ...
                     +–––+
                     |'i'| names[1][7]
                     +–––+
                     | 0 | names[1][8]
                     +———+

Each string literal ("Zara Ali", "Hina Ali", etc.) is stored as a zero-terminated array of char somewhere in memory (string literals are stored in such a way that they are available over the lifetime of the program).

Each names[i] stores the address of the first character of each string literal.

The expression names has type "pointer to pointer to char" (char **)1 and evaluates to the address of the first element of the names array - it’s equivalent to writing &names[0]. The expression names[0] evaluates to the address of the first character in the "Zara Ali" string literal - it’s the same as writing &names[0][0].

Use the %p conversion specifier to print pointer values instead of %d - %d expects its corresponding argument to have type int, and pointers are not integers:

printf( "Value of names[%d] = %p\n", i, (void *) names[i] );

printf( "Value of names = %p\n", (void *) names );
printf( "Value of names+1 = %p\n", (void *) (names + 1) );

This is pretty much the only time you need to explicitly cast a pointer to void * in C.


  1. Unless it is the operand of the sizeof or unary & operators, or unless it is a string literal used to initialize an array of character type in a declaration, an expression of type "N-element array of T" will be converted, or "decay”, to an expression of type "pointer to T" and the value of the expression will be the address of the first element of the array.

    The variable names is declared as an array of pointer to char (char *[]). However, when names appears in an expression and it is not the operand of sizeof or unary &, it is converted to type "pointer to pointer to char (char **).

    This is why names is an array of char * - each of the string literals is itself an array expression ("9-element array of char"), but in this context "decays" to type char *.
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • i am doing coding from 3 to 4 months ...... I feel grateful to get such a satisfying and concept clearing answer from you. – Sahil Sep 19 '21 at 22:47