user-0 提问: 线性表相关，代码说0error，但运行时一直运行不下去，求看看这种情况到底是哪里出错了！

回复:
user: user-1
content: 为什么用二级指针？那就看你能否理解以下内容了。 首先你要理解形参只是函数栈的局部变量，修改局部变量(也就是给形参赋新值)是不会影响函数外的变量的。 举个例子 void fun(int n) {n=10;} int main() { int a = 5; fun(a);  printf(“%d”, a); //调用fun后a不会变为10 return 0; } 显然在main调用fun，main的a是不会变为10的，因为实参a是main方法栈的变量，形参n是fun方法栈的变量，a和n内存地址不同，函数调用只是把实参a内存的信息拷贝到形参n的内存，所以函数内修改形参的内存(n=10)，不会影响实参a的内存。 改为 fun(int *n) {*n=10;} //注意这里是*n=，而不是n= int main() { int a; fun(&a);  //这里是传入a的地址 printf(“%d”, a); //调用fun后a会变为10 return 0; } 这个和上面的区别是什么？fun的形参改为int*指针，main把a的地址拷贝给了fun的形参n，在函数内不去修改形参的内存(即不去执行n=10，这点很重要)，而是修改形参n内存中保存的a的地址的内存(即执行*n=10)，这样才会影响函数外的a。  可见，要想在函数内处理形参能改变函数外的实参，必须满足 1 形参就要用指针类型 2 把实参的地址传给形参 3 并且函数内不能用 形参=xx的方式，要用 *形参=xx的方式。  所以同样的，对比上面的条件，在你的main里 List *L;  inList(&L); //要想在inList里改变L，这里就要传入L的地址(而且inList里不能用L=xx，要用*L=xx)。 L本身是指针，&L就是二级指针，所以inList的形参要用二级指针，即inList(List **L)

user: user-2
content: #include<stdio.h> #include<stdlib.h> #define Maxsize 5   // int i是线性表长度  typedef struct List        //线性表的定义 {     char data[Maxsize];     int length; }List;  void inList(List **L)    //线性表的初始化 {     *L=(List *)malloc(sizeof(List));        //给线性表分配空间     if (!(*L))         exit(0);     (*L)->length=0;        //使表长为0 }  void InputList(List *L,int i)        //给线性表输入元素 {     int p;     for(p=0;p<i;p++)    //建议用i作为循环变量，用len作为第二个形参     {         printf("请输入你想要输入的元素:");         scanf("%c",&L->data[p]);     }     L->length = i;    //少一步更新线性表长度 }  void outputList(List*L,int i)        //输出线性表元素 {     int p;     for(p=1;p<i;p++)     {         printf("线性表第%d个元素为:%c",p,L->data[p]);         printf("\n");     } }  int InsertList1(List*L,int i)        //用尾插法插入元素 {     int p,m;     printf("请输入你想插入元素个数:");     scanf("%d",&p);     getchar();    //for '\n'     L->length=i+p;     for(m=1;(m+i)<=L->length;m++)     {         printf("请输入你想输入的元素:");         scanf("%c",&L->data[m+i]);     }      return L->length;        //返回现在元素个数 }  int InsertList2(List*L,int i)        //在中间插入元素 {     int m;     printf("你计划在第几个元素插入新元素:");     scanf("%d",&m);     getchar();    //for '\n'     for(;i>=m;i--)     {         L->data[i+1]=L->data[i];    //使m后的元素均向后挪一位,从末位开始挪     }     printf("你想插入的元素为:");     scanf("%c",&L->data[m]);     L->length++;     return L->length;                //返回现在线性表的长度 }  int deleteList(List*L,int i)                //删除线性表元素 {     int m;     printf("输入你想删除的线性表第几个元素:");     scanf("%d",&m);     getchar();    //for '\n'     for(;m<=i;m++)                    //从被删除元素开始,元素集体往前挪一位     {         L->data[m]=L->data[m+1];     }     return L->length; }  void DestoryList(List*L)            //销毁线性表 {     free(L); }  int main()                            //主函数 {     int i,a;     List *L;      inList(&L);   //首先需要初始化L，否则这是一个野指针；；；；；；     printf("请输入你想要输入元素的个数:");        //获得线性表长度,i为表长     scanf("%d",&i);     getchar();    //for '\n'      if (i > Maxsize)    //防止越界         i = Maxsize;      InputList(L,i);      outputList(L,i);      i=InsertList1(L,i);      outputList(L,i);      printf("线性表第三个元素为:%c",L->data[3]);        //输出线性表第三个元素     printf("线性表的长度为:%d",i);                    //输出线性表长度      i=InsertList2(L,i);                        //插入新元素,更新插入元素后的线性表长度      for(a=1;a<=i;a++)                //输出线性表元素     {         printf("线性表的元素有:%c",L->data[a]);     }      i=deleteList(L,i);            //删除线性表      outputList(L,i);            //输出目前线性表元素      DestoryList(L);            //摧毁线性表     return 0; }  楼主的代码有多初问题，线性表没有调用初始化，初始化函数参数需要是二重指针，还有就是要多加几条getchar();

user: user-0
content: 引用 3 楼 qybao的回复:为什么用二级指针？那就看你能否理解以下内容了。 首先你要理解形参只是函数栈的局部变量，修改局部变量(也就是给形参赋新值)是不会影响函数外的变量的。 举个例子 void fun(int n) {n=10;} int main() { int a = 5; fun(a);  printf(“%d”, a); //调用fun后a不会变为10 return 0; } 显然在main调用fun，main的a是不会变为10的，因为实参a是main方法栈的变量，形参n是fun方法栈的变量，a和n内存地址不同，函数调用只是把实参a内存的信息拷贝到形参n的内存，所以函数内修改形参的内存(n=10)，不会影响实参a的内存。 改为 fun(int *n) {*n=10;} //注意这里是*n=，而不是n= int main() { int a; fun(&a);  //这里是传入a的地址 printf(“%d”, a); //调用fun后a会变为10 return 0; } 这个和上面的区别是什么？fun的形参改为int*指针，main把a的地址拷贝给了fun的形参n，在函数内不去修改形参的内存(即不去执行n=10，这点很重要)，而是修改形参n内存中保存的a的地址的内存(即执行*n=10)，这样才会影响函数外的a。  可见，要想在函数内处理形参能改变函数外的实参，必须满足 1 形参就要用指针类型 2 把实参的地址传给形参 3 并且函数内不能用 形参=xx的方式，要用 *形参=xx的方式。  所以同样的，对比上面的条件，在你的main里 List *L;  inList(&L); //要想在inList里改变L，这里就要传入L的地址(而且inList里不能用L=xx，要用*L=xx)。 L本身是指针，&L就是二级指针，所以inList的形参要用二级指针，即inList(List **L) 我懂了！！！！谢谢！

user: user-0
content: 引用 1 楼 qybao 的回复:main函数里L指针没初始化 inList函数在函数里改变L的指向，不影响函数外指针的指向，所以应该用二级指针，即 inList(List  **L)，然后在main里先调用它初始化L 不太懂为什么要用二级指针，我才发现main里没有放初始化函数

user: user-1
content: main函数里L指针没初始化 inList函数在函数里改变L的指向，不影响函数外指针的指向，所以应该用二级指针，即 inList(List  **L)，然后在main里先调用它初始化L