一,枚举

(1)枚举也可以用来创建新的数据类型,枚举类型存储区就是一个整数类型存储区,只不过这个存储区里只能记录有限的几个整数(2)声明枚举类型时需要提供一组名称,每个名称代表一个整数,这些整数都可以记录在枚举类型存储区里(3)声明枚举类型的时候需要使用enum关键字,第一个枚举名称对应的整数是0,向后依次递增。(4)可以在声明枚举类型的时候指定某个名称对应的整数,它后面的名称对应的整数会随之改变。

enum birth {zhangsan=1998, lisi= 1991, wangwu=1994, chenliu=1993};

二,联合

联合也可以用来声明新的数据类型,联合存储区可以用不同的方式解释。联合也需要声明,声明联合的时候需要使用union关键字。联合存储区的大小是最大使用方式的大小。

#include <stdio.h>
union un
{char buf[2];int num;float fnum;
};
int main()
{union un abc = {0};abc.fnum = 1.0f;printf("1.0是0x%x\n", abc.num);printf("sizeof(abc)是%d\n", sizeof(abc));return 0;
}

三,宏:#define预处理指令可以用来定义宏

1,宏可以用来给数字起名字;定义宏的时候要把宏名称写在前面,把它所代表的数字写在后面;宏名称通常全部由大写英文字母构成;宏名称里不能包含空格;用宏给数字起名字的时候宏定义语句里不能有赋值操作符;编译器会把程序中所有宏名称替换成它所代表的数字;


#define DDR_WRITE8(addr,value)      *((volatile UINT8 *) (addr)) = value
#define DDR_READ8(addr)             (*(volatile UINT8 *) (addr))
#define DDR_WRITE16(addr,value)     *((volatile UINT16 *)(addr)) = value
#define DDR_READ16(addr)            (*(volatile UINT16 *)(addr))
#define DDR_WRITE32(addr,value)     *((volatile UINT32 *)(addr)) = value
#define DDR_READ32(addr)            (*(volatile UINT32 *)(addr))
#define DDR_WRITE64(addr,value)     *((volatile UINT64 *)(addr)) = value
#define DDR_READ64(addr)            (*(volatile UINT64 *)(addr))

2,可以在编译命令中使用-D选项指定宏所代表的数字。如果程序中的某些数字只能在编译的时候才能确定就应该用宏代表它们;宏还可以用来给计算公式起名字;计算公式里包含未知数字,可以使用宏参数表示这些未知数字;宏的参数不一定代表数字,所以它没有类型名称;如果宏有多个参数,不同参数之间需要用逗号分开

3,编译器采用二次替换的方式处理带参数的宏。宏不能使用自己的存储区和函数进行数据传递。宏没有形式参数也没有返回值。能当作数字使用的宏必须编写成一个表达式(因为宏没有返回值存储区)。宏的参数可以直接代表函数的存储区,因为宏没有返回值存储区,所以不能保证优先计算宏内部的操作符。所有能当作数字使用的宏必须写在一对小括号里。因为宏没有形式参数,所以不能保证优先计算参数内部的操作符。宏的所有能当数字使用的参数也应该写在小括号里。不要把自增或自减的计算结果作为宏的参数。

4,#是一个宏操作符,它可以把宏的参数转换为字符串字面值。##也是一个宏操作符,它可以把一个代表标识符的宏参数和其他内容连接成为一个新的标识符

5,条件编译可以在编译的时候从几组语句中选择一组编译而忽略其他组

(1)#ifdef/#ifndef...#else...#endif:以上结构可以根据一个宏是否被定义过从两组语句中选择一组编译。这个结构最开始的预处理指令是二选一的,这个最开始的预处理指令后要跟着一个宏名称。如果采用#ifdef则它后面的宏名称,如果被定义过就编译前一组,否则编译后一组,如果采用#ifndef则刚好相反

(2)#if...#elif(任意次数)...#else...#endif  以上结构也可以实现条件编译,它可以根据任意逻辑表达式的结果从几组语句中选择一组编译

6,多文件编程时一个文件里可以包含多个函数,一个函数必须完整的属于一个文件

多文件编程基本步骤:

(1).把所有函数分散在多个源文件里(主函数单独占一个文件)

(2).为每个源文件编写配对的头文件(主函数所在源文件不需要配对头文件)所有不分配内存的内容都可以写在头文件里。至少要包含源文件里所有函数的声明

(3).修改所有源文件,让它们包含必要的头文件(配对头文件是必要头文件,如果源文件里使用了某个头文件中声明的函数则这个头文件也是必要头文件)

编译多文件程序时可以在gcc命令中把所有源文件名称列出,也可以把编译过程记录在Makefile里,然后使用make工具进行编译,应该把头文件的内容包含在预处理中,这样可以避免多次编译。

7,最开始的预处理指令必须是#ifndef,头文件里使用的宏名称应该根据文件路径变化得到。

