c - 使用 sizeof 查找 argv 中字符串的大小

标签 c pointers sizeof argv

在这一点上,这更像是一个概念性问题,而不是一个实际问题,但它确实困扰着我。

假设我有一个名为“test.c”的 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.”。这是有道理的,因为我选择了一个字符数组。在 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] 并获取字符串大小(加上 \0 的 1)的问题,这是因为它是一个参差不齐的数组。在这种情况下,第一个维度的大小未知,第二个维度也是如此。在这种情况下,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 个字节。

关于c - 使用 sizeof 查找 argv 中字符串的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26111267/

相关文章:

c - Typedefed 数组类型不可分配

c - 从指针数组中读取字符串

c - 数据类型不匹配和编译器冲突

有关 sizeof 运算符的 c 编程查询 请在 windows 和 linux 中指定输出及其原因

c函数返回数组并将数组与另一个数组进行比较

c++ - 为什么取消引用称为取消引用的指针?

c - 表达式必须有一个指向 C 中对象类型的指针 2

c++ - 初始化后将指针设为const

c - 与负数比较时,为什么 sizeof 运算符会发生这种情况?

c - 在 c : when do I have to use malloc 中实现字符串队列