【问题标题】:a pointer about *argv[]关于 *argv[] 的指针
【发布时间】:2012-05-09 06:44:24
【问题描述】:

这是我的main.c

......
int main(int argc, char **argv)
{
    init_arg(&argc, &argv);
    ......
}

这是我的init_arg.c

......
void init_arg(int *argc, char ***argv)
{
    printf("%s\n", *argv[1]);
    ......
}

我编译它没有错误和警告。

我运行它:

./a.out include

得到分段错误

调试的时候发现步骤printf("%s\n", *argv[1]);

弄错了,它显示:

print *argv[1]

Cannot access memory at address 0x300402bfd

我想知道,如何在init_arg()函数中打印argv[1]

【问题讨论】:

标签: c pointers gdb arguments main


【解决方案1】:

您需要在 (*argv) 周围添加一对括号来更改评估顺序。您当前拥有它的方式,首先评估 [1],产生一个无效的指针,然后被取消引用,导致未定义的行为。

printf("%s\n", (*argv)[1]);

【讨论】:

  • 或者,等效地,您可以使用argv[0][1](与输入一样长,但可能更具可读性)。
  • @torek 我会避免使用argv[0] 代替(*argv),因为传入的是“标量”指针(即指向单个数组的指针),而不是指向数组的指针。我认为(*argv) 语法强调了我们正在查看指向标量的指针的概念。
  • 显然你属于那些喜欢保持 C 下降的区别的人。我同情!在 1980 年代初期,我有一位同事喜欢根据方便的情况一直混合使用指针和数组表示法。特别是他会做这样的事情:time_t now[1]; time(now); ... 而不是time_t now; time(&now); ...。 :-)
  • "[...] 保持 C 放弃的区别" 这是一个常见的误解,主要是由于数组在传递给函数时会衰减为指针。您展示的示例是一个很好且完全合法的示例:将包含一项的数组视为指针与将指针视为包含一项的数组之间存在很大差异。
  • 我的观点是,C 语言 没有提供任何方法(在被调用者中,例如函数fn)来发现某个指针参数T *p 是否指向单个项目 (T var; fn(&var);) 或 N 连续项目中的第一个 (T var[N]; fn(var);)。它可以帮助 程序员 区分它们,但语言本身并不能为您做到这一点。与 Pascal 和 Go 等进行比较。
【解决方案2】:

Argv 已经是一个指针。像这样传递它:

init_arg(&argc, argv);

init_arg 应该是这样的:

void init_arg(int *argc, char **argv) {
    printf("%s\n", argv[1]);
}

【讨论】:

  • 这个答案是正确的,但是他也可以只通过argc而不是&argc。大概传递&argc&argv 的目的是允许init_arg 修改它们。
  • 你可以像这样修改它们。
【解决方案3】:

我假设首先传递&argc&argv 的原因是您可以在init_arg 中更新它们。一般来说,我喜欢这样编写此类函数:

/*
 * init_arg: do something useful with argc and argv, and update argc and argv
 * before returning so that the caller can do something else useful that's
 * not shared with all the other callers of init_arg().
 * (this comment of course needs updating to describe the useful things)
 */
void init_arg(int *argc0, char ***argv0) {
    int argc = *argc0;
    char **argv = *argv0;
    ... all the operative code goes here, and then ...
    *argc0 = argc;
    *argv0 = argv;
}

当然,这意味着你不能在init_arg 中尽早使用returns,所以会有一些折衷,但使用相同的常规旧argcargv 在@ 中肯定要容易得多987654329@.

【讨论】:

  • 如果您错过了提前返回,请使用 goto :)
猜你喜欢
  • 1970-01-01
  • 2013-06-19
  • 2018-04-05
  • 1970-01-01
  • 2022-01-21
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多