in Programming edited by
380 views
2 votes
2 votes

What is the output of the following program?

#include <stdio.h>
void f(char**);
int main()
{
char *argv[] = { "ab", "cd", "ef", "gh", "ij", "kl" };
f(argv);
return 0;
}
void f(char **p)
{
char *t;
t = (p += sizeof(int))[-1];
printf("%s\n", t);
}
  1. ab
  2. cd
  3. ef
  4. gh
in Programming edited by
by
380 views

3 Comments

char *argv[] = { "ab", "cd", "ef", "gh", "ij", "kl" };

above statment is declaring an array of character pointer not array character. Please correct me if wrong .

I guess this a typo. If not then each element of argv is basically a pointer to string . I dont know but this assumption look weird ,,, Can anybody explain what this statement means. Where i m wrong in my interpretation?

0
0
@Satyajeet Singh , same doubt here!! Someone please help.
0
0

@shraddha 

in c, there is no data type for string . So we define string as below:

char string1[4]="abcd";           //this is string  but internally it is just a arry of characters. 

char * string1="abcd";             //this is a string constant . it has address associated with it

so 

char *argv[] = { "ab", "cd", "ef", "gh", "ij", "kl" };

this declaration is basically defining an  array of string constants . Each array item is a string constant ( or a constant pointer). 

Hope this helped! 

2
2

2 Answers

4 votes
4 votes
Best answer

sizeof(int) is compiler dependent ..  so from this line 

t = (p += sizeof(int))[-1];  
what we get is

if sizeof(int) = 2
 [ in 16 bit systems it is 2 bytes, which is now obsolate we don't use 16 bit computer now a days] 

then  
t = (p += sizeof(int))[-1] 
t = (p = p + 2)[-1] 
t = *(p + 2 -1) = *(p+1) = address of second element i.e. 'cd' 

--------

if sizeof(int) = 4 [ in 32 bit systems size of int = 4 B,  we use 32 Bit systems now a days ]
then  

t = (p += sizeof(int))[-1] 
t = (p = p + 4)[-1] 
t = *(p + 4 -1) = *(p+3) = address of forth element i.e. 'gh'. 

..................

#include <stdio.h>  
void f(char**);   
int main()  
{  
char *argv[ ] = { "ab", "cd", "ef", "gh", "ij", "kl" };     // it creates character array.

 //    In char array address point to only starting of character array. 


f(argv);      // function call with base address of char array.   
return 0;  


void f(char **p)       // function call comes here. here p is pointer to pointer array

{  
char *t;  //create pointer variable  
t = (p += sizeof(int))[-1];         //  t = (p = p+4 ))[-1];    

                                              // p point to "gh" starting of this char array.

                                            //     now P[-1] ; t= *(p-1); now t point to  "gh" array . 

                                       

  
printf("%s\n", t);                // %s this tell to print string until % not encounter .

since every string stored end with %.  
}

so it prints 'gh' 

selected by

1 comment

I get the explanation Sir, but my doubt is that assuming 1 char takes 1 B and memory is Byte addressible,
for the array argv[] each string has two + one \0 characters so each string element takes 3 addresses. So if I make the address of argv[0] as 100 then address of argv[1] will be 103, argv[2] will be 106 and so on.

Now incrementing p by size of int once means it should skip 4 addresses right? That means it should point to 104 which is the address of the letter 'd'. Where am I going wrong?
0
0
3 votes
3 votes

actually sizeof(int) is compiler dependent ..  so from this line 

t = (p += sizeof(int))[-1];  
what we get is
if sizeof(int) = 2 
[ in 16 bit systems it is 2 bytes, which is now obsolete we don't use 16 bit computer now a days] 

then  
t = (p += sizeof(int))[-1] 
t = (p = p + 2)[-1] 
t = *(p + 2 -1) = *(p+1) = address of second element i.e. 'cd' 

--------------
if sizeof(int) = 4 [ in 32 bit systems which is used now a days ]

then  

t = (p += sizeof(int))[-1] 
t = (p = p + 4)[-1] 
t = *(p + 4 -1) = *(p+3) = address of forth element i.e. 'gh'. 

..................

#include <stdio.h> 
void f(char**);  
int main() 

char *argv[ ] = { "ab", "cd", "ef", "gh", "ij", "kl" };        // it creates character array.

     //   In char array address point to only starting of character array. 


f(argv);               // function call with base address of char array.  
return 0; 


void f(char **p)             // function call comes here. here p is pointer to pointer array


char *t;                             //create pointer variable 
t = (p += sizeof(int))[-1];            //t = (p = p+4 ))[-1];

                                          // p point to "gh" starting of this char array.

                                       //       now P[-1] ; t= *(p-1); now t point to  "gh" array . 

 
printf("%s\n", t);               // %s this tell to print string until % not encounter .

since every string stored end with %. 
}

so it prints 'gh' 

The size of an int is really compiler dependent. Back in the day, when processors were 16 bit, an int was 2 bytes. Nowadays, it's most often 4 bytes on a 32 bits system or 8 bytes on 64 bits system

http://stackoverflow.com/questions/11438794/is-the-size-of-c-int-2-bytes-or-4-bytes

edited by

4 Comments

Totally satisfied with your answer

Only 1 question Bikram sir

on the D-Day what size of int we should take?

coz I have been taking it as size = 2 unless explicitly specified.

1
1
 what size of int we should take?

 size of int we should take in 32 bit systems as 4 Bytes .

yes, 2 Bytes was used previously in 16 Bit systems but now we mostly use 32 Bit systems so size of int is 4 Bytes .

2
2

char *argv[ ] = { "ab", "cd", "ef", "gh", "ij", "kl" };        // it creates character array.

If it creates char array then what does the following declaration mean?

char argv[] = { "ab", "cd", "ef", "gh", "ij", "kl" };

@Habibkhan 

0
0
argv is an array of pointer to character

and each of the pointer is  pointing to the first element of corresponding char string
0
0
Answer:

Related questions