C语言自定义数据类型
- 格式:doc
- 大小:39.50 KB
- 文档页数:6
C语言结构体二维数组什么是结构体?在C语言中,结构体是一种用户自定义的数据类型,用于表示一组相关的数据。
它允许我们将不同类型的变量组合在一起,形成一个新的复合数据类型。
结构体可以包含不同类型的成员变量,这些成员变量可以同时被访问和操作。
使用结构体可以更好地组织和管理复杂的数据,提高代码的可读性和可维护性。
二维数组二维数组是指由多个一维数组组成的数据结构。
在C语言中,我们可以使用二维数组来表示表格、矩阵等具有行列关系的数据。
二维数组实际上是一个由多个一维数组按照顺序排列而成的连续内存空间。
通过指定行和列索引,我们可以访问和操作二维数组中的元素。
结构体与二维数组的组合应用结构体与二维数组可以相互嵌套使用,在某些情况下能够更好地满足我们对数据的需求。
定义结构体首先,我们需要定义一个结构体来表示具有行列关系的数据。
以矩阵为例:struct Matrix {int rows; // 行数int cols; // 列数int data[100][100]; // 数据};在上面的例子中,我们定义了一个名为Matrix的结构体,它包含了三个成员变量:rows、cols和data。
其中,rows表示矩阵的行数,cols表示矩阵的列数,而data[100][100]则是一个二维数组,用于存储矩阵的具体数据。
初始化结构体接下来,我们可以使用结构体来创建具有特定行列关系的二维数组。
例如:struct Matrix mat;mat.rows = 3;mat.cols = 4;// 初始化二维数组for (int i = 0; i < mat.rows; i++) {for (int j = 0; j < mat.cols; j++) {mat.data[i][j] = i * mat.cols + j;}}在上面的例子中,我们创建了一个名为mat的结构体变量,并初始化了它的行数和列数。
然后,使用嵌套循环遍历二维数组,并依次赋值。
c语言结构体可变长度数组C语言是一种广泛应用于系统软件开发和嵌入式系统领域的编程语言,其强大的灵活性和高效的执行速度使得它成为了众多开发者的首选。
在C语言中,结构体是一种用来封装不同类型的数据的自定义数据类型。
在C语言中,结构体可以包含多个成员变量,这些成员变量可以是不同的数据类型,如整型、浮点型、字符型等。
除了这些基本数据类型外,结构体还可以包含一个可变长度的数组,这为程序员提供了更大的灵活性和功能性。
结构体的可变长度数组在实际的软件开发中有着广泛的应用。
比如,在编写一个学生管理系统时,可以使用结构体的可变长度数组来存储学生的信息。
这样一来,无论学生的数量有多少,都可以通过动态分配内存来存储这些信息,从而实现对学生数据的高效管理和操作。
为了更好地理解结构体的可变长度数组,我们来看一个具体的例子。
假设我们需要编写一个程序,用来存储学生的成绩信息。
每个学生有一个学号、姓名和多门课程的成绩。
我们可以使用结构体的可变长度数组来存储这些信息。
我们定义一个学生的结构体,包含学号、姓名和一个可变长度的成绩数组。
```struct Student {int id;char name[20];float scores[];};```接下来,我们需要动态分配内存来存储学生的信息。
假设我们有5个学生,他们的成绩分别为75.5、80.0、90.5、85.0和95.0。
我们可以使用malloc函数来动态分配内存,并使用指针来访问结构体的成员变量。
```int main() {int num_students = 5;struct Student *students = (struct Student *)malloc(num_students * sizeof(struct Student));students[0].id = 1;strncpy(students[0].name, "Tom", sizeof(students[0].name)); students[0].scores[0] = 75.5;students[1].id = 2;strncpy(students[1].name, "Jerry", sizeof(students[1].name)); students[1].scores[0] = 80.0;students[1].scores[1] = 85.0;// 依此类推...free(students);return 0;}```通过上述代码,我们可以看到,我们可以根据需要给每个学生的成绩数组分配不同的长度。
C语言结构体构造函数简介在C语言中,结构体(struct)是一种自定义的数据类型,用于将不同类型的变量组合在一起形成一个新的复合数据类型。
结构体构造函数是一种用于创建并初始化结构体变量的方法,类似于其他面向对象编程语言中的构造函数,用于为结构体变量分配内存空间并初始化其成员变量。
本文将详细介绍C语言中结构体构造函数的概念、使用方法以及注意事项。
结构体构造函数的定义和作用结构体构造函数是一种特殊的函数,用于创建并初始化结构体变量。
它的作用是方便地为结构体变量分配内存空间并初始化其成员变量,避免手动分配内存和逐个初始化成员变量的繁琐过程。
结构体构造函数的定义与普通函数类似,但其函数名与结构体类型相同,没有返回类型,并在函数体内部完成了分配内存和初始化成员变量的过程。
例如:typedef struct {int age;char name[20];} Person;Person createPerson(int age, const char* name) {Person p;p.age = age;strcpy(, name);return p;}在上述代码中,createPerson函数是一个结构体构造函数,用于创建并初始化Person类型的结构体变量。
它接受两个参数,分别是年龄和姓名,将这些值分别赋给p的成员变量age和name,最后返回创建好的结构体变量p。
使用结构体构造函数创建结构体变量使用结构体构造函数创建结构体变量非常简单,只需要调用结构体构造函数并传入相应参数即可。
以下是使用上述createPerson函数创建Person类型结构体变量的示例:Person person1 = createPerson(25, "Tom");在上述示例中,createPerson函数被调用并传入了25和”Tom”作为参数,返回的结构体变量被赋给了person1。
结构体构造函数的优点结构体构造函数的引入使得创建和初始化结构体变量变得更加便捷和可读,具有以下几个优点:1.简化代码:使用结构体构造函数可以避免手动分配内存和逐个初始化成员变量的繁琐过程,减少了代码的冗余,提高了代码的可读性和可维护性。
c语言struck的用法
在C语言中,结构体(struct)是一种用户自定义的数据类型,
它可以包含不同类型的成员变量(也称为字段)。
结构体的定义通常在函数外部,而结构体的声明可以在函数内部或外部。
以下是一个包含姓名和年龄两个字段的示例结构体的定义:
```
struct Person {
char name[50];
int age;
};
```
结构体类型的变量可以通过使用结构体的定义来声明。
例如:
```
struct Person p1; // 声明一个名为p1的Person类型的变量
```
结构体的成员变量可以通过`结构体名.成员名`的方式进行访问。
例如:
```
strcpy(, "John"); // 赋值姓名
p1.age = 25; // 赋值年龄
```
通过结构体变量访问成员变量时要使用点(.)运算符。
结构体也可以作为函数的参数进行传递,可以返回结构体作为函数的返回值。
结构体还可以嵌套使用,即在结构体中包含另一个结构体作为成员变量。
可以使用typedef关键字来为结构体定义别名,以便更方便地使用。
以上是C语言中结构体的基本用法,更多关于结构体的用法和细节可以参考C语言的相关书籍或在线资料。
C语言中type定义方法及数组应用一、type的定义方法1. 在C语言中,type是一种用户自定义的数据类型,通过type定义可以使代码更简洁、易读,结构更清晰。
2. C语言中type定义可以使用typedef关键字,其基本语法如下: typedef 原类型名新类型名;其中,原类型名可以是基本数据类型(int、float、char等)或者已经定义过的自定义类型,新类型名是用户根据需要自定义的名称。
3. 举例说明:定义一个新的类型Score,代表学生成绩的数据类型。
typedef int Score;表示将int类型重命名为Score,以便在程序中使用Score来代表学生成绩。
二、数组的定义和应用1. 在C语言中,数组是一种非常重要的数据结构,它可以存储多个相同类型的数据,通过下标来访问数组中的元素。
2. 数组的定义方法如下:元素类型数组名[数组大小];其中,元素类型是数组中存储的数据类型,数组名是用户自定义的数组名称,数组大小是数组中元素的个数。
3. 举例说明:定义一个长度为5的整型数组,用于存储5个学生的成绩。
int scores[5];表示定义了一个名为scores的数组,可以存储5个整型数据。
三、type与数组的结合应用1. 通过type的定义方法,可以将数组等复杂数据类型进行简化,提高代码可读性和维护性。
2. 举例说明:定义一个类型为int的AliasScore,用来简化int数组类型ScoreArray的使用。
typedef int AliasScore[5];表示将int[5]类型的数组重命名为AliasScore。
3. 使用示例:AliasScore studentScores;表示定义了一个名为studentScores的AliasScore类型数组,可以存储5个学生成绩。
四、总结通过type的定义方法,可以简化数组等复杂数据类型的使用,提高代码编写的效率和可读性。
在实际编程中,合理使用type和数组结合,可以使代码的结构更加清晰,易于理解和维护。
c语言结构体申请空间C语言结构体申请空间是指在编写C程序时,创建一个结构体类型的变量时,需要在内存中分配足够的空间来存储这个结构体的数据。
结构体是C语言中一种自定义的数据类型,它由多个不同的数据类型组合而成。
在本篇文章中,我们将详细介绍C语言中如何通过动态内存分配来申请结构体空间,并在代码中一步一步地解释相关概念和操作。
1. 了解结构体概念在开始介绍结构体申请空间之前,我们需要先了解结构体的概念。
结构体是一种由不同数据类型的变量组合而成的自定义数据类型。
通过结构体,我们可以将不同类型的数据组合到一个新的数据结构中,从而更方便地表示和处理相关数据。
结构体由一个或多个数据成员组成,每个数据成员可以是不同的数据类型,例如整型、字符型、浮点型等。
通过定义结构体,我们可以在内存中预留一片连续的空间,用于存储结构体中各个数据成员的值。
下面是一个定义包含姓名、年龄和性别的结构体的示例代码:cstruct Person {char name[20];int age;char gender;};2. 静态内存分配静态内存分配是C语言中最简单的一种申请结构体空间的方式,也被称为自动变量。
在C语言中,当我们定义一个结构体类型的变量时,编译器会自动为其分配内存空间。
下面是一个使用静态内存分配的示例代码:c#include <stdio.h>struct Person {char name[20];int age;char gender;};int main() {struct Person person;printf("请输入姓名:");scanf("s", );printf("请输入年龄:");scanf("d", &person.age);printf("请输入性别:");scanf(" c", &person.gender);printf("姓名:s\n", );printf("年龄:d\n", person.age);printf("性别:c\n", person.gender);return 0;}在上面的代码中,我们定义了一个结构体类型的变量`person`,并通过`scanf`函数从用户输入中获取其姓名、年龄和性别。
第7章自定义数据类型习题一.选择题:1.当定义一个结构体变量时,系统分配给它的内存空间是【】。
A) 结构中一个成员所需的内存量 B) 结构中最后一个成员所需的内存量 C) 结构体中占内存量最大者所需的容量 D) 结构体中各成员所需内存量的总和2.若有以下说明,对初值中整数2的正确引用方式是【】。
static struct{char ch;int i;double x;} a[2][3]={{‘a’,1,3 .45,’b’,2,,’c’,3,}{‘d’,4,,’e’,5,,’f’,6, }};A) a[1][1].i B) a[0][1].i C) a[0][0].i D) a[0][2].i3.根据以下定义,能打印字母M的语句是【】。
struct p{char name[9];int age;}c[10]={“Jobn”,17,”Paul”,19,”Mary”,18,”Adam”,16};A) printf(“%c”,c[3].name); B) printf(“%c”,c[3].name[1]);C) printf(“%c”,c[2].name); D) printf(“%c”,c[2].name[0]);4.以下说明和语句中,已知int型数据占两个字节,则以下语句的输出结果是【】。
struct st{char a[l0];int b;double c;};printf(“%d”,sizeof(struct st));A) 0 B) 8 C) 20 D) 25.以下说明和语句中,对结构体变量std中成员id的引用方式不正确的是【】。
struct work{int id;int name;} std, *p;p=&std;A) B) * C) (*p).id D) &6.如设有如下定义,若要使px指向rec中的成员x,正确的赋值语句是【】。
struct aa{int x;float y;}rec, *px;A) *px=;B) px=&C) px=(struct aa*);D) px=(struct aa*)&;7.下列程序的输出结果是【】。
c语言结构体的定义一、引言结构体是C语言中非常重要的数据类型之一,它可以用来组织不同类型的数据,方便程序员进行管理和操作。
在本文中,我们将详细介绍C语言结构体的定义。
二、结构体的概念结构体是一种用户自定义的数据类型,它可以包含多个不同类型的变量,并且这些变量可以按照任意顺序排列。
结构体是由程序员自己定义的,它不同于C语言中已经存在的基本数据类型。
三、结构体的定义在C语言中,定义一个结构体需要使用关键字struct,并且需要为该结构体指定一个名称。
具体格式如下:struct 结构体名称 {变量类型1 变量名1;变量类型2 变量名2;...变量类型n 变量名n;};其中,- 结构体名称:指定了该结构体的名称,可以根据需要自行命名。
- 变量类型:指定了每个变量所属的数据类型。
- 变量名:指定了每个变量所使用的名称。
四、示例代码下面是一个简单的示例代码,演示了如何定义一个包含姓名、年龄和性别三个变量的结构体:struct Person {char name[20];int age;char sex;};在上面这个示例代码中,- 结构体名称为Person。
- 变量类型包括char和int。
- 变量名为name、age和sex。
五、结构体的使用定义了一个结构体之后,我们可以使用该结构体来声明变量,并且可以对这些变量进行赋值和访问。
具体代码如下:struct Person {char name[20];int age;char sex;};int main() {struct Person p1 = {"Tom", 18, 'M'};printf("name: %s, age: %d, sex: %c\n", , p1.age,p1.sex);return 0;}在上面这个示例代码中,我们首先定义了一个名为Person的结构体,然后在main函数中声明了一个名为p1的变量,并且对其进行了初始化。
c语言结构体数组动态分配在C语言中,结构体是一种自定义的数据类型,可以将不同类型的数据组合在一起,形成一个结构体变量。
结构体数组是多个结构体变量的集合,可以用于存储和处理多个具有相似属性的数据。
动态分配结构体数组是指在程序运行时,根据需要动态地分配内存空间来存储结构体数组。
这种方式相对于静态分配,可以灵活地处理不同规模的数据,并且减少内存的浪费。
动态分配结构体数组的步骤可以分为以下几个部分:1.定义结构体类型:首先,需要定义一个结构体类型,包含所需的字段。
例如,我们可以定义一个学生结构体,包含学号、姓名和成绩等字段。
2.用户输入数量:在动态分配结构体数组时,需要用户输入所需的结构体数量。
可以通过scanf函数等方式,获取用户输入的数值。
3.分配内存空间:使用malloc函数来分配内存空间,用于存储结构体数组。
需要根据用户输入的数量和每个结构体的大小来计算所需的总内存大小,并调用malloc函数进行分配。
4.初始化结构体数组:分配完内存后,需要将结构体数组的每个元素进行初始化。
可以通过循环遍历结构体数组,并使用赋值操作符“=”来为每个字段赋初值。
5.使用结构体数组:处理完每个结构体的初始化后,就可以对结构体数组进行各种操作了。
可以通过循环遍历结构体数组,并使用结构体的字段进行读写操作。
6.释放内存空间:在程序结束时,需要释放掉动态分配的内存空间,避免内存泄漏。
可以使用free函数来释放内存。
动态分配结构体数组的优点是可以动态地处理不同规模的数据,减少内存的浪费。
而静态分配的结构体数组在编译时就需要确定大小,不能灵活地处理不同规模的数据。
需要注意的是,在动态分配内存空间后,一定要记得在使用完结构体数组后及时释放内存,以防止内存泄漏的问题。
同时,在使用结构体数组时,应该注意数组下标的边界问题,避免数组越界访问。
总结起来,动态分配结构体数组是一种灵活、高效的方式,可以根据需要动态地分配内存空间来存储结构体数组。
自定义数据类型结构体结构体是程序员在程序中自定义的一种数据类型,在说明和使用之前必须先定义它,也就是构造它。
定义一个结构体的语法格式如下:Struct 结构体类型名{成员1的数据类型名成员1名称;成员2的数据类型名成员2名称;..成员n的数据类型名成员n名称;}结构体变量表={成员初始化};注意成员可以由若干个不同的数据类型组成,每个成员也可以是结构体,即可以嵌套定义。
例如:Struct student{Long num;Char name;Char sex;Float score;};已经定义的某种结构体类型可以视为一种标准的数据类型,它的使用方法与标准数据类型使用方法相同,可以用来定义变量、数组、指针。
结构体变量说明结构体变量的说明在程序的变量说明部分给出,一般在结构定义之后,它的语法格式如下:Struct 结构类型名结构变量名表;例如:Struct student stu;指出了结构变量stu是student类型的变量,它由四个成员组成,每个成员的数据类型和名字都与student结构定义中给出的相同。
系统完全按照结构定义时制定的内存模式为结构变量分配内存空间。
可以在定义结构体类型的同时给出结构体变量。
Struct student{Long num;Cha name[20];Cha sex;Float score;}stu1,stu2;这种形式与前面给出的结构定义和结构说明分开处理效果相同。
结构体成员访问结构体成员是通过结构体变量名和成员名进行访问的,不能把他作为一个整体进行访问。
其访问格式如下:结构体变量名.成员名其中运算符.是成员访问运算符,其运算级别是最高的,和圆括号运算符()、下标运算符[]是同一级别的。
如果结构体成员是指针变量,则访问格式为:*如果某个结构体变量的成员数据类型又是一个结构体,则访问方式为:外层结构体变量名.外层成员名.内层成员名可以在定义结构体变量的同时对结构体变量初始化。
{结构体成员}结构体变量={初始数据};struct student{long num;char name[20];char sex;float score;} stu1={200401L,"ZhangHong",'f',92.5f};对于嵌套的结构体类型数据,访问格式为:结构体变量名1.结构体变量名2.成员名结构体变量初始化的格式如下:struct 结构体名{结构体成员}结构体变量={初始数据};初始数据类型必须与结构成员的数据类型相匹配,并且先后顺序一一对应赋值。
要对结构体变量的成员地址进行访问,其语法格式为:&结构体变量.成员名当一个指针变量用来指向一个结构变量时,称为结构体指针变量。
结构体指针变量中的值是所指向的结构体变量的首地址。
结构体指针变量:Struct 结构名*结构体指针变量名Struct student *pstu;必须先赋值后使用,把结构体变量的首地址赋给指针变量,不能把结构名或结构体变量名赋给指针变量。
pstu=&stu1;结构体名和结构体变量是两个不同的概念,结构体名只能表示一个结构形式,编译系统并不对它分配内存空间,只有当某变量被说明为这种类型的结构时,才对该变量分配存储空间。
这是因为结构体变量被定义后相当于标准数据类型被使用。
利用结构体指针变量访问成员如下:(*结构体指针变量).成员名或者:结构体指针变量->成员名后一种形式较为方便,容易区分。
三种访问结构体成员的方式:结构变量。
成员名(*结构指针变量)。
成员名结构指针变量->成员名结构体与数组相同结构的结构体变量组成的数组,简称结构数组。
Struct student{Long num;Char name[20];Char sex;Struct birthday bir;Float score;}students[35];上面定义了一个结构数组students,共35个元素,students[0]~students[34]。
每个数组元素都具有struct student的结构形式,用来描述一个学生的相关信息。
结构数组名students表示该数组存储的首地址。
结构数组在说明的同时也可以对它进行初始化赋值。
语法格式如下:Struct 结构体名结构数组名[数组长度]={初始数据};与其他数组一样,结构体数组的元素也可以用指针来引用。
但指针应说明为数组元素类型的指针,并将数组名或者数组的第0个元素的地址赋给指针变量。
引用上述结构体数组students元素的指针变量说明如下:Struct student *p=students;或者Struct student *p=&students[0];则p为指向结构数组的指针变量,且p指向该结构数组的0号元素,p+1指向1号元素,p+i指向第i号元素。
(*p).num或p->num表示引用students[0].num(*++p).num或(++p)->num表示引用students[1].numC语言中规定,定义某个结构体时,其成员的类型可以是该结构体本身,但是这个成员只能是指针变量或指针数组,不能使普通变量或数组。
结构体与函数结构体作为函数的参数可以采用三种方式进行传递:将结构体成员作为单独的参数传递给函数;将整个结构体变量作为参数传递给函数;将指向结构体的指针作为参数传递给函数。
链表动态分配内存空间的函数:第一个内存管理函数是非配内存空间函数malloc(类型说明符*)malloc(size);其功能是分配一块长度为size字节的连续内存区域。
函数的返回值为该区域的首地址。
“类型说明符”说明把该区域用于何种类型的指针。
(类型说明符*)表示把返回值强制转换为该类型指针。
Pc=(char*)malloc(100);表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。
第二个内存管理函数为calloc(类型说明符*)calloc(n,size);表示一次分配n块区域。
Ps=(struct student *)calloc(2,sizeof(struct student));第三个内存管理函数为释放内存空间函数free。
Free(void*ptr)其作用是释放ptr所指向的一块内存空间,ptr是任意类型的指针变量,它指向被释放区域的首地址。
被释放的区域应该是malloc或calloc函数所分配的区域。
每一次分配一块空间可用来存放一个学生的信息,可称之为一个结点。
有多少个学生就分配多少块内存空间,也就是建立多个结点。
将若干个结点按一定的原则连接起来的一组数据称之为链表。
链表中的结点之间的联系可以用指针实现。
即在节点结构中定义一个成员用来存放下一个结点的首地址,这个用于存放地址的成员常称之为指针域。
为了确定链表中的第一个结点,需要设置一个指向第一个结点的头指针。
然后依次在第一个结点的指针域内存入第二个结点的首地址,依此类推,最后一个结点因无后续结点连接,其指针域可赋NULL。
链表中的每一个结点都是同一种结构类型。
数据结点定义的语法格式如下:Struct <结点名>{<数据类型名> <变量表>;<结点名> *<结点指针名>;};联合体语法与结构体很相似,但却有不同。
联合体几个成员共享同一个位置开始的存储区,这些成员并不同时存在,而是在不同时刻拥有不同的成员,在同一时刻仅拥有其中一个成员。
因此,联合体变量的存储空间只要保证能存放其中任何一个成员就可以了。
联合体成员的数据类型可以是任何数据类型,联合体在定义、变量说明和使用形式上均与结构体相似,两者本质上的不同仅在于使用内存的方式上。
Union 联合体名{成员1数据类型成员1名;成员2数据类型成员2名;...成员n数据类型成员n名;}联合体变量表={成员初始化};联合体变量说明:Union data ua,ub,uc,*pu,*d[20];上面说明了date联合类型的联合变量ua,ub,uc,联合指针*pu和联合数组d。
联合体成员访问由于联合的各个成员使用相同的开始内存区域,所以联合占用的内存空间在某个时刻只能保证某个成员的数据真实有效。
联合体与结构体的区别(1)从存储结构上来看,结构变量所占的内存长度是每个成员所占的内存长度之和。
每个成员分别占有自己独立的内存单元。
而联合变量所占的内存长度等于最长的成员的长度。
(2)在初始化时,结构体初始化与一维数组类似,而联合只能对第一个成员初始化。
(3)从成员的地址看,结构体各成员的地址互不相同,只有第一个成员的地址与结构变量地址相同(类型不同),联合体所有成员的地址相同,都等于联合变量的地址。
(4)从使用上看,结构体中所有成员可以分别赋值、同时存在、互不影响。
而联合体中通过给某成员赋值,该成员覆盖其他成员,使联合体中始终只能正确保存一个成员的值。
枚举类型enum 枚举类型名{枚举常量表};常量表中的每个常量都是一个标识符。
Enum weekday {SUN,MON,YUE,WED,THU,FRI,SAT};枚举常量不是变量,不能在程序中用赋值语句对它赋值。
但可以在定义枚举类型时对它赋初值。
定义枚举类型时系统自动给每个枚举常量分配一个表示序号的整数值,默认第一个值为0,以后每个标识符的值依次比前面的增加1,。
可以通过赋初值来改变默认值,从赋值以后的标识符开始忍然依次加1。
枚举常量是一个标识符,不是字符常量也不是字符串常量,使用时不要加单引号或双引号。
标准类型别名定义允许程序员为数据类型取别名,这主要是为了便于程序的移植及简化程序书写格式。
Typedef 原类型名新类型名;Type int INTEGER;以后就可以用INTEGER来代替int作整形变量的类型说明了。
但long INTEGER i;这样的定义是错误的,它不像宏定义中的宏名那样作简单的字符串替换。
同样typedef也可以用于定义数组,指针,结构等类型。
Typedef char STRING[20];表示STRING是字符数组类型,长度为20。
STRING a1,a2;等价于:Char a1[20],a2[20];又如:Typedef struct student{Long num;Char name[20];Char sex;Float score;}STU;然后可以用STU来说明结构变量。