成长之路---C语言笔记(结构体与共用体)
标签: 成长之路---C语言笔记(结构体与共用体) 博客 51CTO博客
2023-04-14 18:23:59 211浏览
谚云:世上无难事,只畏有心人,有心之人,即立志之坚午也,志坚则不畏事之不成---任弼时
在实际问题中,一组数据往往具有不同的数据类型。显然不能用一个数组来存放这一组数据,为了整体存放这些类型不同的相关数据,C语言允许用户自定义的数据类型包括结构体类型、共用体类型和枚举类型,其中结构体和共用体属于构造类型,枚举型属于简单类型。
结构体
C语言中给出了一种构造数据类型——结构(struct)或叫结构体, 它相当于其他高级语言中的记录。结构体是一种构造类型, 它由若干数据项组成,组成结构体的各个数据项被称为结构体成员,每一个成员可以是一个基本数据类型或者一个构造类型。结构体既然是一种“构造”而成的数据类型,那么在说明和使用之前必须先根据实际情况定义结构体类型,然后再定义结构体类型变量,如同在说明和调用函数之前要先定义函数一样。
结构体类型的定义
因为结构体类型比较复杂系统无法事先为用户定义一种统一的结构体类型因此在我们定义结构体变量之前,用户要先定义结构体类型,即用自己定义的结构体类型定义结构体变量。在定义结构体类型过程中我们应该指明该结构体的类型名,包含哪些成员,各成员及其数据类型。
struct 结构体名
{
成员列表;
};//末尾的分号一定要加分号
结构体名用作结构体类型的标志,又被称作"结构体标志(Structure Tag)".成员列表由诺诺干个成员组成,每个成员都是该结构体的一个组成部分,每个成员都是该结构体的一个组成部分,对每个成员也必须作类型说明。
struct 结构体类型名
{
类型说明符 成员1;
类型说明符 成员2;
类型说明符 成员3;
};
注:
- struet 是关键字,必须原样写出,表示定义一个结构体类型,它是语句的主体。
- 结构体名、成员名的命名规则与标识符的定义规则一样。大括号内是结构体成员列表,各结构体成员的定义方式和一般变量的定义方式相同。
- 结构体类型的定义是一个语句, 应以分号结束。注意,“}”后面的分号一定不能省略,否则会出错。
- 结构体类型的定义只说明了该类型的构成形式,系统并不为其分配内存空间,编译系统仅给变量分配内存空间。
- 结构体成员的类型也可以是另一个结构体类型(嵌套使用)遵循先定义后使用原则。
- ”struct 结构体类型名” 为结构体的类型说明符, 可用于定义或说明变量。 结构体类型的定义可置于函数内,这样该类型名的作用域仅为该函数。如果结构体类型的定义位于函数之外,则其定义为全局的,可在整个程序中使用。
- 结构体是一种复杂的数据类型,是数目固定、类型不同的变量在内存中的分配模式,并没有分配实际的内存空间。当定义了结构体类型的变量之后,系统才能在内存中为变量分配存储空间。因此,结构体类型定义是为结构体变量的定义服务的。
结构体变量的定义
结构体类型反映的是所处理对象的抽象特征,如要描述具体对象时,就需要定义结构体类型的变量,简称为结构体变量或结构体。定义结构体变量有三种方法。
定义类型后再定义变量
/*结构体类型名 变量1,变量2,...变量n;*/
例如:
struct stu
{
int b;
char c;
};
struct stu a;
定义结构体类型的同时定义结构体变量
/*struct 结构体名
{
成员列表;
}变量名列表;*/
//例如:
struct stu
{
int b;
int c;
}a,d;
直接定义结构体变量
/*struct
{
成员列表;
}变量名列表;*/
//例如:
struct
{
int a;
char b;
}a,b;
注:此方法没有具体指出结构体类型名,所以在程序中仅有-处需 要定义某种结构体类型变量时可使用,该方法与前两种方法的区别在于,第三种方法省去了结构体类型名,而直接给出结构体变量,这种情况下不能使用前两种方法对变量进行定义,只能在构造类型的时候定义变量。
结构体变量的引用
在程序中使用结构体变量时,要对每个单元格进行引用,即不能把它作为个整体来使用。除了允许具有相同类型的结构体变量相互赋值以外,一般对结构体变量的使用,包括赋值、输入、输出、运算等都是通过结构体变量的成员来实现的。
结构体变量名.成员名
在之前的学习中我们了解过运算符“.”(成员运算符),其优先级最高,结合方向从左向右。
如果成员本身是一个结构体变量,则必须逐级找到最低级的成员才能使用,即只能对最低级的成员进行赋值或存取以及运算。成员可以在程序中单独使用,与普通变量完全相同。 其中,“.”运算符的优先级别最高,所以可以把“结构体变量名成员名”看作一个整体。如果a、b是同类型变量, 则对于各自的同名成员 num,也可用a.num、 b.num来区分。对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定进行的运算)
可以引用结构体变量成员的地址,也可以引用结构体变量的地址。结构体变量的地址的主要用作函数参数,传递结构体变量的地址。
结构体变量的赋值
已知结构体变量的值,在定义结构体变量时可以给它的成员赋初值,这就是结构体的初始化,它包括定义结构体变量时赋初值和定义结构体变量后赋初值。
定义结构体变量时赋初值 和其他类型变量一样,对于结构体变量可以在定义时进行初始化赋值。对结构体变量赋初值的格式为:
struct结构体类型名变量名={成员1的值,成员2的值,..成员n的值};
初值表用“{}”括起来,表中各个数据以逗号分隔,并且应与结构体类型定义时的成员个数相等,类型一致。如果初值个数少于结构体成员个数,则给无初值对应的成员赋予0值;如果初值个数多于结构体成员个数时,则编译出错。当结构体具有嵌套结构时,内层结构体的初值也需用“{}”括起来。案例:
#include <stdio.h>
int main()
{
struct stu
{
int num;
char name[20];
char sex;
float score;
}a = { 1001, "Zhang", 'M',78.5 };
/*定义结构体变量并初始化*/
struct stu b = { 1002,"Wang", 'F',67.5 };
printf("NO.=%d\tName= =%s\tsex=%c\tscore=%5.2f\n", a.num, a.name, a.sex, a.score);
/*输出结构体a的值*/
printf("NO.=%d\tName= -%s\tsex=%c\tscore- =%5.2f", b.num, b.name, b.sex, b.score);
/*输出结构体b的值*/
}

