在这一点上,这更多是一个概念性问题,而不是实用性问题,但这确实让我感到困扰。
让我们说我有一个名为“ test.c”的交流程序,我想找到用户输入作为参数的单词时在数组中的空格数。例如,“ ./ test.c test_run”应该打印9,因为它有8个字符,然后一个表示空终止字符。当我在argv上尝试使用sizeof时,遇到了一些麻烦。
int main(int argc, char *argv[]) {
char buf10[10];
printf("The size of buf10 is: %i.\n", sizeof(buf10));
return 0;
}
打印结果:“ buf10的大小为:10。 ”。这是有道理的,因为我选择了一个char数组。在C语言中,char的大小为1个字节。如果我选择int,则此数字为4。
现在我的问题是为什么我不能用argv做到这一点?
int main(int argc, char *argv[]) {
printf("argv[1] has the value: %s\n", argv[1]);
printf("strlen of argv[1] is: %i\n", strlen(argv[1]));
printf("sizeof of argv[1] is: %i\n", sizeof(argv[1]));
return 0;
}
以“ ./test Hello_SO”运行会给出输出:
argv[1] has the value: Hello_SO
strlen of argv[1] is: 8
sizeof of argv[1] is: 4
字符串长度很有意义,因为它应该为9,但减去“ \ 0”则为8。
但是我不明白为什么sizeof返回4(指针的大小)。我知道* argv []可以认为是** argv。但是我已经考虑了这一点。在我的第一个示例中,我打印“ buf”,但在这里我打印“ argv [1]”。我知道我可以通过使用strlen轻松获得答案,但是正如我之前所说,这只是概念性的。
指针和数组不是一回事,尽管它们在许多情况下非常相似。sizeof
是关键的区别。
int arr[10];
assert(sizeof arr == (sizeof(int) * 10));
int *ip;
assert(sizeof ip == sizeof(int*));
arr
上面的类型是int[10]
。查看数组类型和指针之间差异的另一种方法是尝试分配给它们。
int i;
ip = &i; // sure, fine
arr = &i; // fails, can't assign to an int[10]
数组不能分配给。
什么是最令人困惑的是,当你有一个数组作为函数参数,它实际上是相同的具有指针。
int f(int arr[10]) {
int x;
arr = &x; // fine, because arr is actually an int*
assert(sizeof arr == sizeof(int*));
}
为了解决您为什么不能使用sizeof argv[1]
并获取字符串大小(加上的1 \0
)的问题,这是因为它是一个参差不齐的数组。在这种情况下,第一个尺寸未知,第二个尺寸也未知。sizeof
在这种情况下,其行为类似于编译时操作,并且直到运行时才知道字符串的长度。
考虑以下程序:
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("%zu\n", sizeof argv[1]);
}
为此生成的程序集是:
.LC0:
.string "%zu\n"
.text
.globl main
.type main, @function
main:
.LFB3:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $8, %esi # this 8 is the result of sizeof
movl $.LC0, %edi # the format string
movl $0, %eax
call printf # calling printf
movl $0, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
如您所见,的结果sizeof argv[1]
是在编译时完成的,上面没有计算字符串的长度。我使用的是64位,所以我的指针是8个字节。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句