기술나눔

C 언어 - 구조

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

1. 구조 정의 및 사용

1.1 개요

이전에 본 int, float, char 등과 같은 데이터 유형은 단순히 프로그램에서 사용됩니다. 필요에 따라 복잡한 데이터를 생성하려면 구조를 사용해야 합니다.

예를 들어, 학생의 학번, 이름, 성별, 나이 등이 동일한 학생에 속하지만 이러한 변수는 서로 다른 유형에 속하지만 단순히 정의하기 위해 서로 다른 변수를 사용하는 경우에는 이들 간의 관계를 반영하기 어렵습니다. . 내부 연결. 그런 다음 이러한 데이터를 결합할 수 있는 변수를 만들어 변수에 넣으므로 사용하기가 훨씬 간단해집니다.

  1. 结构体类型:
  2.         struct Student
  3.         {
  4.               int num;//学号为整形;
  5.               char name[20];//姓名为字符串;
  6.               char sex;//性别为字符型;
  7.               int age;//年龄为整形
  8.               float score;//成绩为浮点型
  9. char addr[30];//地址为字符型;
  10. }

안에:

struct Student는 구조 유형입니다.

struct는 구조체 유형을 선언하는 키워드입니다.

Student는 다른 구조와 구별하기 위해 구조의 이름입니다.

중괄호에는 구조의 구성원이 포함되어 있으며 그룹을 구성원 목록이라고 하며 해당 이름은 변수 이름과 일치합니다.

참고: 구조 유형에는 struct Student;

구조체의 멤버는 다른 구조체의 형식일 수도 있습니다.

구조 날짜

{        

int 월;

국제 일;

년도;

};

구조체 학생

{

정수 번호;

char 이름[20];

숯 섹스;

국제 연령;

구조체 날짜 생일;

문자 주소[30];

}

1.2 구조변수의 정의

이전에는 모델과 동등한 구조 유형만 정의했으며 변수는 정의하지 않았습니다. 다음으로 구조 변수를 정의하고 여기에 특정 데이터를 저장합니다.

방법 1: 먼저 구조 유형을 선언한 후 구조 변수를 정의합니다.

이전 구조 유형인 struct Student를 기반으로 구조 변수를 정의합니다.

구조체 학생 student1, student2;

이 방법은 int a,b와 유사합니다. 유일한 전제 조건은 이미 구조 유형이 있고 구조 변수가 유형에 따라 정의된다는 것입니다.

    방법 2: 유형을 선언하는 동안 변수 정의

형태:

구조체 구조체 이름

                {

회원 목록;

}변수 이름 목록;

예:

구조체 학생
                {
정수 번호;
char 이름[20];
숯 섹스;
국제 연령;
부동 소수점수;
문자 주소[30];
}학생1,학생2;

      방법 3: 유형 이름을 지정하지 않고 구조 유형 변수를 직접 정의

형태:

구조

                        {

멤버 변수;

}변수 이름 목록;

이름이 지정되지 않은 구조 유형이며 일반적으로 사용되지 않습니다.

참고: 1. 구조 변수의 멤버 이름은 프로그램의 변수 이름과 동일할 수 있습니다.

2. 구조 변수의 구성원은 단독으로 사용될 수 있으며 그 상태와 기능은 일반 변수와 동일합니다.

1.3 구조체 변수의 초기화 및 참조

