2013-08-11 3 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 메모리가 malloc()를 사용하여 할당 허용 대답의 main() 섹션에서 :

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

나는 25 여기에 할당 된 바이트와 사이에 혼란스러워지고 있어요 10에 정의 된 char* inputs[10];

여기서 정확히 무엇이 일어나고 있습니까? 그리고 위에서 언급 한 문제를 어떻게 해결할 수 있습니까?

답변

2

견적을 작성한 예에는 *이 추가로 있습니다. malloc이 필요하기 때문에 예를 들어 inputschar에 대한 10 개의 포인터 배열이고 여기에서 name은 1을 보유하는 버퍼입니다. 코드에 malloc이 필요하지 않습니다.

귀하의 구조가 메모리에 다음과 같습니다 (4 바이트 int의 가정) :

main에서 student 배열과 같은 enter image description here

: 보시다시피

enter image description here

, 필드가 하나씩 차례로 배치됩니다. 따라서 첫 번째 학생의 이름을 읽으려면 student[0].name (strncpy을 사용하여 오버플로가 없음)을 작성해야합니다. 두 번째 학생 이름의 세 번째 글자를 바꾸려면 student[1].name[2]을 사용하십시오.

+0

당신이 조금 잘못 이해했다고 생각합니다. 내 ** 이름 ** 문자 배열을 전혀 언급하지 않습니다. 내 문제에 대한 해결책을 알고 있습니까? (구조체 배열 내부의 배열 변수 – ash9209

+0

대답을 업데이트했습니다. 이제는 이해하게 되길 바란다. –

+0

Perfect visualization @MihaiMaruseac. Brilliant. – ash9209

1

안전하게 다음과 같이 사용할 수 있습니다 다음 struct 몇 가지 포인터를 가지고 있으며, 포인터를 사용하기 전에 유효한 곳을 가리 키도록해야하기 때문에 당신이 연결

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를 사용합니다. 귀하의 예에서는 그렇지 않습니다.

strcpy을 사용하면 10보다 긴 문자열을 복사 할 때 재앙이 발생할 수 있습니다. 고려해야 할 경우 strncpy을 대신 사용하십시오.

+0

완벽하게 이해할 수 있습니다. – ash9209

+0

오, 그런데 사용했을 때 기억했습니다. ** strcpy ** ** str = "Yu Hao"와 같은 문자 배열에 문자열을 직접 할당 할 수 없다. ** 이와 같은 대체 솔루션이 있습니까? : *** str = "Yu Hao"; ** – ash9209

+0

아니요, 거기 strcpy (student [0] .name, "이름이 [10] 배열에 들어 가지 않는 매우 큰 문자열)" –

0

추천 된 게시물과 관련된 질문에 답하십시오.

먼저 C에서 포인터에 대한 기본 지식을 가지고 있기를 바랍니다. 포인터는 실제로 짧은 메모리 주소입니다. 자세한 내용은 this 소책자 (어레이 및 포이 너에 대한 매우 훌륭한 소개)를 권합니다. 해당 코드에서 inputschar* inputs[10];으로 정의됩니다. 포인터의 배열입니다. 그래서 배열의 각 항목은 주소 여야합니다. malloc 호출에있는 25 인수는 필요하지 않습니다. 요구 사항을 충족 시키려면 40 또는 50을 지정할 수도 있습니다. 보장해야 할 것은 배열의 각 요소가 주소 (즉, malloc이 반환하는 것)입니다. 10은 배열 차원, 즉 당신처럼 malloc 열 번 호출하여 배열을 초기화 할 수 있습니다, inputs에 총 10 주소를 저장하거나 말할 수 지정 위로

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 바이트를 할당하고 있습니다. 옳은? 그렇지 않다면 어디서 잘못 될까요? – ash9209

+0

@ ash9209 OK. 내가 말했던 것처럼 포인터는 메모리 주소입니다. 기본 메모리 저장소에 대한 주소입니다. 우리가 알기는하지만 배열처럼 메모리의 덩어리를 읽는 것만으로도 시작 주소와 크기를 알아야 할 필요가 없습니다 (또는 메모리가 부족하여 잘못된 주소에 액세스 할 때 배열에 액세스 할 때 우리는 경계에서 elments를 벗어나서는 안된다 : p). 여기 있습니다. 20, 40, 심지어 50은 바이트 단위로 사용하려는 메모리 크기입니다. 실제 크기는 사용자가 직접 결정합니다. 50 바이트 메모리 덩어리를 원한다면, np,'malloc (50)'도 5000 바이트의 malloc (5000)이다. –

+0

좋아, 이것은 훨씬 나아졌다. 완벽하게 얻었습니다. 내게 귀중한 시간을 주신 것을 감사하게 생각하십시오. 건배. – ash9209

관련 문제