C语言,枚举,struct,typedef,union的使用

简介: C语言,枚举,struct,typedef,union的使用

枚举、struct结构、typedef和union

一、枚举

1、基本概念

2、枚举的简单应用

二、结构

1、struct结构

2、struct与函数

简单应用(下一天)

3、结构里的结构

简单应用(下一秒)

三、typedef和union

1、typedef

2、联合(union)

一、枚举

1、基本概念

枚举是一种用户定义的数据类型,它用关键字enum以如下语法来声明

enum 枚举类型名字{名字0,…,名字n};

枚举类型的名字通常并不真的使用,要用的是在大括号里的名字,因为它们就是常量符号,他们的类型是int,


值则依次从0到n。如:

enum peoples{ Leo,Tim,Tom,Ann};

创建了三个常量,Leo的值是0,Tim是1,而Ann是2.

需要一些可以排列起来的常量值时,定义枚举的意义就是给这些常量值名字。


枚举量可以做值

枚举类型可以跟上enum作为类型

但是实际是以整数来做内部计算和外部输入输出的

声明枚举量的时候可以指定值


2、枚举的简单应用

#include <stdio.h>


enum COLOR {RED, YELLOW, GREEN, NumCOLORS};  //枚举三种颜色


int main(int argc, char const *argv[])

{

int color = -1;  //定义判断值

char *colorName = NULL;


printf("请输入你喜欢的颜色的代码:");

scanf("%d", &color);  //读入颜色代码

switch( color ) {

case RED: colorName = "red";

break;

case YELLOW: colorName = "yellow";

break;

case GREEN: colorName = "green";

break;

default: colorName = "unknown";

break;

}  //根据输入的不同输出

printf("你喜欢的颜色是%s\n", colorName);  //输出最喜欢的颜色


return 0;

}

二、结构

1、struct结构

声明结构类型

和本地变量一样,在函数内部说明的结构类型只能在函数内部使用。

所以通常在函数内外说明结构类型,这样就可以被多个函数所使用了。


struct point{

int x;

int y;

};


srtuct point p1, p2;

p1和p2都是point里面x和y的值


struct{

int x;

int y;

} p1, p2;


p1和p2都是一种无名结构,里面有x和y


struct point{

int x;

int y;

}p1, p2;


p1和p2都是point里面有x和y的值t。


对于第一和第三种形式都声明了结构point但是第二种结构没有声明point,只定义的两种两个变量。


结构成员

结构和数组相似

数组用[]运算符和下标访问其成员

a[0] = 10;

结构用.运算符和名字访问其成员

today.day

student.firstName

p1.x

p1,y


结构运算

要访问整个结构,直接用变量的名字

对于整个结构可以做赋值,取地址,也可以传递给函数参数

p1 = (struct point){5, 10}; //相当于p1.x = 5; p1.y = 10;

p1 = p2; //相当于p1.x = p2.x; p1.y = p2.y;


结构指针

和数组不同,结构类型的名字必须是结构变量的地址,必须用&运算符

struct date *pDate = &today;


读入日期


#include <stdio.h>


struct date {  //定义结构

int month;

int day;

int year;

};


int main(int argc, char const *argv[])

{

struct date today;


today.month = 11;  

today.day = 4;

today.year = 2022;  


printf("Today`s date is %i-%i-%i.\n",today.year, today.month, today.day);


return 0;

}


2、struct与函数

结构作为函数参数,也可以作为参数的值传入函数

这时候是在函数内新建一个结构变量,并复制调用者的结构的值

也可以返回一个结构

这与数组不同


指向结构的指针

用->表示指针所指的结构变量中的成员


结构数组

struct date dates[];

struct date dates[] = {

{4, 5, 2005}, {2, 4, 2004} };


简单应用(下一天)

#include <stdio.h>

#include <stdbool.h>


struct date {  //定义结构

int month;

int day;

int year;

};


bool isLeap(struct date d);

int numberOfDays(struct date d);


int main(int argc, char const *argv[])

{

struct date today, tomorrow;


printf("Enter today's date (mm dd yyyy):");  

scanf("%i %i %i", &today.month, &today.day, &today.year);  //读入date


if( today.day != numberOfDays(today) ) {  //判断一般情况

 tomorrow.day = today.day+1;

 tomorrow.month = today.month;

 tomorrow.year = today.year;

} else if (today.month == 12 ) {  //date为每年最后一天

 tomorrow.day = 1;

 tomorrow.month = 1;

 tomorrow.year = today.year + 1;

} else {  //date为每月最后一天(不包括12月)

 tomorrow.day = 1;

 tomorrow.month = today.month+1;

 tomorrow.year = today.year;

}


printf("Tomorrow's date is %i-%i-%i.\n", tomorrow.year, tomorrow.month, tomorrow.day);


return 0;

}


