Reputation: 125
I have written small piece of code to understand how to traverse through array of char pointers & 2D array of characters. I've used 1] and 2] while printing the o/p to just keep track of which block of code prints what, kindly ignore them.
The similar code for printing o/p is used for traversing through 3 different (types of) arrays:-
a) Array of Character Pointers: char *argv[]
b) Array of Character Pointers: char *str[]
c) 2D Array of Characters: char strarr[][7]
The basic operation I performed are as follows: If char *foo[] then
A) foo points 1st element (string) of foo (doubtful about this one)
B) *++foo points to 1st char of next element of foo
C) **++foo gives 1st char of next element of foo
D) ++*foo points to next char within element of foo
E) *++*foo gives next char within element of foo
The operations A, B, C & D are allowed only in case of char *argv[]. char *str[] allows only operations C & D; while 2D array char strarr[][7] doesn't allow all A-D.
I understand why operation C & D are allowed for char *str[] and not for char strarr[][7]: Since char *str[] is an array pointers and the increment of value its elements (i.e. value of address to string) is allowed while in case of char strarr[]2[7] is 2D array of element it is not possible to increment the address of its elements.
Correct me for any wrong assumptions.
But I am not able to understand why operation of **++str, *++str or ++str is not allowed whereas **++argv *++argv or ++argv is allowed?
Both argv and str are array of char pointers then why this different behavior? (str points to str[0] then why ++str causes error instead of pointing to str[1]?) Is char *argv[] is some special kind of array or operations on it performed in some other way/method?
When I write **++str, *++str or ++str the compiler gives the following error:
gcc -Wall -c "TestProg.c" (in directory: /home/crownedeagle/Downloads/CDAC C-CAT/C - K&R Solutions) TestProg.c: In function ‘main’: TestProg.c:61:33: error: lvalue required as increment operand printf("\n1]\n**++str = %c", **++str); ^
//Pointer of Array and Array Pointer Experimentation
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
int main(int argc, char *argv[])
{
int i;
if (argc == 7)
{
printf("\n");
for (i = 0; i < argc; i++)
printf("%s\t\t%p\n", argv[i], argv[i]);
printf("\n0]\n**argv = %c", **argv);
printf("\n*argv = %s", *argv);
printf("\n1]\nargv = %p", argv);
printf("\n*argv = %s", *argv);
printf("\n**++argv = %c", **++argv);
printf("\nargv = %p", argv);
printf("\n*argv = %s", *argv);
printf("\n**++argv = %c", **++argv);
printf("\nargv = %p", argv);
printf("\n*argv = %s", *argv);
printf("\n2]\nargv = %p", argv);
printf("\n&(argv[0]) = %p", &(argv[0]));
printf("\n*argv = %p", *argv);
printf("\n&(**argv) = %p", &(**argv));
printf("\n*++*argv = %c", *++*argv);
printf("\n*argv = %s", *argv);
printf("\nargv = %p", argv);
printf("\n&(argv[0]) = %p", &(argv[0]));
printf("\n*argv = %p", *argv);
printf("\n&(**argv) = %p", &(**argv));
printf("\nargv[0] = %s", argv[0]);
printf("\n\n");
for (i = 0; i < argc; i++)
printf("%s\t\t%p\n", argv[i], argv[i]);
}
char *str[] = {"ABCDEF", "HIJKLM", "OPQRST", "VWXYZA", "123456"};
printf("\n");
for (i = 0; i < 5; i++)
printf("%s\t\t%p\n", str[i], str[i]);
printf("\n0]\n**str = %c", **str);
printf("\n*str = %s", *str);
//printf("\n1]\n**++str = %c", **++str);
//printf("\n*str = %s", *str);
printf("\n1]\nstr = %p", str);
printf("\n&(str[0]) = %p", &(str[0]));
printf("\n*str = %p", *str);
printf("\n&(**str) = %p", &(**str));
printf("\n*++*str = %c", *++*str);
printf("\n*str = %s", *str);
printf("\nstr = %p", str);
printf("\n&(str[0]) = %p", &(str[0]));
printf("\n*str = %p", *str);
printf("\n&(**str) = %p", &(**str));
printf("\nstr[0] = %s", str[0]);
printf("\n\n");
for (i = 0; i < 5; i++)
printf("%s\t\t%p\n", str[i], str[i]);
char strarr[][7] = {"ABCDEF", "HIJKLM", "OPQRST", "VWXYZA", "123456"};
printf("\n");
for (i = 0; i < 5; i++)
printf("%s\t\t%p\n", strarr[i], strarr[i]);
printf("\n0]\n**strarr = %c", **strarr);
printf("\n*strarr = %s", *strarr);
//printf("\n1]\n**++strarr = %c", **++strarr);
//printf("\n*strarr = %s", *strarr);
printf("\n1]\nstrarr = %p", strarr);
printf("\n&(strarr[0]) = %p", &(strarr[0]));
printf("\n*strarr = %p", *strarr);
printf("\n&(**strarr) = %p", &(**strarr));
//printf("\n*++*strarr = %c", *++*strarr);
printf("\n*strarr = %s", *strarr);
printf("\nstrarr = %p", strarr);
printf("\n&(strarr[0]) = %p", &(strarr[0]));
printf("\n*strarr = %p", *strarr);
printf("\n&(**strarr) = %p", &(**strarr));
printf("\nstrarr[0] = %s", strarr[0]);
printf("\n\n");
for (i = 0; i < 5; i++)
printf("%s\t\t%p\n", strarr[i], strarr[i]);
return 0;
}
crownedeagle@EagleNest:~/C - K&R Solutions$ ./TestProg abcdef hijklm opqrst vwxyza 123456 789012 ./TestProg 0x7ffd61c027c7 abcdef 0x7ffd61c027d2 hijklm 0x7ffd61c027d9 opqrst 0x7ffd61c027e0 vwxyza 0x7ffd61c027e7 123456 0x7ffd61c027ee 789012 0x7ffd61c027f5 0] **argv = . *argv = ./TestProg 1] argv = 0x7ffd61c01c98 *argv = ./TestProg **++argv = a argv = 0x7ffd61c01ca0 *argv = abcdef **++argv = h argv = 0x7ffd61c01ca8 *argv = hijklm 2] argv = 0x7ffd61c01ca8 &(argv[0]) = 0x7ffd61c01ca8 *argv = 0x7ffd61c027d9 &(**argv) = 0x7ffd61c027d9 *++*argv = i *argv = ijklm argv = 0x7ffd61c01ca8 &(argv[0]) = 0x7ffd61c01ca8 *argv = 0x7ffd61c027da &(**argv) = 0x7ffd61c027da argv[0] = ijklm ijklm 0x7ffd61c027da opqrst 0x7ffd61c027e0 vwxyza 0x7ffd61c027e7 123456 0x7ffd61c027ee 789012 0x7ffd61c027f5 (null) (nil) XDG_VTNR=7 0x7ffd61c027fc ABCDEF 0x400dfa HIJKLM 0x400e01 OPQRST 0x400e08 VWXYZA 0x400e0f 123456 0x400e16 0] **str = A *str = ABCDEF 1] str = 0x7ffd61c01b80 &(str[0]) = 0x7ffd61c01b80 *str = 0x400dfa &(**str) = 0x400dfa *++*str = B *str = BCDEF str = 0x7ffd61c01b80 &(str[0]) = 0x7ffd61c01b80 *str = 0x400dfb &(**str) = 0x400dfb str[0] = BCDEF BCDEF 0x400dfb HIJKLM 0x400e01 OPQRST 0x400e08 VWXYZA 0x400e0f 123456 0x400e16 ABCDEF 0x7ffd61c01b50 HIJKLM 0x7ffd61c01b57 OPQRST 0x7ffd61c01b5e VWXYZA 0x7ffd61c01b65 123456 0x7ffd61c01b6c 0] **strarr = A *strarr = ABCDEF 1] strarr = 0x7ffd61c01b50 &(strarr[0]) = 0x7ffd61c01b50 *strarr = 0x7ffd61c01b50 &(**strarr) = 0x7ffd61c01b50 *strarr = ABCDEF strarr = 0x7ffd61c01b50 &(strarr[0]) = 0x7ffd61c01b50 *strarr = 0x7ffd61c01b50 &(**strarr) = 0x7ffd61c01b50 strarr[0] = ABCDEF ABCDEF 0x7ffd61c01b50 HIJKLM 0x7ffd61c01b57 OPQRST 0x7ffd61c01b5e VWXYZA 0x7ffd61c01b65 123456 0x7ffd61c01b6c
Upvotes: 0
Views: 161
Reputation: 16540
the order of execution of urinary operators is from right to left so:
* & + - ! ~ ++expr --expr
means the ++ is executed first then **.
regarding:
printf("\n1]\n**++str = %c", **++str);
so, ++str
results in the str[1]
pointer
de-reference it once via '*' results in the string pointed to by str[1]
The second de-reference via '*' results in garbage as the string where: str[1]
points is not a pointer
Upvotes: 0
Reputation: 310980
In this function declaration
int main(int argc, char *argv[])
the compiler adjusts the parameter having the array of unknown size type to pointer to the element type. That is this declaration is equivalent to
int main(int argc, char **argv )
So within the function you are dealing with a pointer and you may apply increment or assignment operators.
For example these function declarations
void f( int a[100] );
void f( int a[10] );
void f( int a[] );
declare the same one function and all the declarations are adjusted by the compiler to the declaration
void f( int *a );
From the C Standard (6.7.6.3 Function declarators (including prototypes))
7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.
In this declaration
char *str[] = {"ABCDEF", "HIJKLM", "OPQRST", "VWXYZA", "123456"};
there is declared an array of the type char * [5]
. Arrays are non-modifiable lvalues. So you may not apply to arrays increment or assignment operators.
Upvotes: 3