【问题标题】:Pointer arithmetic in array of strings字符串数组中的指针运算
【发布时间】:2020-11-17 14:32:28
【问题描述】:

我正在阅读一本 linux 编程用 c 语言的书,它有以下代码。

        int main(int argc, char *argv[])
    {
        int opt;
        while ((opt = getopt(argc, argv, "iv")) != -1) {
            switch (opt) {
            case 'i':
                opt_ignorecase = 1;
                break;
            case 'v':
                opt_invert = 1;
                break;
            case '?':
                fprintf(stderr, "Usage: %s [-iv] [<file>...]\n", argv[0]);
                exit(1);
            }
        }
        argc -= optind;
        argv += optind;
}

我不明白为什么 argv += optind 有效。 当我尝试另一个程序时,如下所示:

int main(int argc, char* argv[])
{
    
    char* test[] = {"Hello", "World", "I"};
    argv += 1;
    test += 1;
    printf("%s", test[0]);
    return 0;
}

gcc 编译器显示错误

a.c:8:9: error: assignment to expression with array type
8 |    test += 1;

argv 上的 += 有效,但不适用于测试。 我不明白我做错了哪一部分..

【问题讨论】:

  • char* argv[] 作为函数参数是写char** argv 的不同方式。所以,它是一个指向指针的指针,test 是一个指针数组

标签: c


【解决方案1】:

当一个数组声明出现在函数参数列表中时,它会自动调整为声明一个指针。所以int main(int argc, char *argv[]) 实际上将argv 声明为具有char ** 类型。

由于argv 是一个指针,我们可以用argv += optind; 递增它。 argv 最初指向几个char * 中的第一个,而argv += optind; 改变了它指向的char * 中的哪一个。

相比之下,声明char* test[] = {"Hello", "World", "I"};test 定义为char * 的数组。由于是数组,所以不能移动; test += 1 试图改变数组的位置,这是不允许的。

定义test后,你可以定义一个新的指针char **p = test;,然后你可以用p += 1;调整p。 (注意,在char **p = test; 中,test 会自动转换为指向其第一个元素的指针,因此这相当于char **p = &amp;test[0];。)

(注意:语法上,char * test [] 中的*test [] 绑定,而不是char,因此char* test[] 具有误导性。像char* a, b; 这样的声明不会同时声明a 和@ 987654348@ 为char*。它声明achar *bchar,所以char *a, b; 是一个更好的含义图片。)

【讨论】:

  • 嗨,eric,谢谢您的解释。在尝试做类似 char *hello[] = {"Hello", "I", "am", "Low"};字符 ** 测试 = 你好;有用。顺便说一句,有点跑题了,如果我做上面这样的事情有什么缺点?
  • @nicklowkc:它本身并没有太大的缺点,在你进一步学习 C 和编程之前,我不会担心它。一个缺点是表单需要两个标识符,hellotest,而可以使用一个标识符,char **test = (char *[]) {"Hello", "I", "am", "Low"};。但是在程序的上下文中还有其他的考虑,比如数组应该是静态的还是自动的,是否需要重置到开头,其他地方是否使用了相同的字符串等等。
【解决方案2】:

argv 没有数组类型,尽管声明是如何编写的;它的实际类型是char **

在函数参数列表中,T a[N]T a[] 形式的任何声明都调整T *a - 所有三个都将 a 声明为指针,而不是数组。这适用于函数参数声明,而不是常规声明。

【讨论】:

    猜你喜欢
    • 2021-06-28
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 2012-02-08
    相关资源
    最近更新 更多