Массив реализации указателей в C - PullRequest
1 голос
/ 12 августа 2010

Hii,

Я пытался написать программу ... У нас есть структура, которая имеет поле ранга и поле имени. Указатель на эту структуру хранится в массиве фиксированного размера. Я реализовал это следующим образом, и у меня есть определенные проблемы ... Код, который я написал:

 #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 ]

2 голосов
/ 12 августа 2010

Прежде всего, все ваши функции всегда возвращают 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') 

, для того чтобы это значение было равно false, ch должно быть как «n», так и «N»в то же время.Вы действительно хотите

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

ОБНОВЛЕНИЕ 2: Я только что заметил самую большую проблему в вашем коде.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.

0 голосов
/ 12 августа 2010
 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 () вызывает эту проблему. Поскольку '\ n' после чтения символа в 'ch' используется как вход для scanf. Один из способов решения вашей проблемы - прочитать '\ n' с помощью дополнительного getchar (), прежде чем он будет прочитан get (). Также вы должны изменить цикл while в delete.

0 голосов
/ 12 августа 2010

Я запутался в использовании переменной "rank". Main использует его в качестве индекса для последнего узла в массиве, а узлы используют его в качестве ранжирования. Добавление узлов увеличивает его, но удаление узлов не уменьшает его.

По крайней мере, я бы предложил отделить переменную индекса от переменной ранжирования, чтобы упростить логику.

Лично я бы написал структуру для инкапсуляции массива с собственными функциями отслеживания индекса и добавления / удаления. Таким образом, Main может свободно читать пользовательские настройки и манипулировать рангами новых узлов, не беспокоясь о деталях структуры данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...