【问题标题】:How is argv a string array when it's a char array?当 argv 是 char 数组时,它如何是字符串数组?
【发布时间】:2018-08-10 11:59:08
【问题描述】:

为什么argv[0] 不打印文件名的第一个字符而不是整个文件名字符串?

如果argv 是一个指向字符数组的指针,那么不应该用[n] 访问它,结果是一个字符?如果它是一个字符串(如printf(argv[n] 建议的那样),那么为什么argv[0][0] 不给我文件名的第一个字符(编译但启动时崩溃)?

int main(int argc, char **argv){

    printf(argv[0][0]);

    while (1){}
    return 0;
}

【问题讨论】:

  • 因为argv是一个指向char数组的指针指针
  • char ** 可以通过两个索引运算符访问,例如二维数组 (argv[0][0]),但二维数组是数组数组,而不是指针数组。您可以在 SO 上找到几个已在此处解决此问题的问题。
  • @LukaKostic 编译器不在乎。这就是存在未定义行为的原因。您也为此与自己签订了​​合同。符号char *argv[] 只是为了向读者表明预期的参数确实是一个指针数组,但最终它还是被解释为char **argv,编译器真的不在乎。
  • @LukaKostic 这里有一个很好的教训:代码胜于雄辩。编码都是关于细节的,写出来的描述会遗漏。在这种情况下,您在概念上是正确的 argv[0][0] 是文件名的第一个字符。问题是您没有正确打印该字符。总是发布代码。
  • @LukaKostic argv[0][0] 本身不会崩溃。这就是您使用它的方式,这就是代码如此重要的原因。

标签: c


【解决方案1】:

您的代码表现出未定义的行为,因为您将 char 传递给需要指针的函数。

要打印单个字符,您有这些选项,

  • fputc(argv[0][0], stdout);
  • putchar(argv[0][0]); // Effectively the same as above
  • printf("%c\n", argv[0][0]);

您可以添加更多printf() 变体。

您的代码崩溃的原因是因为printf(argv[0][0]); 是未定义的行为,因为该函数将尝试取消引用指针但您传递了单个字符,并且该字符的值将被解释为内存地址。

您确实需要启用编译器警告。

【讨论】:

  • 地址怎么会混淆呢? &argv[0][0] 不是地址,argv[0][0] 不是字符吗?
  • @LukaKostic 最后,char 只是一个整数类型,整数和指针在c 中可以互换,但这种交易的行为并不总是被定义。此外,如果地址是在程序内存范围内的地址,它仍然是无效的,因为它没有指向真正的内存位置,或者是吗?这不会事先知道,这就是为什么这被称为未定义行为。
  • 很明显,指针和整数在 C 中是不可interchangeable 的,但它们是可相互convertible 的。并且一些编译器甚至在没有强制转换的情况下执行这样的转换,这是一个扩展(尽管他们通常愿意发出警告)。
【解决方案2】:

我正在使用 ubuntu server 14 执行,gcc 编译器编译代码,argv[n][n] 为我工作。看看这段代码

// C program to illustrate
// command line arguments
#include<stdio.h>

int main(int argc, char* argv[])
{
    int counter;
    printf("Program Name Is: %s",argv[0]);
    if (argc == 1)
        printf("\nNo Extra Command Line Argument Passed Other Than Program Name");
    if (argc >= 2)
    {
        printf("\nChecking double array elements: %c",argv[0][0]);
    }
    return 0;
}

输出:

Program Name Is: ./test
Checking double array elements: .

你用什么机器来编译和执行?也许还有其他错误...仔细检查!

【讨论】:

  • 我需要一个 printf("%c",argv[0][0]) 而不仅仅是 printf(argv[0][0])
  • 没错,如果您需要从字符串(char 的数组)中读取 char,您可以通过 %c 来完成
猜你喜欢
  • 1970-01-01
  • 2018-10-29
  • 2021-09-17
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
  • 2021-04-07
相关资源
最近更新 更多