枚举
没有使用枚举的情况为
代码
#include<stdio.h> const int Yello = 0; const int Green = 1; const int Red = 2 ; //枚举比const int 方法好用 int main(int argc, char const*argv[]){ int color = 1; switch(color){ case 0: printf("Yello"); break; case 1: printf("Green"); break; case 2: printf("Red"); break; } return 0; }
枚举是一种用户定义的数据类型,它用关键字enum以如下语句来声明
enum 枚举类型的名字{名字0 , 名字1, 名字2...};
枚举类型名字通常并不真的使用,要用的是大括号里的名字【常量符号】,类型为int,值则依次为0到n
操作#include<stdio.h> enum Color {Yello, Green ,Red , Numbers}; void print(enum Color t,int i){ printf("%d\n",t); // enum Color t 为代号 即int char* colorNames [Numbers] = {"Yello","Green","Red"}; if(i >=0 && i < Numbers ){ printf("%s\n",colorNames[i]); } else printf("unknown\n"); } int main(int argc, char const*argv[]){ enum Color c = Red; int myLike = 0; print(c,myLike); return 0; }
枚举量可以指定值
枚举比宏好,因为枚举有int 不过使用起来并没有java那么好用!!!
结构
复合数据类型
- 定义方式
struct date{ int month; int day; int year; }; //<---分号
- 使用
#include<stdio.h> struct date{ //可以在函数内 或者函数外 int month; int day; int year; }; int main(int argc, char const*argv[]){ struct date today ; //!!!! today.year = 2020; today.month = 1; today.day = 2; printf("%i-%i-%i",today.year,today.month,today.day); //%i 在scanf里会识别八进制、16进制输入,并转换成10进制 return 0; }
声明结构的形式 定义 初始化
- p1 p2 都是一种point的结构的两个变量,里面有x和y
struct point{ int x; int y; }; struct point p1 ,p2;
- p1 p2 都是一种无名的结构的两个变量,里面有x和y
struct { int x; int y; }p1 ,p2; //这个结构仅能够给p1 p2 使用
- p1 p2 都是一种point的结构的两个变量,里面有x和y
struct point{ int x; int y; }p1 , p2;
- 初始化
#include<stdio.h> struct date{//结构类型 int month;//结构变量 int day; int year; }; int main(int argc, char const*argv[]){ struct date today ; today.year = 2020; today.month = 1; today.day = 2; struct date myday = {.year = 2020,.month = 1, } ; printf("%i-%i-%i\n",today.year,today.month,today.day); //%i 在scanf里会识别八进制、16进制输入,并转换成10进制 printf("%i-%i-%i\n",myday.year,myday.month,myday.day); return 0; } //2020-1-2 //2020-1-0
结构[类型可以不同]和数组[相同类型]有点像
可以整个结构可以做赋值、取地址也可以传递给函数参数
- p1 = (struct point){5,10};强制类型转换 p1.x = 5 ;p1.y = 10;
- p1 = p2 ; 【数组不可以】 相等后 修改一个 并不会给另外一个造成影响
结构指针
- 和数组不同【数组为首位置的地址】,结构变量的名字并不是结构变量的地址,必须使用&运算符
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.year = 2020; today.month = 1; today.day = 2; struct date myday = today; printf("%p\n",myday); myday.day = 3; printf("%p\n",myday); printf("%i-%i-%i\n",myday.year,myday.month,myday.day); printf("%p\n",today); printf("%i-%i-%i\n",today.year,today.month,today.day); //%i 在scanf里会识别八进制、16进制输入,并转换成10进制 return 0; } //0x200000001 //0x300000001 //2020-1-3 //0x200000001 //2020-1-2
结构作为函数参数
- 可以当作参数的值传入函数
- 这个时候在函数内新建一个结构变量,并复制调用者的结构的值 <-- 克隆品
- 也可以返回一个结构
- 这与数组不同
#include<stdio.h> struct date{ int month; int day; int year; }; //传入函数中的结构变量 在函数中可以创建一个临时的结构变量 然后把这个结构返回给调用者 struct date funtion(struct date day){ printf("%i-%i-%i\n",day.year,day.month,day.day); day.day++; printf("%i-%i-%i\n",day.year,day.month,day.day); return day; //返回传入指针 NICE!!!! } int main(int argc, char const*argv[]){ struct date today ; today.year = 20120; today.month = 1; today.day = 2; printf("%i-%i-%i\n",today.year,today.month,today.day); struct date myday = funtion(today); printf("%i-%i-%i\n",today.year,today.month,today.day); printf("%i-%i-%i\n",myday.year,myday.month,myday.day); return 0; } //20120-1-2 //20120-1-2 //20120-1-3 //20120-1-2 //20120-1-3
- 赋值 scanf("%i %i %i",&today.year,&today.month,&today,day);
传结构的指针好处大于直接传整个结构 因为要花费拷贝的过程!!! 浪费资源
- 现在用指针的话代码如下 p是指针
用-> 表示指针所指的结构变量中的成员struct date *p = &myday; (*p).month = 12; //符号多 //等价于 p->month = 12;
- 参与赋值
struct point* getStruct(struct point *p){// 返回出来可以串入其他函数的运算 ... scanf("%d",&p->x); //p是一个指针 p->x 表示指针对应的结构变量 然后& 取出它的地址 scanf("%d",&p->y); printf("%d %d " ,p->x ,p->y); }
结构其他应用
- 结构数组
struct date dates [100] = {{...},{...}}; - 结构含结构
struct date point { struct date time , struct date day} - 四种形式是等价的
如果有变量定义: struct rectangle r, *rp; rp = &r; 那么下面的四种形式是等价的: r.ptl.x ; //r不是指针 rp->ptl.x ; //ptl是指针 (rp -> ptl).x ; (r.ptl).x; //但没有rp -> ptl -> x 因为ptl 不是指针 即是结构本身
自定义数据类型
typedef 目标一大串 命名为xxx
目的是取别名 typedef int Length; Length就是int!!!
作用于结构 将整个结构替换为
Date day <--原来的--- struct date day;#include<stdio.h> typedef struct date{ //有无结构名字date 已经不是很重要了 int month; int day; int year; } Date; int main(int argc, char const*argv[]){ Date day = {1,3,2020}; printf("%i-%i-%i",day.year,day.month,day.day); return 0; }
字符串
typedef * char[10] Strings节点
typedef struct node { int data; struct node *next; }Node;
联合 union
跟struct 非常相似,但所有成员一起用一份空间
- 代码
union Ant{ int i ; char c ; }ant;
- sizeof(union ...) = sizeof(每个成员)的最大值
所有成员共享一个空间,同一时间只有一个成员是有效的,union的大小是其最大的成员
初始化:对第一个成员做初始化union Ant{ int i ; //1234 十六进制0000 04D2 计算机地位在前 D204 0000 ,c的取值就是int 的数据 char c[sizeof(int)] ; 一块空间 sizeof(int)若等于四个字节,则i跟c 一起用这个空间 }ant;
- 应用:得到整数内部的字节 double内部的字节 中间的笔记