我刚刚开始学习C。
void function(char *str1, char *str2) {
printf("%p\n", str1);
printf("%p\n", str2);
str1++; //*str++;
str2++; //*str++;
printf("%p\n", str1);
printf("%p\n", str2);
}
int main(int argc, char *argv[]) {
function(argv[1], argv[2]);
return 0;
}
如果argv[1]
是“基本”argv[2]
是“程序”;
当我用注释部分替换代码时,它会给出相同的结果,即"a" "r"
;
但是如果我用标志-Werror
编译它,它会给出“警告:计算的值不被使用”
str1++
和*str1++;
有什么区别?
如果我想增加指向的字符
,代码是什么对于行function(argv[1], argv[2]);
,argv[1]
和agrv[2]
我传递给函数,它们是指针还是数组?
什么是*argv[1]
和*argv[2]
答案 0 :(得分:4)
str1 ++和* str1 ++之间有什么区别
它们具有完全相同的副作用(递增指针)。
然而,他们有不同的价值观。第一个在递增之前计算指针的值,第二个求值为它指向的数据。您无论如何都不使用该值,这是您的编译器注意到的。function(argv [1],argv [2]);在这里argv [1]和agrv [2]我传递给函数,它们是指针还是数组?
它们是char的指针,即。字符串。特别是第一和第二命令行参数。
答案 1 :(得分:2)
C中的每个(子)表达式(除少数例外)都有一个值,可能还有副作用。
表达式只能用于值,如下面的42
。
int a = 42;
它们也可以仅用于副作用,如下所示
printf("Hello, world!\n");
当然,它们可用于价值和副作用(下面的getchar
):
while ((ch = getchar()) != EOF) /* void */;
您的编译器只是抱怨您计算了一个值并且没有使用它。编译器知道不会抱怨像printf()
这样的常规构造,但不会在*str++
表达式*str++
具有值*str
和递增str
的副作用。由于您不使用该值,因此它与str++
(具有值str
和编译器不会抱怨的相同副作用和常规构造相同。)
答案 2 :(得分:2)
通过修改一些功能可以最好地说明差异。请记住,++ x仅在返回值中与x ++不同:
void function(char *str1, char *str2)
{
printf("%s\n", str1);
printf("%s\n", str2);
printf("%s\n", ++str1);
printf("%s\n", ++str2);
}
调用函数function("hello", "world")
将打印
hello
world
ello
orld
现在,让我们修改函数以使用*++str
而不是++str
void function(char *str1, char *str2)
{
printf("%s\n", str1);
printf("%s\n", str2);
printf("%c\n", *++str1);
printf("%c\n", *++str2);
}
现在是同一个电话的输出:
hello
world
e
o
*简单地取消引用后面的内容,在这种情况下是字符串的开头。
答案 3 :(得分:0)
指针是固定大小,数组不是。 sizeof(char *)== sizeof(int)== sizeof(float **)等等。我的想法是你将一个固定大小的指针传递给这个字符数组而不是复制整个字符。您可以通过使用*解除引用来获取字符数组的值,但这在大多数情况下对字符串都没用。动态字符串通常保留为指针,因此它们可以考虑任意大小。我不知道你为什么要增加指针的任何理由,但增加字符串中的任何字母都是有意义的。
另外,我倾向于使用预增量。我看到的每一个基准都会更快。