c programming language practice
#####01 变量:
- 本质:程序可操控的一段存储区
- 数据类型:变量的类型决定了存储区的大小和布局(在浮点型上表现明显,符号,指数,小数)
- 命名规则:必须以字母和下划线开头,可以由字母,数字,下划线组成
- 初始化:如果未进行初始化操作,带有静态存储持续时间的变量会被隐式初始化为 NULL(所有字节的值都是 0),其他所有变量的初始值是未定义的。
- 变量声明与定义
- 需要建立存储空间
int a //既是声明也是定义
- 不需要建立存储空间,通过使用extern关键字声明变量名而不定义它。
extern int a //只声明,不定义
- 需要建立存储空间
- 赋值操作
- 左值 lvalue :指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。
- 右值 rvalue :指的是存储在内存中某些地址的数值称为右值(rvalue)表达式。 右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。
- 简言之——变量是左值,因此可以出现在赋值号的左边。数值型的字面值是右值,因此不能被赋值,不能出现在赋值号的左边。
eg: 正常int g = 20; 错误 10 = 20
#####02 常量:
- 本质:常规变量,只是在定义后不能随意修改,在程序执行期间不会值改变
- 类型:
- 整数常量
- 前缀:0x表示16进制,0表示8进制,默认无前缀表示10进制
078 /* 非法的:8 不是八进制的数字 */
- 后缀:U表示无符号整数,L表示长整数
- U和L顺序可以任意,大小写可以通用
30ul /* 无符号长整数 */
- 可单独使用
30u /* 无符号整数 */
- 不能重复
032UU /* 非法的:不能重复后缀 */
- U和L顺序可以任意,大小写可以通用
- 前缀:0x表示16进制,0表示8进制,默认无前缀表示10进制
- 浮点常量:由整数部分,小数点,小数部分和指数部分组成
- 浮点型含义:按照科学计数法小数点是浮动的,位置是可变的。
eg: 1.23x10^9和12.3x10^8完全相等
- 小数形式:必须同时包含整数部分,小数部分
210f /* 非法的:没有小数部分 */
- 指数形式:必须包含小数点,指数部分,带符号的指数用e或者E引入,(科学计数法中10用e来代替)
510E /* 非法的:不完整的指数 */
- 浮点型含义:按照科学计数法小数点是浮动的,位置是可变的。
- 字符常量:字符常量可以是一个普通的字符(例如 'x')、一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')。
- 转义字符
- 字符串常量:字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
- 整数常量
- 定义常量:把常量名定义为大写字母形式
- defind 预处理器
- 井defind variable value
#define WIDTH 5;
- 井defind variable value
- const关键字
- const type variable = value;
const int LENGTH = 10;
- const type variable = value;
- defind 预处理器
#####03 存储类
- 存储类定义C程序中变量/函数的范围(可见性),和生命周期。放置在它们所修饰的类型之前
- 类型:
- auto:局部变量默认存储器
auto int month;
- register:定义可能存储在寄存器中用于快速访问的变量,而不是RAM中的局部变量
register int miles;
- static:指示编译器在程序的生命周期内保持局部变量的存在。无需每次进入和离开作用域时进行创建和销毁操作。
- static 修饰的局部变量,可以在函数调用之间,保持局部变量的值
- static修饰的局部变量, 只初始化1次,每次调用所在方法时,变量的值不会被重复初始化
- static 修饰的全局变量或方法,可以被任何函数或方法调用,只要这些方法出现在跟static变量或方法的同一个文件夹内
- 全局变量, 默认被static修饰
- static 修饰的局部变量,可以在函数调用之间,保持局部变量的值
- extern:用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置
- extern是用来使用在另一个文件中声明一个全局变量或函数 #####04 运算符
- auto:局部变量默认存储器
- 运算符 operator
- 类型
- 算术运算符 +,-,*,/,%,++,--
- / 整除无小数
- % 整除后的余数
- ++ 自增加1
- -- 自减少1
- 前置先运算后赋值,后置运算先赋值后运算
- 关系运算符 ==,!=,>,<,>=,<=
- 逻辑运算符 &&,||,!
- 位运算符 &,|,^
- 赋值运算发 =
- 疑问?C语言中没有字符串连接符?
- 杂项运算符
- sizeof() 返回变量的大小为int类型
int a; printf("int: %d\n",sizeof(a));
- & 返回变量地址值为int类型
printf("a: %d", &a);
- ? : 三元条件表达式
d > 10 ? printf("d>10") : printf("d<10");
- 指向一个变量
int *b; printf("*b: %d\n",*b);
- sizeof() 返回变量的大小为int类型
- 算术运算符 +,-,*,/,%,++,--
- 优先级
- 后缀: ++,--,(),[]
- 乘除
- 加减
- 移位: <<,>>
- 关系
- 逻辑
- 条件
- 赋值
- 类型
#####05 判断
- 判断结构 decision
- 定义:指定一个或多个要评估的或测试的条件,以及条件为真时的必要执行语句,和条件为假时的可选执行语句
- 条件判断关键字:
- C中把任何非零和非空的值假定true
- 零或者null假定为false
- 条件判断语句
- if
- if……else……
- 嵌套if
- switch
- 嵌套switch
- 三元运算符
decision ? run true : run false
- 注意细节:
- switch 先计算表达式,再逐个和case后的常量比较
- if语句当满足条件后,会跳出判断结构,switch当满足条件后,不会跳出判断结构,而是继续向下执行,所以最好在case语句后,加上break语句来中断条件判断语句
#####06 循环
- 循环机构 loops
- 定义:允许我们多次执行一个语句或者语句组
- 循环类型
- for 循环
- while循环
- do……while循环:与while循环相比,采用尾判断
- 嵌套循环
- 循环控制语句
- break语句
- continue语句
- goto语句
- 注意细节:
- 无限循环,当表达式不存在,它被假设为真。偏向使用for(;;)结构来表示一个无线循环
#####07 函数
- 定义函数:函数由一个函数头和一个函数主体组成
- 返回类型:函数可以返回一个值,return_type是函数值的数据类型
- 没有返回值的函数 return_type是关键字void。
- 函数签名:
- 函数名称:函数的实际名称
- 参数列表:函数参数的类型,顺序,数量。(参数是可选的,函数可以不包含参数)
- 函数主体:包含一组定义函数的执行任务的语句。
- 返回类型:函数可以返回一个值,return_type是函数值的数据类型
- 主函数:函数是一组一起执行任务的语句,每个C函数都至少包含一个主函数即main()函数。
- 函数声明:函数声明会告诉编译器函数名称以及如何调用函数,包括返回类型和函数签名。
- 在函数声明中,参数的名称并不重要,只有参数的类型是必须的
int max(int, int)
- 在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必须的。要调用函数的文件顶部声明函数。
- 调用函数:当程序调用函数时,程序的控制权会转移给被调用的函数,当函数的返回语句执行完,会把控制权交给主程序。
- 内置函数:
- 输出/输入函数
- 内置函数:
- 传递参数:默认情况C使用传值调用来传递参数。
- 传值调用
- 引用调用
- 形参:如果函数要使用参数,则必须声明接收参数值的变量,被当作函数内的局部变量。
- 实参
#####08_作用域规则
- 定义作用域:作用域是程序中定义的变量所存在的区域,超过该区域变量就不能访问
- 局部变量:在函数或块内部的声明的变量,只能在函数内部使用,局部变量在外部是不可访问的
- 全部变量:在函数外部的声明的变量,通常是程序的顶部。全局变量在整个程序生命周期内都是有效的,可以被程序内的任何函数访问。
- 区别:
- 全局变量保存在内存的全局存储区,占用静态的存储单元
- 局部变量存储在栈中,只有在所在函数被调用时,才动态地为变量分配存储单元
- 细节:
- 在程序中,局部变量和全局变量的名称可以相同,但是,在函数内会使用局部变量,全局变量不会被使用。
- 当局部变量被定义时,系统不会对其初始化(未初始化的变量会导致内存位置中已经可用的垃圾值),必须自行对其初始化; 定义全局变量时,系统会自动对其初始化。
#####09_数组
- 数组:可以存储一个固定大小的,相同类型元素的顺序集合。通过声明一个数组变量,使用索引逐个访问。
- 声明数组 格式: type arrayName [arraySize]
int balance[10]
- 初始化数组
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
- 大括号{}之间的值的数目不能大于声明数组时,在方括号[]中指定的元素数目
- 如果[]内没有指定数组大小,那么数组的大小则为初始化时{}中元素的个数
- 访问数组元素
- 所有的数组都是0作为它们第一个索引,也被称为基索引,数组的最后一个索引是数组总数大小减去1
- 数组元素通过数组名称加索引来访问
double salary = balance[9];
,元素的索引放在[]内,跟在数组名称的后面
- 进阶用法
- 多维数组:常用来表示矩阵
- 格式:type name [size1][size2][size3]
int threedim[5][10][4]
- 格式:type name [size1][size2][size3]
- 传递数组给函数
- 形参是一个指针
void myFunction(int *param)
- 形参是一个已定义的数组
void myFunction(int param[10])
- 形参是一个未定义的数组
void myFunction(int param[])
- 形参是一个指针
- 从函数返回数组
- 指向数组的指针
- 多维数组:常用来表示矩阵
#####10_枚举
- 枚举是一种基本数据类型,可以让数据更简洁,更易读
- 语法定义格式:
enum 枚举名 {枚举元素1,枚举元素2,枚举元素3,……};
- 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
- 当指定某个枚举元素的值,后续元素值会在此基础上加1。
- 不同方式来定义枚举变量
- 先定义枚举类型,再定义枚举变量
enum DAY {MON = 1, TUE, WED, THU, FRI, SAT, SUN}; enum DAY day;
- 定义枚举类型的同时定义枚举变量
enum DAY {MON = 1, TUE, WED, THU, FRI, SAT, SUN} day;
- 省略枚举名称,直接定义枚举变量
enum {MON = 1, TUE, WED, THU, FRI, SAT, SUN} day;
- 先定义枚举类型,再定义枚举变量
- 细节:
- C中 枚举类型是被当做int或者unsigned int 类型来处理的
- 特殊情境下(枚举类型必须是连续),可以遍历枚举的元素
- 枚举可以和switch配合使用
- 将整数转换为枚举,枚举类型与其他类型间转换?
- 枚举使用场景?