【问题标题】:Why do we not need to dereference command line arguments (easy)为什么我们不需要取消引用命令行参数(简单)
【发布时间】:2017-03-21 10:25:42
【问题描述】:

当我们从命令行获取参数时,像这样:

int main(int argc, char *argv[]) { }

据我了解,argv 是指向指针数组的指针,其中保存了传入参数的地址。

既然是这样,为什么我们可以通过使用来访问命令行参数

argv[i]

没有取消引用它,因为它包含指针?

【问题讨论】:

  • argv 是指向指针的指针,而不是指向指针数组的指针。碰巧它指向的是数组中的第一个。
  • the clockwise/spiral rule 之后声明char *argv[] 会告诉您argv 是指向char 的指针数组。 IE。一个字符串数组。从技术上讲,这并不正确,因为您不能将数组作为参数传递,但出于所有实际原因,这就是您应该看到的argv:作为字符串数组。
  • 此外,您应该在访问argv 元素之前检查argc。这可以避免越界访问该数组
  • argv 是(指向第一个元素的)指针数组,而不是指向数组的指针。
  • "为什么我们可以使用 argv[i] 访问命令行参数" 取决于您如何使用它。如果您想将其用作字符串,则不必取消引用它。如果要使用单个字符,则必须取消引用它。

标签: c pointers


【解决方案1】:

您忘记了字符串 (char *) 是通过它的起始地址而不是绝对值访问的……您将为字符串存储什么值?通用 'string' 类型应该使用多少内存,因此 'string' 可以使用多长时间?

C 中的字符串由许多可打印字符组成,以 nul (\0) 结尾。这些都存储在内存中。

char *argv[] 参数指定有一个 char * 元素数组。正如我们在上面建立的,char * 是一个字符串(或 char 元素的数组)。

char *argv[] 参数可以合法地声明为char **argv

例如,您可以打印字符串中每个字符的绝对值,以及它们在内存中的地址:

#include <stdio.h>

int main(void) {
    char *my_string = "Hello World";
    int i;

    for (i = 0; my_string[i] != '\0'; i++) {
        printf("%c - 0x%02hhX - %p\n", my_string[i], my_string[i], &(my_string[i]));
    }

    return 0;
}

在这里,我们使用my_string[i] 取消引用指针以获取单个字符。

输出:

H - 0x48 - 0x400614
e - 0x65 - 0x400615
l - 0x6C - 0x400616
l - 0x6C - 0x400617
o - 0x6F - 0x400618
  - 0x20 - 0x400619
W - 0x57 - 0x40061a
o - 0x6F - 0x40061b
r - 0x72 - 0x40061c
l - 0x6C - 0x40061d
d - 0x64 - 0x40061e

你也可以像这样实现这个程序(注意取消引用):

#include <stdio.h>

int main(void) {
    char *my_string = "Hello World";
    char *s;

    /* s = my_string
     * is equivelant to:
     * s = &(my_string[0]) */

    for (s = my_string; *s != '\0'; s++) {
        printf("%c - 0x%02hhX - %p\n", *s, *s, s);
    }

    return 0;
}

【讨论】:

  • 您应该使用int main(void),而不是void main(void),因为根据C11标准,前者是main的标准签名。
【解决方案2】:

在main函数中:int argcchar *argv[]数组所指向的字符串个数

int main(int argc, char *argv[]) { }

int argc:

int argc定义主函数传入多少字符串。

char *argv[] :

char *argv[] 将每个单词/参数存储在此数组中。

示例:

#include <stdio.h>
int main(int argc, char const *argv[]){
  for(int i=0; i<argc; i++){
    printf("%s\n", argv[i]);
  }
  return 0;
}

编译:

gcc -o c 例子.c

运行:

./c 一二那里四五

输出:

./c
one
two
there
four
five

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 2017-06-22
    • 1970-01-01
    • 2013-06-22
    • 2020-11-08
    • 2015-03-24
    • 2013-04-01
    相关资源
    最近更新 更多