У меня есть структура Item со следующими членами.

struct Item{
    char *name;
    int price;
    double weight;
};

Другая структура Inventory со следующими членами.

struct Inventory{
    struct Item **item;
    int NUMITEMS;
};

У меня есть функция addItem(), которая принимает Inventory* в качестве параметра.

void addItem(struct Inventory* i){
     printf("Enter Name:");
     scanf("%s",i->item->name);
     printf("Enter Price");
     scanf("%d",i->item->price);
     printf("Enter Weight");
     scanf("%lf",i->item->weight);
}

Основная цель функции - присвоить значения члену структуры Item. Как я могу это сделать? Я хочу установить значения членов структуры Item с помощью двойного указателя типа item из функции. Весь мой код:

#include<stdio.h>
 struct Item{
  char *name;
  int price;
  double weight;
   };

 struct Inventory{
  struct Item **item;
  int NUMITEMS;
 }inventory1;

struct Character{
 char *name;
 int Level;
 long XP;
 struct Inventory inventory;
 };
  void createCharacter(struct Character* c){
    printf("Enter Name:");
    c->name = (char*) malloc(40*sizeof(char));
    scanf("%s",c->name);
    printf("Enter Level:");
    scanf("%d",&c->Level);
    printf("Enter XP:");
   scanf("%ld",&c->XP);
  }
void viewCharacter(struct Character* b){
printf("%s level %d with %ld XP",b->name,b->Level,b->XP);
  }
 void addItem(struct Inventory* i){
 i->item =(struct Item*)malloc(i->NUMITEMS*sizeof(struct Item));
 printf("Enter name:");
 scanf("%s",i->item->(*name));
 }

void viewItem(struct Inventory* i){
   //yet to write
 }
c
2
IcanCode 7 Дек 2020 в 13:08

1 ответ

Лучший ответ

Эта структура ...

 struct Inventory{
  struct Item **item;
  int NUMITEMS;
 }inventory1;

... имеет вид обертки для массива, возможно, динамически выделяемого, указателей на struct Item. Члены экземпляров item указывают на первый указатель в этом массиве. Существует несколько способов доступа к элементам элементов, на которые указывают элементы массива, но поскольку структура представляет собой массив, наиболее естественным и интуитивно понятным способом, вероятно, будет использование синтаксиса массива:

struct Inventory *inv = /* ... */ ;

for (int i = 0; i < inv->NUMITEMS; ++i) {
    printf("%s\n",
            // here:
            inv->item[i]->name
    );
}

Объяснение : поскольку inv является указателем на struct Inventory, косвенный оператор доступа к члену является естественным для доступа к его элементам, таким как inv->item. Со своей стороны, inv->item является указателем на другой указатель. Вы должны разыменовать его, а затем разыменовать результат, чтобы получить struct Item. Хотя вы можете использовать оператор разыменования (унарный *) непосредственно для этой цели, оператор индексации массива [] и оператор косвенного доступа к членам -> разыменовываются как часть их поведения (всегда) , так что вы получите два необходимых указания, индексируя массив элементов и используя оператор косвенного доступа для получения интересующего элемента.

Дополнительные примечания :

  • имя члена item элемента struct Inventory может ввести вас в заблуждение, поскольку оно является указателем на указатель на элемент, а не указателем непосредственно на элемент, и потому, что оно имеет все виды служит указателем на первый из (возможно) нескольких указателей на элементы в таком массиве, несмотря на то, что его имя является единственным.

  • сигнатура вашей функции viewItem() и, возможно, вашей функции addItem() поэтому кажется недостаточной для очевидной задачи. Если вы хотите просмотреть конкретный элемент, вам необходимо указать какой именно , предположительно, передав его индекс в качестве дополнительного аргумента. То же самое, если вы хотите добавить элемент в определенную позицию (в отличие от добавления после последнего уже присутствующего элемента).

1
John Bollinger 7 Дек 2020 в 14:12