2013-08-11 2 views
1

Я пытаюсь понять концепцию массивов структур и придумал проблему. Надеюсь, вы можете мне помочь.Как использовать переменную массива внутри массива структур?

Итак, проблема, с которой я столкнулась, - это как объявить и использовать (т. Е. Принимать значения &) переменной массива в массиве структур?

Этот пример кода может визуально помочь вам понять мою проблему:

#include<stdio.h> 

struct node{ 

    int roll; 
    char name[10]; 
    int grades[5]; // Accepts 5 grades for each student 
}; 

int main() 
{ 
    struct node student[3]; 

    /*Accept and display values for structure members here*/ 

    return 0; 
} 

Я знаю, что есть подобный пример here.

Но я не понимаю, линия 4 в main() секции принято отвечать, где память выделяется с помощью malloc():

list[ip].inputs[inp]= (char*)malloc(25);

Я путаюсь между 25 байтов, выделенных здесь, и 10, определенный в char* inputs[10];

Что именно происходит здесь? И как вы решаете проблему, о которой я говорил выше?

ответ

2

В приведенном примере есть дополнительный код *. malloc необходим только из-за этого, в вашем примере inputs представляет собой массив из 10 указателей на char, а здесь name является буферным буфером 10 char s. Вам не нужен malloc в вашем коде.

Ваша структура выглядит в памяти (при условии, 4-байт int ы):

enter image description here

Ваш student массив из main выглядит следующим образом:

enter image description here

Как вы видите, поля выкладываются один за другим. Таким образом, чтобы прочитать имя первого ученика, вы должны записать его в student[0].name (используя strncpy, чтобы не было переполнения). Чтобы изменить третью букву имени второго ученика, вы будете использовать student[1].name[2].

+0

Я думаю, вы его немного поняли. Я вообще не имею в виду массив символов ** **. И знаете ли вы решение моей проблемы? (Переменная массива внутри массива структуры. – ash9209

+0

Я обновил ответ. Надеюсь, вы поймете сейчас. –

+0

Идеальная визуализация @MihaiMaruseac. Brilliant – ash9209

1

Вы можете безопасно использовать его как это:

strcpy(student[1].name, "Yu Hao"); 
student[1].grades[1] = 95; 

printf("student 1 name: %s\n", student[1].name); 
printf("student1 grades1:%d\n", student[1].grades[1]); 

Пример вы связаны использует malloc потому что struct имеет некоторые указатели и указатели должны указывать где-то действительный перед использованием. Это не так в вашем примере.

Обратите внимание, что использование strcpy может привести к катастрофе, если вы скопируете строку длиной более 10, если это необходимо, вместо этого используйте strncpy.

+0

Понял это отлично. – ash9209

+0

О, кстати, я вспомнил, когда вы использовали ** strcpy **, что мы не можем выделять строку массиву символов, непосредственно как ** str = «Yu Hao»; ** Существует ли альтернативное решение следующим образом: *** str = «Yu Hao»; ** – ash9209

+0

Нет, там это не так. Кроме того, использование 'strcpy' подвержено катастрофе. Подумайте о' strcpy (student [0] .name "Очень большая строка, которая не относится к имени [10] array") ' –

0

Чтобы ответить на вопрос, связанный с указанным сообщением.

Во-первых, надеюсь, что у вас есть базовые знания о указателях в C. Указатель действительно является адресом памяти для краткости. Подробнее Я рекомендую вам буклет this (очень отличное представление о массивах и пуаров). В этом разделе кодов, inputs определяется как char* inputs[10];. Это массив указателей. Итак, каждый элюмент в этом массиве должен быть адресом. Аргумент 25 в сообщении malloc не требуется (вы также можете указать 40 или 50 в соответствии с вашими требованиями). Единственное, что вы должны гарантировать, это то, что каждый элемент в массиве является адресом (это то, что возвращает malloc). 10 определяет размер массива, то есть вы можете хранить 10 адреса в общей сложности в inputs или сказать, вы можете инициализировать массив, вызвав malloc десять раз, как:

struct a; 
for (int i = 0; i < 10; i++) { 
    a.inputs[i] = (char *) malloc(25); 
} 

Вернуться к вашей собственной проблеме. В вашем случае символ name определяет адрес для хранения. Вам не нужно новое хранилище malloc.

+0

Не могли бы вы рассказать о части ** malloc (25) **? Вы сказали **, вы также можете указать 40 или 50 для удовлетворения ваших требований **. Нам нужно сохранить 10 адресов в ** входах **. Хорошо, я понимаю. Я до сих пор не понимаю, как на картинке 25. Когда мое мышление ведет меня, оно выделяет 25 байт каждому адресу в массиве ** input **. Верный? если нет, то где я иду не так? – ash9209

+0

@ пепел9209 OK. Как я уже сказал, указатель - это адрес памяти. Это адрес для основной памяти. В то время как мы знаем, как массив, чтобы читать кусок памяти, нам нужно не только знать его начальный адрес, но и его размер (или у нас закончится память и доступ к недействительному адресу, я уверен, вы знаете, что при доступе к массиву мы не должны устранять эльмы вне границы: p). Вот. 20, 40, даже 50 - это размер памяти, который вы хотите * использовать * в байте. Фактический размер определяется вами самостоятельно. Если вам нужен 50-байтовый блок памяти, np, 'malloc (50)' даже 5000-байтовый 'malloc (5000)'. –

+0

Хорошо, это было намного лучше. Получил это отлично. Цените, что вы даете мне свое драгоценное время. Приветствия. – ash9209