【问题标题】:Pointers, structure, passing arguments, recursion指针、结构、传递参数、递归
【发布时间】:2015-06-16 01:04:30
【问题描述】:

我有这样的代码:

typedef struct _Statistics {

  Some code here

} Statistics;

void function1(char *string, Statistics *statistic){

   Some code here

   function1(string1, statistic);
}
int main(){

   Statistics statistic;
   function1(string, &statistic);
}

这可能是一个愚蠢的问题,但我不完全理解指针: 我明白为什么我在主函数中使用&,&发送变量统计的地址,以便在function1中我可以修改它。但是为什么我不在递归函数中使用 & 呢?

【问题讨论】:

  • 因为它已经是一个指针。 main 中的 statistic 是一个实际对象。调用function1(string, &statistic); 将指针 传递给function1。所以当function1调用自己时,它可以直接使用main()给出的指针。
  • 将你的函数声明为void function1(char *string, Statistics *ptr),你就会明白为什么递归调用是function1(string1, ptr);

标签: c pointers recursion struct argument-passing


【解决方案1】:

因为&statistic(在function1()中)是指针的内存地址,而不是指针所包含的地址。

&statistic 的类型是Statistics** in function1()。


关于指针的几句话

假设我们定义了以下变量:

char c = 'a';
char *p_c = &c;

现在,我们将打印p_c和c的值和内存地址:

printf("%c\n", c); // will print 'a'
printf("%c\n", *p_c); // will print 'a' 

printf("%p\n", &c); // will print the memory address of c
printf("%p\n", p_c); // will print the memory address of c

printf("%p\n", &p_c); // will print the memory address of p_c

最后我们定义一个char**,一个指向char的指针:

char **p_pc = &p_c;

printf("%c\n", **p_pc); // will print 'a'
printf("%p\n", *p_c); // will print the memory address of c
printf("%p\n", p_c); // will print the memory address of p_c

【讨论】:

    【解决方案2】:

    有时这样写会有所帮助:

    void function1(char* string, Statistics* statistic){
    

    变量statistic 是一个指向Statistics 的指针,而不是Statistics 本身。如果您在函数 1 中执行此操作:

       function1(string1, &statistic);
    

    您将传递一个指向(因为 &)指向(因为声明中的 *)统计的指针,这是不正确的。

    您在 main 中将 statistic 声明为 Statistic 增加了混乱:您在两个范围内使用了具有不同类型的相同变量名。

    使用不同的变量名称更清晰:

    typedef struct _Statistics {
      Some code here
    } Statistics;
    
    void function1(char* string, Statistics* ptrstat){
       Some code here
       function1(string1, ptrstat);
    }
    
    int main(){
       Statistics statistic;
       function1(string, &statistic);
    }
    

    【讨论】:

    • 所以基本上,当我第一次用 & 调用 function1(从 main)时,我给他地址位置,例如 444555666,*statistic 是该地址持有的东西,例如 444555666 持有 5,但在统计中我仍然有相同的位置。我说的对吗?
    • 基本上就是这样,是的
    【解决方案3】:

    一般情况下(即大多数语言),您可以按值传递或按引用传递。这将取决于函数的定义及其“签名”;即声明它及其参数的方式。

    按值传递就像一个赋值,如果复制一个更大的结构,它会花费更长的时间。此外,该函数仅接收一个副本,因此您可以更改函数中的参数,但这只会影响函数的本地副本(参数)并且不会更改原始值(在调用者中)传给你了。

    相比之下,按引用传递只是传递原始值的指针(内存中的地址)。这要快得多(4 或 8 个字节),但这确实意味着该函数不仅可以读取调用者的值,还可以写入调用者的值。有时你想要这个!有时你不会。

    在您的主要业务中,您拥有统计数据的价值。您调用的函数需要地址 (*),因此您需要传递其地址 (&statistic),而不是传递值 (statistic)。

    在调用自身的函数中,您有一个指向 statistic (Statistics *) 的指针,并且您必须传递一个指向 statistic (Statistics *) 的指针:因此,只需传递它,指针 'statistic'。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-02
      • 2017-10-13
      • 1970-01-01
      • 2013-11-18
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多