C中的指针数组实现

时间:2010-08-12 14:19:31

标签: c pointers

Hii,

我一直在尝试编写一个程序......我们有一个具有rank字段和name字段的结构。这个结构的指针存储在一个固定大小的数组中。我已经实现了如下,我有一些问题...... 我写的代码是:

 #include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct 
{
 int rank;
 char *name;
}node;

int insert(node **a , char name[] , int *rank)
 {
 if(*rank >= 5)
  {
   printf("\n Overflow ");
   return 0;
  } 
  (*rank)++;
  node *new = (node *)malloc(sizeof(node));
  new->name = name;
  new->rank = *rank;
  a[*rank] = new;

  return 0;
 } 

int delete(node **a , int *rank)
 {
  int i = *rank;
  if(*rank<0)
   {
    printf("\n No elements");
    return 0;
   }
   printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name);
   printf("\n Reordering the elements ");
   while(i<5)
    {
     a[i] = a[i+1];
    }  
  return 0;
 }

 int display(node **a , int rank)
  {
   while(rank>0 && (a[rank])>0)
    {
     printf(" rank = %d    name = %s \n",((a[rank])->rank),((a[rank])->name));
     rank--;
    }            
    return 0;
  }

int main()
 {
  node *a[5] = {NULL};
  char ch = 'y';
  int choice,rank = -1;
  char name[10];
  while(ch!='n' || ch!= 'N')
   {
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n");
    scanf("%d",&choice);
    switch(choice)
     {
      case 1:
        printf("\n Enter name to insert");
        gets(name);
        insert(a,name,&rank);
        break;
      case 2:
        printf("\n Enter rank to delete ");
        scanf("%d",&rank);
        delete(a,&rank);
        break;
      case 3:
        display(a,rank);
        break;
      case 4:
        exit(0);
      default:
        printf("\n Invalid choice...please enter again ");
        break;
     } 
    ch = getchar();
  }
 return 0;
 } 

首先是系统自动选择除了第一次......(我在那里找不到故障......)我对这个指针的东西有点困惑...请看看它是否是好的...欢迎任何更正,请给我一些解释,为什么它是错的,我们怎么做...

谢谢

3 个答案:

答案 0 :(得分:2)

首先,即使出现错误情况,所有函数也始终返回0。如果你把秩数作为一个int传递,并且返回它的新值,那么生活会变得如此简单。

rank = insert(a, name, rank); 
/* : */
/* : */
int insert(node **a , char name[] , int rank)  
{  
 if(rank >= 5)  
 {  
   printf("\n Overflow ");  
   return 0;  
 }   
 rank++;  
 node *new = (node *)malloc(sizeof(node));  
 new->name = name;  
 new->rank = rank;  
 a[rank] = new;  
 return rank;  
}

我上次使用scanf已经很多年了,但我记得,你必须说明流中的每个字符,意思是“不要忘记输入”。

scanf("%d\n",&choice);  

同样使用gets(name);,如果您输入的内容超过9个字符,那么您会非常紧张,因为它会覆盖您程序的堆栈。

更新: 此外,您有两种退出此程序的方法,除了一种方法永远不会有效。您可以选择选项“4”,它将调用exit(0)。或者,在每个命令结束时,您等待一个字符才能单步执行。您似乎希望能够输入“N”并退出,但不起作用:

while(ch!='n' || ch!= 'N') 

为了评估为假,ch必须是“n”和&amp; “N”同时出现。你真的想要

while(ch!='n' && ch!= 'N') 

UPDATE2:  我刚刚注意到你代码中最大的问题。 name代码中的任何地方都只指向main()中定义的单个数组。每次输入新名称时,它都会覆盖该数组,并且由于每个节点都指向该数组,因此名称随处可见。你需要复制一份。 在insert()中:

node *new = (node *)malloc(sizeof(node));     
new->name = strdup(name);    // use malloc internally.

然后在delete()中你必须释放那个内存(说到哪个,你需要在那里释放节点......)

printf("\n Deleting %d , %s ",((a[*rank]))->rank,((a[*rank]))->name);       
free(a[*rank]->name);
free(a[*rank]);
printf("\n Reordering the elements ");

请记住,每当您致电malloc时,您最终都必须致电free

答案 1 :(得分:0)

我对使用“rank”变量感到困惑。 Main将其用作数组中最后一个节点的索引,节点将其用作排名。添加节点会增加它,但删除节点不会减少它。

至少,我建议将索引变量与排名变量分开,以使逻辑更容易理解。

就个人而言,我会编写一个结构来封装数组,并使用自己的索引跟踪和添加/删除功能。这样,Main可以自由地读取用户选项并操纵新节点的等级,而无需担心数据结构细节。

答案 2 :(得分:0)

 while(ch!='n' || ch!= 'N')
   {
    printf("\n Enter 1 to insert , 2 to delete , 3 to display and 4 to exit \n");
    scanf("%d",&choice); getchar();
    .
    .
    .
    //ch = getchar();
  }

使用getchar()和scanf()会导致此问题。因为将字符读入'ch'后'\ n'作为scanf的输入。解决问题的一种方法是在get()读取之前使用额外的getchar()读取'\ n'。 你也应该在删除时修改while循环。