int numberOfDays(struct date d)

{

int days;

//列出每月的天数

const int daysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  


if ( d.month ==2 && isLeap(d) )  //闰年则为29天

{

 days = 29;

}else

{

 days = daysPerMonth[d.month-1];

}


return days;

}


bool isLeap(struct date d)  //判断平年和闰年

{

bool leap = false;


if( (d.year %4 == 0 && d.year %100 !=0 ) || d.year%400 == 0 )

 leap = true;


return leap;

}


3、结构里的结构

嵌套的结构

struct point {

int x;

int y;

};


如果有变量

struct rectangle r;

就可以有

r.pt1.x 、r.pt1.y,

r.pt2.x和r.pt2.y


如果有变量定义

struct rectangle r, *rp;

rp = &r;

那么下面的四种形式是等价的:

r.pt1.x

rp->pt1.x

(r.pt1).x

(rp->pt1).x

但是没有rp->pt1->x (因为pt1不是指针)


简单应用(下一秒)

#include <stdio.h>


struct time{  //定义结构

int hour;

int minutes;

int seconds;

};

struct time timeUpdate(struct time now);

int main(void)

{

 struct time testTimes[5] = {

  {11, 59, 59}, {12, 0, 0}, {1, 29, 59}, {23, 59, 59} , {19, 12, 27}  

 };   //读入代表时间的结构数组

 int i;

 

 for ( i=0; i<5; ++i ) {

  printf("Time is %.2i:%.2i:%.2i\n", testTimes[i].hour, testTimes[i].minutes, testTimes[i].seconds );  

  testTimes[i] = timeUpdate(testTimes[i]);

  printf("...one second later it's %.2i:%.2i:%.2i\n", testTimes[i].hour, testTimes[i].minutes, testTimes[i].seconds);

 }

 

 return 0;

}

struct time timeUpdate(struct time now)

{

++now.seconds;

if ( now.seconds == 60 ) {

 now.seconds = 0;

 ++now.minutes;

 

 if ( now.minutes == 60 ) {

  now.minutes = 0;

  ++now.hour;

  if ( now.hour == 24 ) {

   now.hour = 0;

  }

 }

}  //嵌套if,判断时间的特殊情况


return now;

}


三、typedef和union

1、typedef

自定义数据类型(typedef)

typedef 功能,声明一个已有的数据类型的新名字。例如:

typedef int Length;


Typedef

声明新类型的名字,是某种类型的别名,提高了程序的可读性


typedef long int64_t;

typedef struct Adate {

int month;

int day;

int year;

} Date;


int64_t i = 10000000;

Date d = { 6, 11, 2022};


2、联合(union)

union AnElt {

int i;

char c;

} elt1, elt2;


elt1, elt2;


联合

存储

所有的成员共用一个空间

同一个时间只有一个成员是有效的

union 的大小是最大的成员


相关文章
|
1月前
|
存储 编译器 C语言
c语言回顾-联合和枚举
c语言回顾-联合和枚举
28 4
|
1月前
|
编译器 C语言
C语言:typedef 和 define 有什么区别
在C语言中,`typedef`和`#define`都是用来创建标识符以简化复杂数据类型或常量的使用,但它们之间存在本质的区别。`typedef`用于定义新的数据类型别名,它保留了数据类型的特性但不分配内存。而`#define`是预处理器指令,用于定义宏替换,既可用于定义常量,也可用于简单的文本替换,但在编译前进行,过度使用可能导致代码可读性下降。正确选择使用`typedef`或`#define`可以提高代码质量和可维护性。
|
1月前
|
存储 C语言 C++
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
深入C语言,发现多样的数据之枚举和联合体
|
1月前
|
存储 安全 编译器
深入理解C语言中的枚举
深入理解C语言中的枚举
|
1月前
|
存储 编译器 C语言
【C语言】自定义类型:联合与枚举的简明概述
【C语言】自定义类型:联合与枚举的简明概述
|
3月前
|
存储 编译器 C语言
【C语言篇】自定义类型:联合体和枚举详细介绍
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
45 1
|
5月前
|
C语言
枚举(C语言)
枚举(C语言)
|
5月前
|
编译器 C语言 C++
【C语言基础】:自定义类型(二) -->联合和枚举
【C语言基础】:自定义类型(二) -->联合和枚举
|
5月前
|
C语言
C语言学习记录——枚举(定义、与结构体的区别、优点)
C语言学习记录——枚举(定义、与结构体的区别、优点)
59 3
|
5月前
|
C语言
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
31 1