정의할 때 구조 변수를 초기화합니다.

      예:학생 정보(학번, 이름, 성별, 주소 포함)를 구조체 변수에 넣어 학생 정보를 출력한다.

  1. #include <stdio.h>
  2. int main()
  3. {
  4. struct Student
  5. {
  6. int num;
  7. char name[20];
  8. char sex;
  9. char addr[20];
  10. }student1 = {101,"Li li",'M',"123XiAn"};
  11. printf("NO:%d,nname:%snssex:%cnaddress:%sn",student1.num,student1.name,student1.sex,student1.addr);
  12. return 0;

결과 분석:

구조 변수를 정의할 때 초기화 목록은 중괄호로 묶인 상수의 수입니다. 참고: 이는 구조 변수의 초기화가 아닙니다. 구조. 신체 유형 초기화.

구조 변수의 멤버 값, 참조 방법은 다음과 같습니다.

구조체 변수명.멤버명

학생1.이름

      다른 구조 유형에 속하는 구조 멤버의 경우 가장 낮은 수준의 멤버를 수준별로 찾아야 합니다. 예를 들어 위에 언급된 구조체 Student에는 구조체 Date birthday가 포함되어 있습니다.

학생 생일.월

동일한 유형의 구조를 서로 할당할 수 있습니다.학생1=학생2;

        예:두 학생의 학생번호, 이름, 학년을 입력하고, 성적이 높은 학생의 학생번호, 이름, 학년을 출력한다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5. struct Student
  6. {
  7. int num;
  8. char name[20];
  9. float score;
  10. }student1,student2;
  11. scanf("%d%s%f", &student1.num, student1.name, &student1.score);
  12. scanf("%d%s%f", &student2.num, student2.name, &student2.score);
  13. printf("The higher score is:n");
  14. if (student1.score > student2.score)
  15. {
  16. printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
  17. }
  18. else if (student1.score < student2.score)
  19. {
  20. printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
  21. }
  22. else
  23. {
  24. printf("%d %s %6.2fn", student1.num, student1.name, student1.score);
  25. printf("%d %s %6.2fn", student2.num, student2.name, student2.score);
  26. }
  27. }

scanf 함수를 사용하여 구조체 변수를 입력하는 경우에는 별도로 입력해야 하며, scanf 함수에서 구조체 변수 이름을 사용하여 모든 멤버의 값을 한꺼번에 입력할 수는 없습니다. 주의할 점은 scanf 함수 앞에 &가 없습니다. 배열 이름은 원래 주소를 나타냈기 때문에 Student1.name입니다.

2. 구조 배열 사용

2.1 구조체 배열 정의

앞서 구조변수를 정의할 때에는 하나씩 정의했지만, 연산에 참여해야 하는 관련 데이터의 집합이라면 당연히 학생 10명의 정보 등의 데이터를 사용해야 한다. 은 구조 배열입니다. 구조 배열의 각 배열 요소는 구조입니다.

예를 들어, 세 명의 후보자가 있고 각 유권자는 한 사람에게만 투표할 수 있습니다. 먼저 후보자의 이름을 입력하고 마지막으로 각 사람의 투표 결과를 표시하는 프로그램을 작성해야 합니다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Person
  5. {
  6. char name[20];
  7. int count;
  8. }leader[3] = { "wang", 0, "zhang", 0, "li", 0 };
  9. int main()
  10. {
  11. int i, j;
  12. char lead_name[20];
  13. for (i = 0; i < 10; i++)
  14. {
  15. scanf("%s", lead_name);
  16. for (j = 0; j < 3; j++)
  17. {
  18. if (strcmp(lead_name, leader[j].name) == 0)
  19. leader[j].count++;
  20. }
  21. }
  22. printf("nResultn");
  23. for (i = 0; i < 3; i++)
  24. {
  25. printf("name:%s,count:%dn", leader[i].name, leader[i].count);
  26. }
  27. return 0;
  28. }

구조체형 배열의 일반 형식을 정의합니다.

        구조체 구조체 이름

        {

변수 목록

} 배열 이름 [배열 길이];

또는

먼저 struct Student와 같은 구조 유형을 선언한 다음 구조 배열을 정의합니다.

        구조 유형 배열 이름 [배열 길이];

구조체 배열을 초기화하는 형식은 정의 뒤에 다음을 추가하는 것입니다.

      ={초기값 목록};     

