Pointers And Strings |
|
char names[][20] = {
"Ajay",
"Atul",
"Ramesh",
"Sivaramakrishnan",
"Sameer"
} ;
char
*n[] = {
"Ajay",
"Atul",
"Ramesh",
"Sivaramakrishnan",
"Sameer"
} ;
2-D array suffers from
two limitations: What will be the output of the following program main( )
{
static
char *s[ ] = {
"ice",
"green",
"cone",
"please"
} ;
staic
char **ptr[ ] = { s + 3 , s + 2 , s + 1 , s } ;
char
***p = ptr ;
printf (
"\n%s" , **++p ) ;
printf (
"\n%s" , *--*++p + 3 ) ;
printf (
"\n%s" , *p[-2] + 3 ) ;
printf (
"\n%s" , p[-1][-1] + 1 ) ;
}
Output: Explanation: Finally, the base address of ptr[ ] is assigned to a pointer to a pointer to a pointer, p. Reeling?! Going through the figure would decidedly aid you to get disentangled. Thus, p is assigned the address 6020.
Having sorted out what is present where, we now proceed to the printf( ) s. Let us tackle the expressions one by one. **++p The first one prints out the string starting from the address **++p . The ++ goes to work first and increments p not to 6021, but to 6022. The C compiler has been made to understand that on incrementing a pointer variable, it is to point to the next location of its type. The words `of its type' hold significance here. A pointer to a char on incrementing goes one byte further, since a char is a 1-byte entity. A pointer to an int points 2 bytes further, as an int is a 2-byte entity. Also, a pointer by itself is always a 2-byte entity, so incrementing a pointer to a pointer would advance you by 2 bytes. Having convinced ourselves that p now stores 6022, we go on to evaluate the expression further. *p signifies contents of 6022, i.e. 4010. **p means value at this address, i.e. value at 4010, which is the address 1010. The printf( ) prints the string at this address, which is "cone". *--*++p + 3 p , presently contains 6022, which on incrementing becomes 6024. Value at this address is the address 4008, or in terms of s , s + 1 . On this the decrement operator -- works to give 4006, i.e. s . Value at 4006, or *( s ) is 1000. Thus the expression is now reduced to ( 1000 + 3 ), and what finally gets passed to printf( ) is the address 1003. Value at this address is a '\0', as at the end of every string a '\0' is inserted automatically. This '\0' is printed out as a blank by printf( ) . *p[-2] + 3 The current address in p is 6024. *p[-2] can be thought of as *( *( p - 2 ) ) , as num[i] is same as *( num + i ) . This in turn evaluates as *( *( 6024 - 2 ) ) , i.e. *( *( 6020 ) ) , as p is a pointer to a pointer. This is equal to *( 4012 ) , as at 6020 the address 4012 is present. Value at 4012 is 1015, i.e. the base address of the fourth string, "please". Having reached the address of letter `p', 3 is added, which yields the address 1018. The string starting from 1018 is printed out, which comprises of the last three letters of "please", i.e. `ase'. p[-1][-1] + 1 The above expression can be thought of as *( p[-1] - 1 ) + 1, as num[i] and *( num + i ) amounts to the same thing. Further, p[-1] can itself be simplified to *( p - 1 ) . Hence we can interpret the given expression as *( *( p - 1 ) - 1 ) + 1 . Now let us evaluate this expression. After the execution of the third printf( ) , p still holds the address 6024. *( 6024 - 1 ) gives *( 6022 ) , i.e. address 4010. Therefore the expression now becomes *( 4010 - 1 ) + 1 . Looking at the figure you would agree that 4010 can be expressed as s + 2 . So now the expression becomes *( s + 2 - 1 ) + 1 or *( s + 1 ) + 1 . Once again the figure would confirm that *( s + 1 ) evaluates to *( 4008 ) and *( 4008 ) yields 1004, which is the base address of the second string "green". To this, 1 is added to yield the address of the first element, `r'. With this as the starting address, printf( ) prints out what is remaining of the string "green". What will be the output of the following program main( ) { char str[ ] = "For your eyes only" ; int i ; char *p ; for ( p = str, i = 0 ; p + i <<= str + strlen ( str ) ; p++, i++ ) printf ( "%c", *( p + i ) ) ; } Output
Explanation
The for loop here hosts two initialisations and two incrementations, which is perfectly acceptable. However, there must always be a unique test condition. In the initialisation part, p is assigned the base address of the string, and i is set to 0. Next the condition is tested. Let us isolate this condition for closer examination. p + i <<= str + strlen ( str ) Since length of str[ ] is 18, str + strlen ( str ) would give the address of '\0' present at the end of the string. If we assume that the base address of the string is 4001, then the address of '\0' would be 4019. Since p has been assigned the base address of the string, in the first go, p + 0 would yield 4001. Since this is less than 4019, the condition holds good, and the character present at the address ( p + 0 ) , i.e. `F', is printed out. This can be understood better with the aid of the Figure 2. After this, both p and i are incremented, so that p contains 4002 and i contains 1, and once again the condition in the for loop is tested. This time ( p + i ) yields 4003, whereas the expression str + strlen ( str ) continues to yield 4019. Therefore again the condition is satisfied and the character at address 4003, i.e. `r' gets printed. Likewise, alternate elements of the string are outputted till i is 8, corresponding to which `l' is printed. Now, when p and i are incremented one more time, the test condition evaluates to: p + i <<= str + strlen (
str ) The 18th element of str is of course the '\0', which is also printed out as a blank. On further incrementation of p and i , control snaps out of the for and the program execution is terminated. |
|
Designed and
Managed by |
|