将指针传递给函数时为什么会出现2个星

Me_*_*_me 3 c memory pointers

花了很长时间才使这个代码工作,有人可以向我解释为什么我需要2个星,当我将指针传递给字符串作为函数的参数时?根据定义,指针将地址保存到将放置特定变量的存储器中.所以它是一个变量,它有自己的地址,在这个地址下是另一个变量的地址.好的.因此,如果我将指针传递给函数,我会使用&符号,因为我必须将指针地址传递给函数.精细.但接下来会发生什么.该函数接收存储器中该指针所在的信息.好的.这就是我的理解.我不明白为什么在定义函数及其参数时我需要两颗星.我传递一个指向char变量的指针.为什么不使wpisuj(char*w)无效.为什么wpisuj(char**w).内存分配对我来说是不可接受的 - 我使用malloc保留内存,malloc返回此内存的地址,因此我将此地址作为变量w的值.然后再一些我不明白的东西,如果*w是指针并将新创建的地址保存在内存中,为什么我使用*w来放置一个字符串.它应该不是*(*w)吗?由于*w是保留存储器的地址,因此*(*w)是该存储器的内容.

加起来.我不明白的是:1)为什么wpisuj(char**w)而不是wpisuj(char*w)2)为什么strcpy(w,bufor)而不是strcpy((*w),bufor)

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
# define SIZE 256

void wpisuj(char** pw){
  char bufor[256];
  scanf("%s", bufor);
  int l;
  l=strlen(bufor)+1;
  *pw=(char*)malloc(l*sizeof(char));
  strcpy(*pw, bufor);
}


int main(){
  char* w;
  wpisuj(&w);
  printf("%s", w);  

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我也可以询问有关释放内存的问题.我是否认为这是明星的核心数量(如下面的代码所示):

void free_memory(char **w){
   free(*w);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在main()中释放内存,我会:

int main(){
  w=malloc(sizeof(buffer)+sizeof(char));
/* some code before */
  free(w);
}
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 6

因为很明显可以考虑以下简单程序

#include <stdio.h>

void f( int x )
{
    x = x + 20;
}

int main(void) 
{
    int x = 10;

    printf( "Before the call f( x ) x = %d\n", x );

    f( x );

    printf( "After  the call f( x ) x = %d\n", x );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出将是

Before the call f( x ) x = 10
After  the call f( x ) x = 10
Run Code Online (Sandbox Code Playgroud)

如你所见,x在函数f中没有被处理,因为该函数处理main中定义的对象x的副本.

但是,如果您将以下列方式重写该功能

#include <stdio.h>

void f( int *x )
{
    *x = *x + 20;
}

int main(void) 
{
    int x = 10;

    printf( "Before the call f( x ) x = %d\n", x );

    f( &x );

    printf( "After  the call f( x ) x = %d\n", x );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

那么在这种情况下输出将是

Before the call f( x ) x = 10
After  the call f( x ) x = 30
Run Code Online (Sandbox Code Playgroud)

因为我们将原始对象x的地址传递给函数,并且在函数内部更改了原始对象本身.

对于帖子中的指针,这同样有效.

如果要定义指针

char *p;
Run Code Online (Sandbox Code Playgroud)

在main中并将其作为函数的参数传递

void f( char *p );
Run Code Online (Sandbox Code Playgroud)

然后该函数将处理原始对象的副本.副本的任何更改都不会影响原始指针.因此,在第一个示例中,您应该传递一个指向此指针的指针,该指针应该被声明为

void f( char **p );
Run Code Online (Sandbox Code Playgroud)

而你必须称之为

f( &p );
Run Code Online (Sandbox Code Playgroud)