8,如果一个源文件里希望使用另外一个源文件里声明的全局变量就需要使用extern关键字再次声明这个全局变量。使用extern关键字声明变量的语句通常放在头文件里。静态全局变量不可以被其他源文件里的语句使用。

#include<stdio.h>
typedef struct
{int x;int y;
}point;point* mid_point(point *a,point *b,point *mid)
{mid->x=(a->x+b->x)/2;mid->y=(a->y+b->y)/2;return mid;
}
int main()
{point A,B,C;printf("请输入第一个点的坐标(x1,y1)\n");scanf("%d,%d",&(A.x),&(A.y));printf("请输入第二个点的坐标(x2,y2)\n");scanf("%d,%d",&(B.x),&(B.y));point *mid_ptr;mid_ptr=mid_point(&A,&B,&C);printf("这条直线中点的坐标是(%d,%d)\n",C.x,C.y);printf("指针读取函数返回值的地址,里面对应的坐标值是:(%d,%d)\n",mid_ptr->x,mid_ptr->y);
}

四,结构体

1,定义:C语言里可以在一个存储区里记录多个相关数字,这种存储区的类型叫结构体类型,这种类型需要程序员编写语句创建出来。

2,结构体存储区里包含多个子存储区,每个子存储区可以用来记录一个数字。

结构体中不同子存储区的类型可以不同,甚至某些子存储区还可以是结构体存储区。

结构体声明语句可以用来创建结构体类型,结构体声明语句中需要使用struct关键字。

结构体声明语句中包含的变量声明语句不会分配内存,它们只是用来表示结构体存储区内部的多个子存储区类型。结构体声明语句可以写在头文件里,结构体类型可以用来声明结构体变量,结构体变量分配了内存,它们可以用来记录数字。

声明结构体变量时需要把struct关键字和结构体类型名称合起来作为类型名称使用。

3,typedef关键字可以用来给现有数据类型起别名别名可以用来替换原有类型名称。

可以把结构体声明语句和起别名语句合并这个时候可以省略结构体本身的名称。

4,C语言不可以在结构体里包含函数结构体变量在声明的时候也应该初始化。

初始化结构体变量的时候可以为每个子存储区提供一个初始化数据,所有初始化数据写在大括号中间,不同数据之间用逗号分开。

5,结构体变量通常不会作为整体使用,一次只会使用其中某个子存储区。可以在结构体变量名称后加.然后再加某个子存储区名称的方法表示某个子存储区。

6,同类型结构体变量之间可以直接赋值,结构体指针用来记录结构体存储区的地址。当结构体指针和结构体存储区捆绑后可以在结构体指针后加->再加上子存储区名称来表示某个子存储区。

7,结构体存储区可以作为形式参数使用但是这样会造成时间和空间的浪费,一般不这么做,使用结构体指针作为形式参数可以避免这种浪费。结构体指针形式参数要尽量加const关键字。

8,不要使用结构体存储区记录返回值,而应该使用结构体指针存储区,这样可以避免时间和空间的浪费,不可以把局部结构体存储区的地址作为返回值使用。

9,一个存储区的地址必须是它自身大小的整数倍(double类型存储区的大小只需要是4的整数倍),这个规则叫做数据对齐,结构体内部的子存储区通常也需要遵守数据对齐的规则,数据对齐可能导致结构体内部不同子存储区之间有空隙。

10,结构体存储区的大小必须是其中占地最大基本类型存储区大小的整数倍(如果占地最大的基本类型存储区是double则结构体存储区的大小只需要是4的整数倍就可以了)这个规则叫做数据补齐。数据补齐可能在结构体存储区最后造成一些浪费的字节。

#include<stdio.h>
typedef struct
{char name[14];float height;int age;
}student;
int main()
{student prn;printf("请输入学生姓名:\n");scanf("%s",&(prn.name));printf("请输入学生体重:\n");scanf("%g",&(prn.height));printf("请输入学生年龄:\n");scanf("%d",&(prn.age));printf("这个学生姓名是:%s,身高是%gkg,年龄是%d岁\n",prn.name,prn.height,prn.age);student person;person=prn;printf("这个学生姓名是:%s,身高是%gkg,年龄是%d岁\n",person.name,person.height,person.age);student stu={"wangfang",50.5,28};
printf("这个学生姓名是:%s,身高是%gkg,年龄是%d岁\n",stu.name,stu.height,stu.age);}

