瘋子C语言笔记(结构体/共用体/枚举篇)
(一)结构体类型
1.简介:
例:
struct date
{
int month;
int day;
int year;
};
struct student
{
int num;
char name[20];
char sex;
int age;
struct date birthday; /*birthday 是 struct date 类型*/
char addr[30];
}student1,student2;
(1):结构体可嵌套
(2):与枚举相比结构体内元素为变量,而枚举为常量
(3):元素只能单个引用:如:student.num; student.birthday.month;
(4):内部元素变量可以与其他变量重名且互不影响;
(5):赋值:student.num = 10010;
2.初始化
(可直接赋值)
struct student
{
long int num;
char name[20];
char sex;
char addr[20];
}a = {10101,"Li Lin","M","BeiJing Road"};
3.结构体数组
struct student
{
int num;
char name[20];
char sex;
int age;
struct date birthday; /*birthday 是 struct date 类型*/
char addr[30];
};
struct student stu[3];
注:数组中每一个元素都是一个结构体类型数据;
4.指向结构体类型数据的指针
struct student
{
int num;
char name[20];
char sex;
int age;
struct date birthday; /*birthday 是 struct date 类型*/
char addr[30];
};
struct student stu_1;
struct student *p;
p = &stu_1;
注:
(1)一个结构体变量的指针就是该变量所占据的内存段的起始地址(开头地址);
(2)(*p).num 等价于 stu_1.num;(*p两端的括号不能省略)
(3)(*p).num 等价于 p->num; (-> 称为指向运算符)
(4)如下运算
p->n; 得到p指向的结构体变量中的成员n的值。
p->n ++;得到p指向的结构体变量中的成员n的值,用完该值后使它加1。
++ p->n;得到p指向的结构体变量中的成员n的值加1,然后再使用它。
-> 运算优先级大于 ++;
5.指向结构体数组元素的指针
struct student
{
int num;
char name[20];
char sex;
int age;
struct date birthday; /*birthday 是 struct date 类型*/
char addr[30];
};
struct student stu[3];
struct student *p;
for( p = stu;p < stu + 3;p ++)
printf( "%5d %-20s %2c %4d\n",p->num,p->name,p->sex,p->age);
注:p是一个指向struct student 类型数据的指针变量,它用来指向一个struct student 类型的数据(及:stu数组的一个元素如stu[0],stu[1],的起始地址),不应用来指向stu数组元素中的某一成员,
p = stu[1].name; 这样的用法是错误的
但是:
强制类型转换后可以用
p = (struct student *)stu[0].name; 这样是正确的;
这样的话:p的值是stu[0]元素的name成员的起始地址。printf(“%s”,p)输出stu[0]中成员name的值。但printf(“%s”,p +1)则输出 stu[1]中name的值。p+1 的值是在p值的基础上加上结构体struct student的字节长度。
因为:p加减运算他的类型就是他的最小运算单元
6.结构体变量做函数参数
注:用结构体变量做函数参数时,采用值传递的方式,将结构体变量所占的内存单元的内容全部顺序传递给形参。
#include<stdio.h>
#include<string.h>
#define FORMAT "%d\n%s\n%f\n%f\n%d\n"
struct student
{
int num;
char name[20];
float score[3];
} ;
void main()
{
void print(struct student);
struct student stu;
stu.num = 12345;
strcpy(stu.name,"Li Li");
stu.score[0] = 67.5;
stu.score[1] = 89;
stu.score[2] = 78.6;
print(stu);
}
void print(struct student stu)
{
printf(FORMAT,stu.num,stu.name,stu.score[0], stu.score[1],stu.score[2]);
printf("\n");
}
运行结果:
12345
Li Li
67.500000
89.000000
78.599998
7.用指针处理链表
例:
#include<stdio.h>
#define NULL 0
struct student
{
long num;
float score;
struct student *next;
};
void main()
{
struct student a,b,c,*head,*p;
a.num = 10101;a.score = 89.5;
b.num = 10103;b.score = 90;
c.num = 10107;c.score = 85;
head = &a;
a.next = &b;
b.next = &c;
c.next = NULL;
p = head;
do
{
printf("%ld%5.1f\n",p -> num,p -> score);
p = p -> next; //使P指向下一结点
}
while(p != NULL);
}
运行结果:
10101 89.5
10103 90.0
10107 85.0
注:
该例子结点都是在程序中定义的,不是临时开辟的,也不能用完后释放,这种链表称为“静态链表”。
8.处理动态链表
①malloc函数
原型:void *malloc(unsigned int size)
其作用是在内存的动态存储区分配一个长度为size的连续空间。此函数的值(即“返回值”)是一个分配域的起始地址(类型为void)。如果此函数未能成功地执行(例如内存不足),则返回空指针(NULL)。
②calloc函数
原型:void *calloc(unsigned n unsigned int size);
其作用是在内存的动态存储区分配n个长度为size的连续空间。函数返回一个指向分配域起始位置的指针;如果分配不成功,返回NULL;
③free函数
原型:void free (void *p);
其作用是释放由p指向的动态存储区,使这部分内存区能被其他变量使用。p是最近一次调用calloc或malloc函数时返回的值。free函数无返回值。
9.建立动态链表
------------------------------------------------------------------------------------
(二)共用体
1.概述:使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构;
2.定义
union 共用体名
{
成员表列;
}变量表列;
如:
union data
{
int i;
char ch;
float f;
}a,b,c;
或者
union data
{
int i;
char ch;
float f;
};
union data a,b,c;
注:共用体与结构体定义形式相似,但占内存不同,结构体占的是各个成员内存和,共用体的内存是成员中字节最长的那个;
3.共用体变量的引用方式
必须先定义后引用,引用时只能引用共用体变量中的成员。
如:
a.i
a.ch
a.f
4.共用体类型数据的特点
(1)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。所以对于共用体变量中起作用的成员是最后一次存放的成员。
如:
a.i = 1;
a.c = 'a';
a.f = 1.5;
只有a.f 是有效的,a.i ,a.c已经无意义了,此时用"printf("%d",a);"是不行的,"printf("%d",a.i);"是不行的,"printf("%d",a.f);"可以;
(2)共用体变量的地址、它的各成员的地址都是同一地址。
即:&a, &a.i, &a.c, &a.f都是同一地址;
(3)不能对共用体变量名赋值,不能赋值给共用体名,不能定义共用体时对它初始化。
①
union data
{
int i;
char ch;
float f;
}a={1,'a',1.5}; 错误
②
a = 1; 错误
m =a; 错误
(4)不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针(和结构体变量这种用法相仿)。
(5)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。
------------------------------------------------------------------------------------
(三)枚举类型
1.enum weekday{sum,mon,tue,wed,thu,fri,sat};(枚举定义的量都为常量)
声明一个枚举类型 enum weekday,可以用此类型来定义变量。如:
enum weekday workday,week_end;
workday和week_end被定义为枚举变量,它们的值只能是sum到sat之一。如:
workday = mon;
week_end = sum;
等价于
enum {sum,mon,tue,wed,thu,fri,sat} workday,week_end;
它们都是其中之一。
2.当然可以用
typedef enum {sum,mon,tue,wed,thu,fri,sat} weekday;
即等价于 enum weekday{sum,mon,tue,wed,thu,fri,sat};
3.枚举类型特点
(1)枚举元素作为常量,它们是有值的,C语言编译按定义时的顺序使它们的值为 0,1,2.....
①
在上面定义中,sun的值为0,mon的值为1......sat的值为6。
例如:
printf("%d",workday);
将输出整数 1。
②
可以在定义式对元素赋初值
如:
enum weekday {sum =7,mon =1,tue,wed,thu,fri,sat} workday,week_end;
定义sun为7,mon为1,其他值还是按顺序给值,即sat任为6。
③枚举类值可比较大小做判断。
(2)一个整数不能直接赋给一个枚举变量
如:
workday = 2; 错误
但可
workday = (eunm weekday)2; 正确
瘋子C语言笔记(结构体/共用体/枚举篇)的更多相关文章
- C语言高级-结构,共用体,文件,链表
C语言结构 标准声明方式 struct student{ int age; char sex; }; 这个可以在main函数中定义: struct student ...
- 瘋子C语言笔记(指针篇)
指针篇 1.基本指针变量 (1)定义 int i,j; int *pointer_1,*pointer_2; pointer_1 = &i; pointer_2 = &j; 等价于 i ...
- 瘋子C语言笔记 (string)
1.strstr() 函数 搜索一个字符串在另一个字符串中的第一次出现.找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址:如果未找到所搜索的字符串,则返回NULL. 2.strcat() 函数 ...
- 瘋耔java语言笔记
一◐ java概述 1.1 ...
- 5、数组&字符串&结构体&共用体&枚举
程序中内存从哪里来 三种内存来源:栈(stack).堆(heap).数据区(.date): 栈(stack) 运行自动分配.自动回收,不需要程序员手工干预: 栈内存可以反复使用: 栈反复使用后,程序不 ...
- C++结构、共用体、枚举
一.结构 结构是C++OOP的基石.学习有关结构的知识僵尸我们离C++的核心OOP更近. 结构是用户定义的类型,同一个结构可以存储多种类型数据,这使得将一个事物的不同属性构成一个对象成为了可能.另外C ...
- C语言-10-位域与共用体
位域 在某种特定情况下,一个结构体中的多个变量只使用各自存储空间的几位,而其他位从来不使用.这种情况下,可以使用位域来限定每个变量的用来存储数据的位宽. 作用 限定结构体中变量用来存放数据的位宽,即使 ...
- C语言基础 (11) 结构体 ,共用体 枚举 typedef
1 课堂回顾 作用域与生命周期 2 static 局部变量 2 打字游戏 3 内存分区代码分析 4 结构体基本操作 (复合类型[自定义类型 #include <stdio.h> #incl ...
- C++复合类型(结构,共用体,枚举)
•结构是用户定义的类型,而结构的声明定义了这种类型的数据属性. 一.关键字struct声明: 定义了一种新类型 struct inflatable{ char name[20];//结构成员 fl ...
随机推荐
- Big Data
Hadoop安装教程_伪分布式配置_CentOS6.4/Hadoop2.6.0 http://dblab.xmu.edu.cn/blog/install-hadoop-in-centos/ Spark ...
- https://yq.aliyun.com/articles/65125?spm=5176.100240.searchblog.18.afqQoU
https://yq.aliyun.com/articles/65125?spm=5176.100240.searchblog.18.afqQoU
- 从Swift3的标准库协议看面向协议编程(一)
Swift中,大量内置类如Dictionary,Array,Range,String都使用了协议 先看看Hashable 哈希表是一种基础的数据结构.,Swift中字典具有以下特点:字典由两种范型类型 ...
- 详解一个自己原创的正则匹配IP的表达式
这里给大家详细讲解一下一个匹配IP地址的正则表达式, 有关正则方面的知识,会在详细的讲解中提到. 在讲解之前,我先给大家介绍一下,ip地址的生成规则. IP地址,是由32位数字二进制转为四个十进制的字 ...
- Union和Union All到底有什么区别
以前一直不知道Union和Union All到底有什么区别,今天来好好的研究一下,网上查到的结果是下面这个样子,可是还是不是很理解,下面将自己亲自验证: Union:对两个结果集进行并集操作,不包括重 ...
- magereverse - Magento数据库表结构
Magento数据库表结构相当复杂,250多张表包含了非常多的表关联关系,让刚刚接触Magento的开发者来说真的非常头疼.往往是看到一个产品的各种属性分散在非常多的表中,找不到任何办法来取出它们的数 ...
- 设计一个程序,程序中有三个类,Triangle,Lader,Circle。
//此程序写出三个类,triangle,lader,circle:其中triangle类具有类型为double的a,b,c边以及周长,面积属性, //具有周长,面积以及修改三边的功能,还有判断能否构成 ...
- 百度地图坐标纠偏和转换工具和DLL
百度一直以来都是个即想装出一副拥抱互联网开放的样子,又为了短期商业利益封闭自己的公司,模仿谷歌地图,开放了自己的百度地图 API,为了防止别人盗用其数据和用户自由迁移,地图相比于火星坐标,又更加封闭, ...
- 在使用 CryptoAPITransform进行加密时异常要调用Reset()
在使用 CryptoAPITransform进行加密时异常要调用Reset() 通过.net源码能看到Reset()里有 public void Reset() { _depadBuffer = nu ...
- spring boot 添加jsp支持注意事项
1.一定要使用war包<packaging>war</packaging>2.将provided改为compile,具体如下: <dependency> <g ...