【问题标题】:Strange out of scope variable奇怪的超出范围的变量
【发布时间】:2012-04-02 12:16:02
【问题描述】:

我正在查找getopt 命令,我发现使用该函数似乎莫名其妙地产生了另一个名为optarg 的变量。你可以看看这个in the following program I swiped from Wikipedia:的例子

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <unistd.h>    /* for getopt */
int main (int argc, char **argv) {
    int c;
    int digit_optind = 0;
    int aopt = 0, bopt = 0;
    char *copt = 0, *dopt = 0;
    while ( (c = getopt(argc, argv, "abc:d:012")) != -1) {
        int this_option_optind = optind ? optind : 1;
        switch (c) {
        case '0':
        case '1':
        case '2':
            if (digit_optind != 0 && digit_optind != this_option_optind)
              printf ("digits occur in two different argv-elements.\n");
            digit_optind = this_option_optind;
            printf ("option %c\n", c);
            break;
        case 'a':
            printf ("option a\n");
            aopt = 1;
            break;
        case 'b':
            printf ("option b\n");
            bopt = 1;
            break;
        case 'c':
            printf ("option c with value '%s'\n", optarg);
            copt = optarg;
            break;
        case 'd':
            printf ("option d with value '%s'\n", optarg);
            dopt = optarg;
            break;
        case '?':
            break;
        default:
            printf ("?? getopt returned character code 0%o ??\n", c);
        }
    }
    if (optind < argc) {
        printf ("non-option ARGV-elements: ");
        while (optind < argc)
            printf ("%s ", argv[optind++]);
        printf ("\n");
    }
    exit (0);
}

注意optarg 现在似乎没有被声明或初始化。也许这只是我不知道的 C 中的一个常见特性,但我已经在谷歌上搜索了几个小时,但我不知道我要查找的内容的名称。任何解释都会很好。

【问题讨论】:

    标签: c variables scope arguments


    【解决方案1】:

    术语是“全局变量”。如果你在函数之外声明一个变量,它可以在函数内部访问:

    int i = 7;
    
    int main()
    {
        printf("%d\n", i); // prints 7
        return 0;
    }
    

    对于optargunistd.h 标头将其声明为具有外部链接的全局char * 变量:

    extern char *optarg;
    

    (见http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html)。

    【讨论】:

    • “外部存储”,例如,在 USB 记忆棒上?
    • @KerrekSB:嘿,好吧,我现在把它改成了“外部定义”。感谢您的评论。虽然我有点喜欢 USB 棒的想法。 :-)
    • @KerrekSB 外部定义为不在您的建筑物的编译单元中,而是在您稍后将链接到的编译单元中。
    • 我认为这个词是“外部链接”:-)(如“标题声明了一个具有外部链接的全局变量”)。
    • @KerrekSB:那是完美,谢谢!现在重新编辑,希望是最后一次。 :-)
    【解决方案2】:

    来自手册页

    GETOPT(3)                BSD Library Functions Manual                GETOPT(3)
    
    NAME
         getopt -- get option character from command line argument list
    
    LIBRARY  
         Standard C Library (libc, -lc)  
    
    SYNOPSIS  
         #include <unistd.h>  
    
         extern char *optarg;  
         extern int optind;  
         extern int optopt;  
         extern int opterr;  
         extern int optreset;  
    
         int  
         getopt(int argc, char * const argv[], const char *optstring);
    

    这些变量在unistd.h 头文件中声明。

    【讨论】:

    • 谢谢。我知道全局变量是什么,但我没有意识到 optarg 是在 unistd.h 中声明的
    • @IrresponsibleNewb Websearch 是回答此类问题的一种非常简单的方法:google.com/#hl=en&q=optarg
    • @DavidHeffernan:或者阅读手册页(当然,假设您使用的是类似 unix 的系统)。所以我喜欢这样回答。在这种情况下,bash 还提供了optarg,因此您需要指定要阅读的手册部分:$ man 3 optarg
    【解决方案3】:

    为了将来参考,如果你找到名字但不知道它们在哪里定义或声明,只运行C预处理器,它负责#include,然后使用grep或搜索词条只是more

    例如

    gcc -E foo.c >foo.i
    

    会将 C 预处理器的结果放入 foo.i

    然后您可以使用 more 查看文件(使用 / 进行搜索)

    该文件将引用包含定义或声明的包含文件。

    例如,
    more foo.i
    然后
    /optarg
    显示线
    extern char *optarg;
    通过向上滚动(或反向搜索 ?# )我可以找到
    # 414 "/usr/include/unistd.h" 3 4

    【讨论】:

      【解决方案4】:

      optarg&lt;unistd.h&gt; 中声明。

      【讨论】:

      • 当然不是 - 这会违反 ODR,不是吗?
      • @KerrekSB 我确定他的意思是它在 unistd.h 中使用 extern 声明,但在其他地方定义。
      【解决方案5】:

      ——变量:char * optarg

      对于那些接受参数的选项,此变量由 getopt 设置为指向选项参数的值。

      我在Using Getopt 网站上找到了这个

      【讨论】:

        猜你喜欢
        • 2016-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多