2.2 구조체 배열 사용하기

        예:n명의 학생에 대한 정보(학번, 이름, 학년 포함)가 있으며, 각 학생의 정보를 학년순으로 출력해야 합니다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. int num;
  7. char name[20];
  8. float score;
  9. };
  10. int main()
  11. {
  12. struct Student stu[5] = { 1001, "Wangwei", 98.25, 1002, "Liuliu", 91, 1003, "Zhangli", 98, 1004, "Xiaozhao", 85, 1005, "Baibai", 94 };
  13. struct Student temp;
  14. printf("The order id:n");
  15. int i, j,k;
  16. for (i = 0; i < 4; i++)
  17. {
  18. k = i;
  19. for (j = i + 1; j < 5; j++)
  20. {
  21. if (stu[j].score>stu[k].score)
  22. {
  23. k = j;
  24. }
  25. }
  26. temp = stu[k];
  27. stu[k] = stu[i];
  28. stu[i] = temp;
  29. }
  30. for (i = 0; i < 5; i++)
  31. {
  32. printf("%d %s %5.2f", stu[i].num, stu[i].name, stu[i].score);
  33. printf("n");
  34. }
  35. return 0;
  36. }

3. 구조 포인터

3.1 구조 변수에 대한 포인터

소위 구조 포인터는 구조 변수에 대한 포인터입니다. 구조 변수의 시작 주소는 구조 변수의 포인터입니다.

구조 개체를 가리키는 포인터 변수는 구조 변수 또는 구조 배열의 요소를 가리킬 수 있습니다. 포인터 변수의 기본 유형은 구조 변수의 유형과 동일해야 합니다.

예: struct Student * pt;

예:구조체 변수를 가리키는 포인터 변수를 통해 구조체 변수의 멤버 정보를 출력한다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. long num;
  7. char name[20];
  8. char sex;
  9. float score;
  10. };
  11. int main()
  12. {
  13. struct Student stu1;
  14. struct Student *pt;
  15. pt = &stu1;
  16. stu1.num = 10001;
  17. strcpy(stu1.name, "Lili");
  18. stu1.sex = 'M';
  19. stu1.score = 96.5;
  20. printf("No:%dnname:%snsex:%cnscore:%5.1fn", stu1.num, stu1.name, stu1.sex, stu1.score);
  21. printf("n");
  22. printf("No:%dnname:%snsex:%cnscore:%5.1fn", (*pt).num, (*pt).name, (*pt).sex, (*pt).score);
  23. printf("n");
  24. printf("No:%dnname:%snsex:%cnscore:%5.1fn", pt->num, pt->name, pt->sex, pt->score);
  25. return 0;
  26. }

결과 분석:

함수에서 첫 번째 printf 함수는 구조 변수 이름 stu1을 통해 멤버에 액세스합니다.

두 번째 printf 함수는 구조 변수를 가리키는 포인터 변수를 통해 해당 멤버에 액세스합니다. (*pt)는 가리키는 구조 변수를 나타내고 (*pt).num은 가리키는 구조 멤버를 나타냅니다.

또한 C 언어에서는 (*pt).num을 pt-&gt;num으로 바꾸는 것이 허용됩니다.

3.2 구조체 배열에 대한 포인터

포인터 변수는 구조체 배열의 요소를 가리키는 데 사용할 수 있습니다.

예:구조체 배열에는 3명의 학생 정보가 있으며, 해당 학생의 정보를 출력해야 합니다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. struct Student
  5. {
  6. long num;
  7. char name[20];
  8. char sex;
  9. float score;
  10. };
  11. int main()
  12. {
  13. struct Student stu[3] = { 1001, "wangle", 'M', 95, 1002, "chengcai", 'M', 99.9, 1003, "shangmin", 'F', 85.2 };
  14. struct Student *pt;
  15. printf("No. name sex scoren");
  16. for (pt = stu; pt < stu + 3; pt++)
  17. {
  18. printf("%d %s %c %5.2fn", pt->num, pt->name, pt->sex, pt->score);
  19. }
  20. return 0;
  21. }

프로그램에서 pt는 구조체의 특정 멤버가 아닌 구조체 변수를 가리키는 데 사용됩니다. pt=stu[1].name은 불법입니다. 구조 변수이고 다른 하나는 구조 멤버 변수입니다. p++, p 값은 구조의 길이를 증가시킵니다.

3.3 구조 변수와 구조 변수에 대한 포인터를 함수 매개변수로 사용

구조 변수의 값을 함수에 전달하는 방법에는 세 가지가 있습니다.

