我将argv []定义为char *。使用以下printf语句:
printf("%s\n",argv[1]); // prints out the entire string
printf("%p\n",&argv[1]); // & -> gets the address
printf("%c\n",argv[1][0]);// prints out the first char of second var
printf("%c\n",*argv[1]); //
这是我不明白的最后一个。打印*argv[1]
是什么意思?为什么与*argv[1][0]
不一样,你怎么能打印printf("%s\n",*argv[1]);
。另外,为什么&*argv[1]
的地址与&argv[1]
不同?
答案 0 :(得分:4)
char *argv[]
argv
是char指针的数组(1)。所以它是普通数组,只是数组的每个元素都是一个指针。 argv[0]
是一个指针,argv[1]
等等。
argv[0]
- 数组中的第一个元素。由于数组中的每个元素都是char指针,因此this的值也是一个char指针(如上所述)。
*argv[1]
- 现在这里argv[1]
是上面数组中的第二个元素,但argv[1]
也是一个char指针。应用*
只是取消引用指针,然后获得argv[1]
指向的字符串中的第一个字符。
您应该使用%c
进行打印,因为这只是一个角色。
argv[1][0]
已经是数组中第二个字符串的第一个字符 - 因此没有更多空间可以解除引用。这与之前的基本相同。
(1)严格地说它是指向指针的指针,但也许你可以"思考"它作为指针数组。无论如何,有关它的更多信息:https://stackoverflow.com/a/39096006/3963067
答案 1 :(得分:3)
如果argv[1]
是指向char
的指针,那么*argv[1]
会取消引用该指针,并在argv[1]
处获取字符串的第一个字符,因此它就是{\ n}}与argv[1][0]
相同,并使用"%c"
格式说明符打印。
argv[1][0]
本身就是一个char
,而不是一个指针,所以它不是可以解释的。
答案 2 :(得分:3)
数组下标操作a[i]
定义为*(a + i)
- 给定地址a
,偏移i
元素(不是字节)解决和取消引用结果。因此,给定指针p
,*p
相当于*(p + 0)
,相当于p[0]
。
argv
的类型为char **
;鉴于此,以下所有情况均属实:
Expression Type Value
---------- ---- -----
argv char ** Pointer to a sequence of strings
*argv char * Equivalent to argv[0]
**argv char Equivalent to argv[0][0]
argv[i] char * Pointer to a single string
*argv[i] char Same as argv[i][0]
argv[i][j] char j'th character of i'th string
&argv[i] char ** Address of the pointer to the i'th string
由于argv[i][j]
的类型为char
,*argv[i][j]
不是有效的表达式。
这是argv
序列的错误可视化:
+---+ +---+ +---+
argv | | ---> argv[0] | | ---------------------------> argv[0][0] | |
+---+ +---+ +---+ +---+
argv[1] | | -------> argv[1][0] | | argv[0][1] | |
+---+ +---+ +---+
... argv[1][1] | | ...
+---+ +---+ +---+
argv[argc] | | ---||| ... argv[0][n-1] | |
+---+ +---+ +---+
argv[1][m-1] | |
+---+
这可能有助于解释不同表达方式的结果。
答案 3 :(得分:2)
最后一行printf("%c\n",*argv[1]);
既解除引用argv
又访问数组索引1
。换句话说,这就像前一行一样argv[1][0]
,因为数组下标访问[1]
比去引用运算符(*
)有higher precedence。
但是,如果您要在最后一行中括起表达式以使dereference运算符首先被处理,那么您将执行此操作:
printf("%c\n", (*argv)[1]);
现在,当您运行程序时,最后一行输出将是argv[0][1]
而不是[1][0]
,即您用于执行程序的命令行中的第二个字符。
答案 4 :(得分:2)
char *
。+ 0
没用。// printf("%p\n", &argv[1]); is wrong you must cast to (void *)
printf("%p\n", (void *)&argv[1]);
因为%p
说明符期望void *
,所以在正常情况下C自动将指针提升为void *
但printf()
使用变量参数列表。关于这个有很多规则,如果你愿意,我让你阅读doc。但是char *
不会被提升为void *
,而且我会说printf()
除了void *
,所以如果你不自己投射,你会有一个未定义的行为。