C 指针、结构、传递参数、递归

C 指针、结构、传递参数、递归,c,pointers,recursion,struct,argument-passing,C,Pointers,Recursion,Struct,Argument Passing,我有这样的代码: 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, &stati

我有这样的代码:

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);
}
这可能是个愚蠢的问题,但我不完全理解指针:
我理解为什么在主函数中使用变量统计的发送地址(&S),以便在函数1中修改它。但是为什么不在递归函数1中使用&in?

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

&statistic
的类型是
function1()
中的
Statistics**


关于指针的几句话

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

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

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

&statistic
的类型是
function1()
中的
Statistics**


关于指针的几句话

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

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

有时这样写会有帮助:

void function1(char* string, Statistics* statistic){
变量
statistic
是指向统计信息的指针,而不是统计信息本身。如果在功能1中执行此操作:

   function1(string1, &statistic);
您将传递一个指向(由于&)统计数据的指针,而这是不正确的

您主要将
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);
}

有时这样写会有帮助:

void function1(char* string, Statistics* statistic){
变量
statistic
是指向统计信息的指针,而不是统计信息本身。如果在功能1中执行此操作:

   function1(string1, &statistic);
您将传递一个指向(由于&)统计数据的指针,而这是不正确的

您主要将
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);
}
通常(即大多数语言),您可以按值传递或按引用传递。它将取决于函数及其“签名”的定义;i、 e.它及其参数的声明方式

传递值类似于赋值,如果复制更大的结构,则需要更长的时间。此外,函数只接收副本,因此您可以更改函数中的参数,但这只会影响函数的本地副本(参数),并且不会更改传递给您的原始值(在调用方中)

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

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

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

通常(即大多数语言),您可以按值传递或按引用传递。它将取决于函数及其“签名”的定义;i、 e.它及其参数的声明方式

传递值类似于赋值,如果复制更大的结构,则需要更长的时间。此外,函数只接收副本,因此您可以更改函数中的参数,但这只会影响函数的本地副本(参数),并且不会更改传递给您的原始值(在调用方中)

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

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


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

因为它已经是指针了。主要的
统计数据
是一个实际对象。调用
function1(字符串和统计信息)将指针交给函数1。因此,当function1调用自身时,它可以只使用main()给出的指针。将您的函数声明为
void function1(char*string,Statistics*ptr)
,您将看到为什么递归调用是
function1(string1,ptr)统计数据
是一个实际对象。调用
function1(字符串和统计信息)将指针交给函数1。因此,当function1调用自身时,它可以只使用main()给出的指针。将您的函数声明为
void function1(char*string,Statistics*ptr)
,您将看到为什么递归调用是
function1(string1,ptr)所以基本上,当我第一次调用function1(从main)时,我给他地址位置,例如444555666,*统计数据是该地址保存的东西,例如444555666h