1. 구조 변수의 멤버를 매개변수로 사용합니다. 이 방법은 일반 변수를 전달하는 것과 동일합니다. 형식 매개변수와 실제 매개변수(구조 멤버)는 동일한 유형입니다.

2. 구조변수를 실제 매개변수로 사용합니다. 구조변수가 실제 매개변수로 사용되는 경우에는 구조변수가 차지하는 메모리 단위의 모든 내용이 형식 매개변수에도 전달됩니다.

3. 구조변수(배열)에 대한 포인터를 실제 매개변수로 사용하여 구조변수(배열)의 주소를 형식 매개변수에 전달합니다.

예:

학생의 학생번호, 이름, 3개 과목 성적을 포함하는 n개의 구조가 있으며, 평균 성적이 가장 높은 학생의 정보(학생증, 이름, 3개 과목 성적, 평균 성적 포함)를 출력해야 합니다. .

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <string.h>
  4. void print(struct Student stud);
  5. struct Student Max(struct Student stu[]);
  6. void input(struct Student stu[]);
  7. struct Student
  8. {
  9. int num;
  10. char name[20];
  11. float score[3];
  12. float aver;
  13. };
  14. int main()
  15. {
  16. struct Student stu[3], *pt;
  17. pt = stu;
  18. input(pt);
  19. print(Max(pt));
  20. return 0;
  21. }
  22. void input(struct Student stu[])
  23. {
  24. int i;
  25. printf("请输入各学生的信息:学号、姓名、3门成绩:n");
  26. for (i = 0; i < 3;i++)
  27. {
  28. scanf("%d%s%f%f%f", &stu[i].num, stu[i].name, &stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
  29. stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3.0;
  30. }
  31. }
  32. struct Student Max(struct Student stu[])
  33. {
  34. int i, m = 0;
  35. for (i = 0; i < 3; i++)
  36. {
  37. if (stu[i].aver > stu[m].aver)
  38. m = i;
  39. }
  40. return stu[m];
  41. }
  42. void print(struct Student stud)
  43. {
  44. printf("成绩最好的学生是:n");
  45. printf("学号:%d 姓名:%s 三门课程:%5.2f %5.2f %5.2f平均成绩:%5.2fn", stud.num, stud.name, stud.score[0], stud.score[1], stud.score[2], stud.aver);
  46. }

1. 입력 함수를 호출할 때 실제 매개변수는 포인터 변수 pt이고 형식 매개변수는 구조 배열입니다. 전달되는 것은 구조 요소의 시작 주소이며 함수에는 반환 값이 없습니다.

2. Max 함수를 호출할 때 실제 매개변수는 포인터 변수 pt, 형식 매개변수는 구조체 배열, 구조체 요소의 시작 주소가 전달되고 함수 반환 값은 구조체 유형 데이터입니다.

3. print 함수를 호출할 때 실제 매개변수는 구조체 변수(구조배열 요소)이고, 형식 매개변수는 구조체 변수이다. 전달되는 것은 구조체 변수의 각 멤버의 값이며, 함수에는 반환값이 없다.

4. 연결리스트

4.1 개요

연결리스트(Linked List)는 일반적인 데이터 구조로, 동적 저장소 할당을 위한 구조입니다.

데이터를 배열로 저장할 때 배열 길이(다중 배열)를 미리 정의해야 합니다. 어떤 학급에는 100명의 학생이 있고 어떤 학급에는 30명의 학생이 있는 경우, 동일한 배열을 사용하여 다른 학급의 학생들의 데이터를 저장하는 경우 길이가 100인 배열을 정의해야 하지만 이로 인해 리소스가 낭비되는 경우가 많습니다. 연결 목록에는 필요에 따라 메모리 단위가 열립니다.

연결된 목록에는 그림에서 head로 표시되는 "헤드 포인터" 변수가 있으며, 이 변수는 요소를 가리키는 주소를 저장합니다. 연결된 목록의 각 요소는 "노드"라고 하며 각 노드는 두 부분을 포함해야 합니다.

1. 사용자가 요구하는 실제 데이터

2. 다음 요소의 주소

메모리 내 연결리스트의 각 요소의 주소가 불연속적일 수 있음을 알 수 있는데, 특정 요소를 찾으려면 먼저 이전 요소를 찾아야 하고, 이전 요소의 주소를 기준으로 다음 요소를 찾을 수 있다. . "헤드 포인터"가 제공되지 않으면 전체 연결 목록에 액세스할 수 없습니다.

이 경우 구조를 사용하여 연결 목록을 작성하는 것이 가장 적합합니다. 구조에는 여러 멤버가 포함되며 포인터 유형 멤버는 다음 노드의 주소를 저장하는 데 사용됩니다.

구조체 학생

        {

정수 번호;

int 점수;

구조체 학생 *다음;

        }

그 중 num과 Score는 사용자 데이터를 저장하는 데 사용되고 next는 다음 노드의 주소를 저장하는 데 사용됩니다.

4.2 정적 연결리스트

사례:

세 명의 학생 데이터가 포함된 노드로 구성된 정적 연결 목록을 생성하고 각 노드의 데이터가 출력되도록 합니다.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. struct Student
  4. {
  5. int num;
  6. float score;
  7. struct Student * next;
  8. };
  9. int main()
  10. {
  11. struct Student a, b, c, *head, *p;
  12. a.num = 1001; a.score = 85.5;
  13. b.num = 1002; b.score = 95.5;
  14. c.num = 1003; c.score = 84.5;
  15. head = &a;
  16. a.next = &b;
  17. b.next = &c;
  18. c.next = NULL;
  19. p = head;
  20. do
  21. {
  22. printf("%d %5.2fn", p->num, p->score);
  23. p = p->next;
  24. } while (p != NULL);
  25. return 0;
  26. }

예를 들어, 헤드가 노드 a를 가리키고, a.next가 노드 b를 가리키고, b.next가 노드 c를 가리키고, c.next가 null을 가리키도록 연결된 목록을 만듭니다. 이렇게 하면 연결된 목록 관계가 형성됩니다.

연결리스트를 출력할 때 먼저 p를 사용하고 p가 a를 가리키도록 한 다음 a에 데이터를 출력해야 합니다. p=p-&gt;next는 출력을 위한 다음 노드를 준비하는 것입니다.

4.3 동적 연결리스트

4.3.1 동적 메모리 할당

동적 연결 목록에 대해 이야기하기 전에 먼저 동적 메모리 할당에 대해 소개하겠습니다.

앞에서 변수는 전역변수와 지역변수로 나누어진다고 했는데, 비정적으로 저장되는 지역변수는 동적저장영역에 할당된다. 이 저장 영역을 메모리라고 합니다.스택

또한 C 언어에서는 일부 임시 데이터를 저장하기 위한 동적 메모리 할당 영역을 설정할 수 있습니다. 이러한 데이터는 필요할 때 열리고 필요하지 않을 때 해제됩니다. 이 데이터를 특수한 저장 영역이라고 합니다.더미

메모리의 동적 할당은 시스템에서 제공하는 기능인 malloc, calloc, free 및 realloc 기능을 통해 이루어집니다.

1. malloc 기능을 사용하여 동적 저장 영역을 엽니다.

기능: void *malloc(부호 없는 int 크기);

기능:

        메모리의 동적 저장 영역에 길이 크기(단위:바이트)의 연속적인 공간을 할당합니다.

반환 값:

첫 번째 할당된 바이트의 주소는 유형이 없으며 단지 일반 주소입니다.

2. calloc 함수를 사용하여 동적 저장 영역을 엽니다.

기능:void * calloc(부호 없는 n,부호 없는 크기);

기능:

메모리의 동적 저장 영역에 크기의 길이로 n바이트의 연속 공간을 할당합니다. 이 공간은 배열을 저장할 수 있을 만큼 상대적으로 큽니다.

1차원 배열에 대한 동적 저장 공간을 열려면 calloc 함수를 사용합니다. n은 배열 요소의 수이고 크기는 요소의 길이입니다.

반환 값:

첫 번째 할당된 바이트의 주소는 유형이 없으며 단지 일반 주소입니다.

3. realloc 기능을 사용하여 동적 저장 영역을 재할당합니다.

기능:void * realloc(void *p ,unsigned int 크기);

기능:

할당된 동적 메모리를 재할당합니다.

p가 가리키는 동적 공간의 크기를 size로 변경하려면 recallloc 함수를 사용하십시오. p의 값은 변경되지 않고 유지됩니다.

반환 값:

업데이트 후 동적 메모리의 첫 번째 바이트 주소는 기본적으로 p가 가리키는 주소입니다.

4. 무료 기능을 사용하여 동적 저장 영역을 해제하세요.

기능: void 해제(void *p);

기능:

포인터 변수 p가 가리키는 동적 공간을 해제하여 공간의 이 부분을 다른 변수에서 사용할 수 있도록 합니다.

p는 malloc 및 calloc 함수에 대한 최신 호출에서 얻은 반환 값입니다.

반환 값:

없음;

메모: 위 네 가지 함수의 선언은 모두 stdlib.h 헤더 파일에 있습니다.

무효 포인터 유형:

위 함수 malloc 함수와 calloc 함수의 반환 값은 모두 void * 유형이므로 어떤 유형의 데이터를 가리키는 것이 아니라 빈 유형을 가리키는 것으로 이해됩니다. 또는 특정 유형의 데이터를 가리키지 않습니다.

동적 메모리를 호출할 때 프로그램은 함수가 가져온 순수 주소만 사용하고, 이 주소를 사용하려면 변환해야 하는 데이터 유형을 가리키는 속성을 사용하지 않습니다.

예를 들어:

int *p;

p=(int*)malloc(100);

사례:

동적 데이터를 생성하고 학생 5명의 점수를 입력한 후, 60점 미만의 학생이 있는지 확인하는 함수를 이용하여 부적격 점수를 출력하는 단계;

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. int main()
  5. {
  6. void check(int * p);
  7. int *p1, i;
  8. p1 = (int *)malloc(5 * sizeof(int));
  9. for (i = 0; i < 5; i++)
  10. {
  11. scanf("%d", p1 + i);
  12. }
  13. check(p1);
  14. return 0;
  15. }
  16. void check(int * p)
  17. {
  18. int i;
  19. printf("they are fail:n");
  20. for (i = 0; i < 5; i++)
  21. {
  22. if (*(p+i) < 60)
  23. printf("%d ", *(p + i));
  24. }
  25. }

작업 결과:

결과 분석:

프로그램에는 배열이 정의되어 있지 않지만 배열로 사용하기 위해 동적 자유 할당 영역이 열립니다.

malloc 함수에서는 동적 공간을 할당하기 위해 특정 값을 직접 전달하지 않고 대신 sizeof를 사용하여 시스템 정수의 바이트 수를 계산한 다음 5개의 요소를 생성합니다. p를 사용하여 첫 번째 바이트 주소를 가리키고 이를 int 유형으로 변환하고, p+1은 다음 요소를 가리킵니다.

4.3.2 동적 연결 리스트 생성

4명의 학생에 대한 데이터가 포함된 동적 연결 목록을 만드는 함수를 작성하세요.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define LEN sizeof(struct Student)
  5. struct Student
  6. {
  7. long num;
  8. float score;
  9. struct Student * next;
  10. };
  11. int n;
  12. struct Student * creat(void)
  13. {
  14. struct Student * head, *p1, *p2;
  15. n = 0; p1 = p2 = malloc(LEN);
  16. scanf("%ld%f", &p1->num, &p1->score);
  17. head = NULL;
  18. while (p1->num != 0)
  19. {
  20. n = n + 1;
  21. if (n == 1)
  22. head = p1;
  23. else p2->next = p1;
  24. p2 = p1;
  25. p1 = (struct Student *)malloc(LEN);
  26. scanf("%ld%f", &p1->num, &p1->score);
  27. }
  28. p2->next = NULL;
  29. return (head);
  30. }
  31. int main()
  32. {
  33. struct Student * pt;
  34. pt = creat();
  35. printf("n num:%ld score:%5.2fn", pt->num, pt->score);
  36. return 0;
  37. }

작업 결과:

결과 분석: 동적 연결 리스트를 생성하려면 먼저 3개의 구조체 포인터를 지정한 다음, malloc 함수를 사용하여 노드를 생성하고, 3개의 구조체 포인터가 모두 이 노드를 가리키고, p1이 malloc 함수를 사용하여 노드를 생성하고, p2는 다음을 수행합니다. p1은 p2=p1을 가리킨 후 p2를 만듭니다. 다음은 p1의 요소 값이 0이 될 때까지 p2=p1을 가리킵니다. p2의 다음은 p2를 가리키지 않습니다. 새로 생성된 노드는 NULL을 가리킵니다. 이렇게 하면 헤드가 첫 번째 노드를 가리키며 이것이 헤드 노드가 됩니다.

동적 연결 리스트의 입력 및 출력:

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #define LEN sizeof(struct Student)
  5. struct Student
  6. {
  7. long num;
  8. float score;
  9. struct Student * next;
  10. };
  11. int n;
  12. struct Student * creat(void)
  13. {
  14. struct Student * head, *p1, *p2;
  15. head = NULL;
  16. n = 0;
  17. p2 = p1 = malloc(LEN);
  18. scanf("%ld%f", &p1->num, &p1->score);
  19. while (p1->num != 0)
  20. {
  21. n = n + 1;
  22. if (n == 1)
  23. head = p1;
  24. else
  25. p2->next = p1;
  26. p2 = p1;
  27. p1 = malloc(LEN);
  28. scanf("%ld %f", &p1->num, &p1->score);
  29. }
  30. p2->next = NULL;
  31. return head;
  32. }
  33. void print(struct Student * p)
  34. {
  35. do
  36. {
  37. printf("%ld %5.2fn", p->num ,p->score);
  38. p=p->next;
  39. } while (p->num != NULL);
  40. }
  41. int main(void)
  42. {
  43. struct Student * pt;
  44. pt = creat();
  45. print(pt);
  46. return 0;
  47. }

작업 결과:

5. 유니온형

5.1 개요

때로는 서로 다른 유형의 변수를 메모리 단위에 저장하려고 합니다. 예를 들어, 동일한 주소에서 시작하는 메모리 단위에 정수 변수, 문자 변수 및 부동 소수점 변수를 배치하면 여러 변수가 동일한 메모리 단위를 공유할 수 있습니다. . 메모리 구조의 한 부분을 "결합"이라고 합니다.

공용체의 일반적인 형태를 정의합니다.

노동조합 이름

        {

회원 목록;

}변수 목록;

예를 들어:

유니온 데이터

        {

안녕하세요.

문자 ch;

플로트 f;

}알파벳;

구조체 변수가 차지하는 메모리 길이는 각 멤버가 차지하는 메모리 길이의 합이며, 공용 구조체가 차지하는 메모리 길이는 가장 긴 멤버의 길이입니다.

5.2 인용문

미리 정의된 Union 변수만 참조할 수 있습니다. 여기서는 Union 변수를 참조하는 것이 아니라 참조되는 Union 변수의 멤버를 참조합니다.

ai는 공용체 변수의 정수 변수를 나타냅니다.

a.ch는 공용체 변수의 문자 변수를 나타냅니다.

af는 공용체 변수의 실제 변수를 나타냅니다.

5.3 특징

1. 메모리 세그먼트는 여러 가지 유형의 구성원을 저장하는 데 사용할 수 있지만 동시에 여러 유형이 아닌 각 순간에 하나만 저장할 수 있습니다.

2. 유니온 변수는 초기화가 가능하지만, 초기화 테이블에는 상수가 하나만 있을 수 있습니다.

3. 공용체 변수의 멤버는 지난번에 할당한 멤버로 이전 원래 변수를 덮어쓰고 교체합니다.

4. 공용체 변수의 주소는 해당 멤버의 주소와 동일합니다.

5. 통합 변수 이름에 값을 할당할 수 없으며 값을 얻기 위해 변수 이름을 참조하려고 시도할 수도 없습니다.

6. 열거형

일부 변수에 가능한 값이 몇 개만 있는 경우 열거형으로 정의할 수 있습니다. 소위 열거형은 가능한 값을 하나씩 나열하는 것입니다.

예를 들어 열거형 선언은 enum으로 시작합니다.

eunm 주중{일,월,화,수,목,금,토};

위의 내용은 열거형 enum Weekday를 선언합니다. 그런 다음 이 유형을 사용하여 변수를 정의할 수 있습니다.

enum 주중 근무일, 주말;

그 중 근무일과 주말을 열거변수로 정의하고, 중괄호를 열거요소 또는 열거상수라고 부른다.

열거형 선언의 일반적인 형식은 다음과 같습니다.

enum [열거 이름] {열거 요소 목록};

예:

주머니에는 빨간색, 노란색, 파란색, 흰색, 검은색 등 5가지 종류의 공이 있습니다. 매번 가방에서 3개의 공을 꺼내서 서로 다른 색상의 공 3개를 가져와 배열하세요.

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <stdio.h>
  3. int main()
  4. {
  5. enum Color {red,yellow,bule,white,black};
  6. enum Color i, j, k, pri;
  7. int n, loop;
  8. n = 0;
  9. for (i = red; i <= black; i++)
  10. for (j = red; j <= black; j++)
  11. if (i != j)
  12. {
  13. for (k = red; k <= black; k++)
  14. if ((k != i) && (k != j))
  15. {
  16. n++;
  17. printf("%d ", n);
  18. for (loop = 1; loop <= 3; loop++)
  19. {
  20. switch (loop)
  21. {
  22. case 1:pri = i; break;
  23. case 2:pri = j; break;
  24. case 3:pri = k; break;
  25. default:break;
  26. }
  27. switch (pri)
  28. {
  29. case red:printf("%s ", "red"); break;
  30. case yellow:printf("%s ", "yellow"); break;
  31. case bule:printf("%s ", "bule"); break;
  32. case white:printf("%s ", "white"); break;
  33. case black:printf("%s ", "black"); break;
  34. default:break;
  35. }
  36. }
  37. printf("n");
  38. }
  39. }
  40. printf("n total:%dn", n);
  41. return 0;
  42. }

작업 결과:

7. typedef를 사용하여 새로운 유형 이름을 선언하세요.

기존 유형 이름을 대체할 새 유형 이름을 지정하려면 typedef를 사용하십시오.

1. 원래 유형 이름을 새 유형 이름으로 바꾸면 됩니다.

예를 들어:

typedef int 정수;

typedef float 실수;

따라서 다음 두 줄은 동일합니다.

int i,j;——— 정수 i,j;

2. 복잡한 유형 표현 방법 대신 간단한 유형 이름을 지정하십시오.

  구조 유형을 나타내는 새 유형 이름을 지정합니다.

typedef 구조체

        {

영어: int 문;

                ......

} 데이터;

그런 다음 새 유형 이름인 Data를 사용하여 변수를 정의합니다.

데이터 생일;

데이터 * p;

      배열 유형 대신 새 유형 이름을 지정합니다.

typedef int Num[100];

숫자 a;

      포인터 유형을 나타내는 새 유형 이름을 지정하십시오.

typedef char * 문자열;

문자열 p,a[10];

      함수에 대한 포인터를 나타내기 위해 새 유형 이름을 지정합니다.

typedef int (*포인터)();

포인터 p1,p2;

           요약: 변수 정의 방법에 따라 변수 이름을 새로운 유형 이름으로 바꾸고, 앞에 typedef를 추가하여 새 유형 이름이 원래 유형을 나타냄을 선언합니다.

typetef는 기존 유형에 대한 새 유형 이름만 지정하고 새 유형을 생성하지는 않습니다.

typetef와 #define은 표면적으로 유사점이 있습니다.

typedef int 개수

#define Count int

해당 기능은 int 대신 Count를 사용하는 것이지만 실제로는 다릅니다. #define은 사전 컴파일에서 처리되며 간단한 문자열 교체로만 사용할 수 있는 반면 typedef는 컴파일 단계에서 처리됩니다. 사실 단순한 교체는 아닙니다. 대신 새 유형 이름이 생성되고 변수가 정의됩니다.