定义结构体后赋初值
#include<stdio.h>
#include<string.h>
struct stu
{
int num;
char name[20];
char sex;
float score;
}a;
void main()
{
struct stu b;
a.num = 601001;
printf("输入姓名: ");
fgets(a.name,10,stdin);
a.sex = 'M';
a.score - 76.5;
b = a;
/* 将结构体变量a赋值给结构体变量b */
printf("No.=%d\tName=%s\tsex=%c\tscore=%5.2f\n", a.num, a.name, a.sex, a.score);
printf("No.=%d\tName=%s\tsex=%c\tscore-%5.2f\n", b.num, b.name, b.sex, b.score);
}

注:对于结构体变量各个成员不能一次性全部赋值,但是对于同类型的结构体变量之间可以整体赋值一次。
共用体
为了节省内存空间,我们可以把不同用途的数据存放在同一个存储区域,这种数据类型称为共用体类型,也称为联合体类型(union)。构成共用体变量的各成员项的数据类型可以是相同的,也可以是不同的。共用体类型和共用体变量的定义方式与结构体的定义方法类似,也需要先构造共用体类型,后定义共用体变量。共用体成员的引用也与结构体成员的引用方法类似。二者主要区别在于对成员项的存储方式。
共用体的定义
我们可以先定义共用体类型,然后用已定义的共用体类型定义共用体变量;也可以把共用体类型和共用体变量放在一个语句中一次定义。
union {成员列表;};
注:和结构体类型定义一样,在没有定义共用体变量之前,共用体类型定义只是说明了共用体变量使用的内存模式,并没有分配具体的存储空间。 括号后的分号是不可缺少的。这与结构体类型定义是类似的,凡说明为共用体类型num的变量都由上述两个成员组成。
共用体类型变量的定义
与结构体类型变量的定义相似,共用体类型变量的定义也有三种形式。
union mun
{
char b;
int c;
}a;
注::结构体类型的变量所占空间为各个成员项所占空间的总和,而共用体类型的变量所占空间是以最大长度成员项所占空间的大小为准。
共用体类型变量的引用
共用体变量名.成员名
诺引用共用体成员,则a.x即是共用体类型变量a的成员x的值,a.y即是共用体类型变量a的成员y的值。
共用体类型变量的初始化
union 共用体类型名 共用体变量名={初始值};
union num a={45};
使用例子
#include<stdio.h>
union num
{
short x;float y;
};
int main()
{
union num a;
printf("输入x: \n");
scanf("%d", &a.x);
printf("a.x=%d\n", a.x);
printf("输入y: \n");
scanf("%f", &a.y);
printf("a.y=%f\n", a.y);
printf("a.x=%d\n", a.x);
}

今日题目
输⼊两个⾮负 10 进制整数 A 和 B (≤230−1),输出 A+B 的 D (1<D≤10)进制数 输⼊: m n f (解释:f是进制数) 123 456 8 输出: 1103
答案及解题思路见下方,欢迎讨论。
最后的话 :如果大家觉得这篇文章对你们有帮助的话希望你们能够点点关注,你们的关注是我继续写下去的动力,谢谢大家。

(文章中图片与部分内容来源与网络,如有侵权请联系删除)
答案及解析
思路:先求和,然后一直取余就行了。最后倒着输出
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int number_a = 0, number_b = 0, number_c = 0, sum = 0, count = 0;
int p[100] = { 0 };
scanf("%d %d %d", &number_a, &number_b, &number_c);
sum = number_a + number_b;//求和
while (sum) {
p[count++] = sum % number_c;//取余
sum = sum / number_c;
}
for (int i = count - 1;i >= 0;i--) {//倒着输出
printf("%d", p[i]);
}
if (count == 0) printf("0");//如果sum为0输出0
return 0;
}
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论



