기사 디렉토리
프로그램을 설계할 때 가장 중요한 단계 중 하나는 데이터를 표현하는 방법을 선택하는 것입니다. 단순한 변수나 심지어 배열은 많은 경우에 충분하지 않습니다. 이를 위해 C에서는 구조체 변수(structure variable)를 제공하여 데이터를 표현하는 능력을 향상시켜 새로운 형태를 만들 수 있도록 합니다.
1. 구조적 기초
1.1 구조체란?
배열과 마찬가지로 구조체는 여러 구성 요소로 구성되며 배열과 달리 구조체의 멤버는 서로 다른 유형일 수 있으며 구조체의 요소는 멤버 이름으로 액세스할 수 있습니다.
1.2 구조문 만들기
구조 선언은 구조의 조직적 레이아웃을 설명합니다. 선언 구문은 다음과 같습니다.
structure 结构体名 {
数据类型 成员1;
数据类型 成员2;
数据类型 成员3;
...
}
# include <stdio.h>
#define MAXLARGE 20
// 声明一个结构体名为book的结构体
struct book
{
// 定义int类型的BookNum成员
int booknum;
// 定义char类型的Title数组成员,数组最大为MAXLARGE
char title[MAXLARGE];
// 定义char类型的author数组成员,数组最大为MAXLARGE
char author[MAXLARGE];
// 定义double类型的price成员
double price;
};
int main(void){
return 0;
}
이 선언은 int 유형의 변수, char 유형의 두 변수 배열 및 double 유형의 구조로 구성된 구조를 설명합니다. 이 선언은 실제 데이터 개체를 만들지 않고 개체가 무엇으로 구성되어 있는지 설명합니다.
구조체 선언에서 구조체 멤버 목록은 한 쌍의 중괄호로 묶입니다. 각 멤버는 자체 선언으로 설명됩니다. 예: 제목은 MAXLARGE 요소를 포함하는 배열입니다. 멤버는 모든 데이터 유형, 심지어 다른 구조도 될 수 있습니다! 닫는 중괄호 뒤에 세미콜론이 필요하며 구조 레이아웃 정의의 끝을 표시합니다.
구조체 선언은 함수 외부 또는 내부에 배치할 수 있습니다. 함수 내부에 배치되면 함수 사용에 제한이 있는 지역 변수와 같습니다. 외부에 배치하면 선언 이후의 모든 함수를 사용할 수 있습니다.
1.3 구조 변수 정의
구조에는 두 가지 의미가 있습니다. 첫 번째 계층은 구조 레이아웃입니다.구조 레이아웃은 위에서 언급한 바와 같이 컴파일러에게 데이터를 표현하는 방법을 알려주지만 컴파일러가 데이터를 위한 공간을 할당하도록 허용하지는 않습니다. 다음 단계는 구조체에 대한 또 다른 의미 계층인 구조체 변수를 만드는 것입니다.
프로그램에서 구조 변수가 생성됩니다.
// 声明一个结构体名为book的结构体
struct book
{
// 定义int类型的BookNum成员
int booknum;
// 定义char类型的Title数组成员,数组最大为MAXLARGE
char title[MAXLARGE];
// 定义char类型的author数组成员,数组最大为MAXLARGE
char author[MAXLARGE];
// 定义double类型的price成员
double price;
// library表示创建一个book结构体的变量名
} library;
等效于:
struct book library;
컴파일러는 이 코드 라인을 실행하고 구조 변수 라이브러리를 생성합니다. 컴파일러는 책 템플릿을 사용하여 이 변수에 대한 공간을 할당합니다.
구조체를 선언하는 과정과 구조체 변수를 정의하는 과정을 한 단계로 결합할 수 있습니다. 그러면 다음과 같이 표시됩니다.
struct
{
// 定义int类型的BookNum成员
int booknum;
// 定义char类型的Title数组成员,数组最大为MAXLARGE
char title[MAXLARGE];
// 定义char类型的author数组成员,数组最大为MAXLARGE
char author[MAXLARGE];
// 定义double类型的price成员
double price;
} library; // 声明的右花括号后跟变量名
구조체 변수의 선언에서 struct book의 기능은 일반 선언의 int 또는 float와 동일합니다. 예: struct book 유형의 변수 또는 struct book에 대한 포인터를 정의할 수 있습니다.
struct book doyle, panish, *ptbook;
1.4 초기화 구조
구조 변수 초기화는 배열 초기화와 유사한 구문을 사용합니다.
struct book library=
{
100010,
"Tom and Jerry",
"unknow",
10.00
};
1.5 구조체 멤버 접근
그 구조는 슈퍼배열과 유사하며, 이 슈퍼배열에서 하나의 요소는 char형이고 다음 요소는 int형일 수 있으며, 배열에서 첨자를 사용하여 배열의 각 요소에 개별적으로 접근할 수 있다. 구조에서 구조의 구성원에 액세스하려면 구조 구성원 연산자 ------( . )를 사용해야 합니다.
# include <stdio.h>
#define MAXLARGE 20
struct book
{
int booknum; // 定义int类型的BookNum成员
char title[MAXLARGE]; // 定义char类型的Title数组成员,数组最大为MAXLARGE
char author[MAXLARGE]; // 定义char类型的author数组成员,数组最大为MAXLARGE
double price; // 定义double类型的price成员
};
struct book library=
{
100010,
"Tom and Jerry",
"unknow",
10.00
};
int main(void){
// 在主函数中,使用结构体成员操作符访问结构体成员的属性。
printf("%s\n", library.title);
printf("%d", library.booknum);
return 0;
}
1.6 구조체 초기화
C99 및 C11은 구조체에 대한 지정 이니셜라이저를 제공하며 구문은 배열에 대한 지정 이니셜라이저와 유사합니다. 그러나 구조체에 대한 지정 이니셜라이저는 점 표기법과 멤버 이름을 사용하여 특정 요소를 식별합니다.
# include <stdio.h>
#define MAXLARGE 20
struct book
{
int booknum; // 定义int类型的BookNum成员
char title[MAXLARGE]; // 定义char类型的Title数组成员,数组最大为MAXLARGE
char author[MAXLARGE]; // 定义char类型的author数组成员,数组最大为MAXLARGE
double price; // 定义double类型的price成员
};
// 使用C99和C11结构的初始化器初始成员,也可以只初始化部分成员。
struct book ptbook=
{
.booknum=10010,
.title="Tom",
.author="unknow",
.price=12.00
};
int main(void){
printf("%s\n", ptbook.title);
printf("%d", ptbook.booknum);
return 0;
}
둘째, 구조 배열
구조 배열은 기본적으로 배열이며 배열의 각 요소는 구조입니다.
2.1 구조체 배열 선언
구조체 배열 선언은 다른 형식의 배열 선언과 유사합니다. 구조체 배열은 다음과 같이 선언됩니다.
struct book arrayst[MAXARRAY];
위의 코드는 arrayst를 MAXARRAY 요소를 포함하는 배열로 선언합니다. 배열의 각 요소는 책 유형 구조입니다.
배열 이름 arrayat 자체는 구조 이름이 아니라 배열 이름이며 배열의 각 요소는 struct book 유형의 구조 변수입니다.
#include <stdio.h>
#define MAXLARGE 20
struct book
{
int booknum; // 定义int类型的BookNum成员
char title[MAXLARGE]; // 定义char类型的Title数组成员,数组最大为MAXLARGE
char author[MAXLARGE]; // 定义char类型的author数组成员,数组最大为MAXLARGE
double price; // 定义double类型的price成员
};
struct book arrayst[3]={
{
100011, "围城", "钱钟书", 100.00},
{
100012, "西游记", "吴贯中", 102.00},
{
100013, "红楼梦", "曹雪芹", 103.00}
};
int main(void){
printf("%s\n", arrayst[0].title);
printf("%d", arrayst[1].booknum);
return 0;
}
arrayst[1].num은 배열의 두 번째 요소, 즉 두 번째 구조의 num 속성 값에 액세스하는 것을 의미합니다.
3. 중첩 구조
다른 구조체 내에 구조체 포함(예: 중첩 구조체)
예:
#include <stdio.h>
// 第一个结构体
struct names
{
char first_name[20];
char last_name[20];
};
// 第二个结构体
struct friends {
// 嵌套第一个结构体
struct names people;
int age;
char gender;
// 初始化第二个结构体
} info={
{
"Tom", "jerry"},
12,
'm'
};
int main(void){
printf("%s\n", info.people);
printf("%d", info.age);
return 0;
}
구조체 선언 내에서 중첩 구조체가 생성되는 방식에 주목하십시오. int 유형의 변수를 선언하는 것과 같습니다.
struct names people;
이 선언에서 people은 구조체 이름 유형의 변수입니다. 물론 파일에는 구조 이름의 선언도 포함되어야 합니다.
중첩 구조의 멤버에 액세스하려면 도트 연산자를 두 번 사용해야 합니다.
printf("%s\n", info.people.last_name);
넷째, 구조에 대한 포인터
#include <stdio.h>
#define MAXLARGE 20
struct names
{
char first_name[20];
char last_name[20];
};
struct friends {
struct names people;
int age;
char gender;
};
struct friends info[2]={
{
{
"Tom", "jerry"}, 12, 'm'},
{
{
"John", "Tim"}, 11, 'f'}
};
int main(void){
// 声明一个结构指针
struct friends *him;
// 结构指针指向info的第1个元素
him = &info[0];
printf("%s\n", him->people.last_name);
printf("%d", him->age);
return 0;
}
4.1 구조체 포인터 선언 및 초기화
위의 프로그램에서 구조체 포인터를 선언하는 것은 간단합니다.
struct friends *him;
먼저 struct 키워드, 태그 구조 friend, 별표, 포인터 이름 순입니다.
배열과 달리 구조체 변수는 구조체 변수의 주소가 아니므로 구조체 변수 이름 앞에 & 연산자를 추가해야 합니다.
이 선언은 새 구조를 생성하지 않지만 포인터 him은 이제 guy 유형의 기존 구조를 가리킬 수 있습니다. 이 예에서 info는 구조의 배열입니다. 즉, info[0]은 구조이므로 그가 info[0]을 가리키도록 하려면 다음과 같이 작성할 수 있습니다.
him = &info[0];
him은 info[0]을 가리키고, him+1은 info[1]을 가리킵니다.
4.2 포인터로 멤버에 접근하기
위의 프로그램에서 그는 info[0]을 가리키고 연산자 섹션에서 -> 연산자를 사용하여 구조체 포인터 멤버의 값을 얻습니다.
// 获取him指向的成员属性值
printf("%s\n", him->people.last_name);
printf("%d", him->age);
5. 구조 정보를 함수에 전달
ANSI C에서는 구조를 매개변수로 사용할 수 있습니다. 따라서 프로그래머는 구조 자체를 전달할지 아니면 구조에 대한 포인터를 전달할지 선택할 수 있습니다. 구조체의 특정 부분에만 관심이 있는 경우 구조체의 멤버를 매개 변수로 사용할 수도 있습니다. 다음으로 이 세 가지 전달 방법을 분석합니다.
5.1 구조체 멤버 전달
구조체 멤버 전달은 구조체 멤버 속성 값을 함수의 매개변수에 전달하여 함수의 기능을 완성하는 것입니다.
#include <stdio.h>
// 定义结构体
struct funds
{
double balance;
double savefunds;
};
// 定义相加函数
double sum(double x, double y){
return x + y;
}
int main(void){
// 初始化结构体
struct funds per={
1000,
1000
};
//调用函数,函数的参数为结构体的成员属性
printf("The total balance is : %lf", sum(per.balance, per.savefunds));
return 0;
}
5.2 패스 구조 주소
위에서 계속해서 구조체의 주소가 아래 함수에 전달됩니다.
#include <stdio.h>
// 定义结构体
struct funds
{
double balance;
double savefunds;
};
// 定义加法函数。声明形参为结构体地址。形参地址为money
double sum(const struct funds * money){
return (money->balance + money->savefunds) ;
}
int main(void){
// 初始化结构体
struct funds per={
1000,
1000
};
// 将实参结构体地址传入函数。
printf("The total balance is : %lf", sum(&per));
return 0;
}
5.3 패스 구조
함수에 대한 구조 전달을 지원하는 컴파일러는 구조를 매개변수로 전달할 수 있습니다.
#include <stdio.h>
// 定义一个结构体
struct funds
{
double balance;
double savefunds;
};
// 定义相加函数,并将结构体传给函数
double sum(struct funds totalbal){
return (totalbal.balance + totalbal.savefunds) ;
}
int main(void){
// 初始化结构体
struct funds per={
1000,
1000
};
// 将结构体传给函数使用
printf("The total balance is : %lf", sum(per));
return 0;
}
5.4 구조체 및 구조체 포인터 선택
구조체를 전달하는 것과 구조체에 대한 포인터를 전달하는 것은 각각 고유한 장점과 단점이 있습니다. 포인터를 매개변수로 사용하면 주소가 전달되는 한 실행이 빠릅니다. 데이터를 보호할 수 없다는 단점이 있지만 새로운 const 한정자는 이 문제를 해결합니다.
결과를 인수로 갖는 이점은 함수가 원래 데이터를 보존하는 원래 데이터의 복사본에서 작동한다는 것입니다. 단점은 이전 버전에서는 구현하지 못할 수 있으며 구조를 전달하는 것은 시간과 공간의 낭비입니다. 특히 큰 구조를 함수에 전달할 때.
6. 연합
6.1 노동 조합 선언
C 언어에서는 여러 종류의 변수를 같은 메모리 단위에 저장할 수 있습니다.(동시에 저장하지 않음) 일반적인 용도는 불규칙하고 순서를 알 수 없는 혼합된 유형을 저장하도록 테이블을 설계하는 것입니다. 미리. 공용체의 크기가 모두 같고 각 공용체는 다양한 데이터 유형을 저장할 수 있는 공용체 유형의 배열을 사용합니다.
유니온은 구조체와 동일한 방식으로 생성되며 유니온 템플릿과 유니온 변수가 필요합니다. 유니온은 union 키워드로 선언됩니다.
union hold{
int dight;
double big;
char litter;
}
6.2 유니온 사용
다음은 공용체의 몇 가지 용도입니다.
union hold fit;
fit.dight = 10; // 把10存储在fit的dight中
fit.big = 2.1 // 清除10,存储2.0
fit.litter = 'w' // 清除2.0 存储w
도트 연산자는 사용 중인 데이터 유형을 나타냅니다. 공용체에서는 한 번에 하나의 값만 저장할 수 있습니다. 공간이 충분하더라도 char 타입의 값과 int 타입의 값을 동시에 저장할 수는 없습니다. 따라서 코드를 작성할 때 현재 어떤 데이터 유형이 저장되어 있는지 주의하십시오.
포인터를 사용하여 구조체에 액세스하는 것과 동일, 포인터로 공용체에 액세스할 때 -> 연산자 사용
pu = &fit;
int x = pu->dight; // 相当于fit.dight