枚举,联合,宏定义,结构体相关推荐

  1. 枚举、宏定义enum /defint/typedef

    #pragma mark 分类,可快速搜索 #pragma mark 1 枚举创建 int enumOne() {     enum Season {spring=1,summer,autumn,wi ...

  2. c 定义结构体时提示应输入声明_C|语法的合理性理解和分析

    试想如果你作为C语言或C语言编译器的的设计者,肯定不会任意设置语法规则,除了考虑不能有歧义以外,还会考虑其合理性. 1 效率是第一位的,安全处于次要位置 了解C语言"效率第一.安全次之&qu ...

  3. [Swift]枚举、类与结构体的对比

    为什么80%的码农都做不了架构师?>>>    ###枚举.类与结构体的对比### ####枚举与其他两者的关系#### 首先说枚举,相对比较好区分,因为我们知道,枚举与其他两者最大 ...

  4. c语言结构体联合体与枚举考点,C语言-结构体+联合体+枚举

    #include #include #include //1.结构体:是一种构造数据类型 //结构体的用途:把不同的数据类型整合起来,成为一个自定义的数据类型 //1.1 定义一个结构体(定义结构体的 ...

  5. ios 结构体跟枚举变量的区别_[Swift]枚举、类与结构体的对比

    ###枚举.类与结构体的对比### ####枚举与其他两者的关系#### 首先说枚举,相对比较好区分,因为我们知道,枚举与其他两者最大的相同之处就在于都可以定义方法. 而其他的更多特性,对于枚举基本没 ...

  6. (c语言)有10个学生,每个学生数据包括学号、姓名、3门课程成绩,编写程序定义结构体从键盘上输入10个学生的学号、姓名和3门课程的成绩,并输出

    有10个学生,每个学生的数据包括学号.姓名.3门课程的成绩,编写程序定义结构体,从键盘上输入10个学生的学号.姓名和3门课程的成绩,并输出3门课程的总平均成绩和最高分的学生的数据(包括学号.姓名.3门 ...

  7. c语言用typedef定义结构体,C语言结构体定义 typedef struct

    c语言规范,定义结构体: typedef struct ANSWER_HEADER { u8 u8Type; u8 u8Code; u32 u32TimeStamp; struct ANSWER_HE ...

  8. Go 学习笔记(27)— type 关键字(类型定义、类型别名、类型查询、定义接口、定义结构体)

    1. 类型别名定义 定义类型别名的写法为: type TypeAlias = Type 类型别名规定: TypeAlias 只是 Type 的别名,本质上 TypeAlias 与 Type 是同一个类 ...

  9. 定义结构体的时候,里面的变量可以同时初始化吗?(不可以)

    定义结构体的时候,不能对里面的变量同时初始化. 因为定义结构体时,并未给其分配内存,所以初值是无法存储的. 应该声明结构体变量后,手工赋值. struct sstring { int a; int d ...

  10. c 定义结构体时提示应输入声明_C语言结构体的坑很多,这6大方法千万要记住!...

    本文福利在文末! C语言可谓是编程界的传奇语言,历经几十年,依然排名前列. 本文主要说的是C语言中的结构体,结构体是C语言中重要的一部分内容,也是C语言中常用的一种数据结构. 一.关于结构体在C语言中 ...

最新文章

  1. 使用JPA进行update操作时,报org.springframework.beans.factory.BeanCreationException: Error creating bean with
  2. 爱了!安利一个相见恨晚的可视化学习网站
  3. Android OpenGL ES 入门系列(一) --- 了解OpenGL ES的前世今生
  4. VS .NET(C#)四舍五入方法(转)
  5. Groovy/Spock 测试导论
  6. pyqy5——控件2
  7. Python安装Matplotlib,wordcloud,jieba第三方库
  8. Eclipse中启动tomcat访问404解决及原因
  9. 【论文笔记】MOBA类游戏中的强化学习论文5篇
  10. [系统安全] 十三.熊猫烧香病毒IDA和OD逆向分析(中)病毒释放机理
  11. AAAI 2022 论文列表
  12. python开发出来的crm系统_关于python开发CRM系统
  13. html重复渐变包括,html – CSS:当设置为tbody / thead时,在Chrome中重复的渐变
  14. 什么是Java股票交易接口?
  15. 从浙大计算机到字节算法岗!
  16. 豆瓣电影喜剧榜数据爬取
  17. android 安全加固总结报告,Android应用本地代码的安全加固及安全性评估
  18. STL容器基础 - 0
  19. Inserting Data Into Tables Using Direct-Path INSERT
  20. 能给黑白照片自动上色的软件有哪些?这几款建议收藏

热门文章

  1. python把一个文件夹内子文件夹下所有文件复制到指定目录下
  2. 技术经理成长复盘-我是什么样的人
  3. 解决Git使用出现git@githubcom Permission denied (publickey)
  4. 特征值问题编程基础:特征值特征向量的求解和性质
  5. 【Docker容器镜像加速器~阿里云镜像加速器】
  6. 软件测试面试题:请对这个系统做出测试用例:一个系统,多个摄像头,抓拍车牌,识别车牌,上传网上,网上展示?
  7. 68个dlib的landmarks
  8. c语言点亮共阴极数码管,课程设计-基于单片机的共阴极数码管显示电路.doc
  9. Error: While importing ‘run_app_dev‘, an ImportError was raised.
  10. 高逼格技能教你玩转Excel