传入char * argv []和声明char * argv有什么不同?

时间:2014-02-07 15:57:43

标签: c ruby

我的技能非常生疏,所以如果这是一个愚蠢的问题,我道歉,但我甚至不能想到要找到这个简单问题的答案。 此代码编译时没有任何警告:

#include <ruby.h>

int run_script( int argc, char *argv[] )  {
  ruby_sysinit(&argc,  &argv);
}

但是当我编译这段代码时,我收到以下警告:

#include <ruby.h>

int run_script( char * parameters )  {
    int argc=0;
    char *argv[1];
    ruby_sysinit(&argc,  &argv);
}

run_script_3.c: In function 'run_script':
run_script_3.c:7: warning: passing argument 2 of 'ruby_sysinit' from incompatible pointer type

似乎我在两种情况下都传递相同的指针类型。

2 个答案:

答案 0 :(得分:2)

问题是形式参数声明中的数组等效于指针。宣言

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

相当于

int run_script( int argc, char **argv)  { ... }

因为您无法将数组作为参数发送。您只能发送一个指针,即使您将数组作为实际参数,它也总是转换为指针。然后,如果你把&argv放到了这个参数的地址,那么它就是系统堆栈中存储argv值的地址。

另一方面,代码中的数组仍然是一个数组,它是不同的类型。在您的情况下,&argvchar ***的第一个版本中的类型为run_script,而在第二个版本中的类型为char *(*)[1]。它看起来像是同一类型,但事实并非如此。在运行时,存在更大的差异,因为您的两个调用正在向ruby_sysinit发送两个完全不同的值。

你的第二个例子:

int run_script( char * parameters )  {
    int argc=0;
    char *argv[1];
    ruby_sysinit(&argc,  &argv);
}

可能会导致段错误,因为应用于数组的opearator &会给出指向数组第一个元素的指针。因此,调用ruby_sysinit(&argc, &argv);正在发送与ruby_sysinit(&argc, argv);相同的值,即指向char*的值,而不是指向char*所指向的ruby_sysinit

答案 1 :(得分:0)

ruby_sysinit的签名如下(如果我选择了错误的ruby版本,请更正我,我的系统上没有头文件):

void ruby_sysinit(int *argc, char ***argv);

这意味着以下编译:

extern void ruby_sysinit(int *argc, char ***argv);

int run_script(char * params)  {
    int argc = 0;
    char **argv;
    ruby_sysinit(&argc, &argv);
}

现在,当您声明char *argv[1]时,您告诉编译器这是一个包含一个元素的数组。这与char **argv不同。

编辑:您可能会发现this question on SOthis article (as linked in the other question)有用。