C语言简介: BCPL->newB->C->UNIX->Minix->Linux->gcc C语言诞生于1971~1973年,在肯.汤普逊和丹尼斯.里奇领导下编写完成, 归属于美国的贝尔实验室。 C语言为了专门编写操作系统而诞生的语言,所以天生适合对硬件编程, 也因为速度快而著称,也非常适合实现数据结构和算法。 由于出现时间早,有很多缺陷,也没想过普通人能使用C语言编程,因此 存在着缺陷,但是前辈总结了一些可以避免的经验《C陷阱与缺陷》 《C程序设计语言》 自由源于自律
C89语法标准,也是gcc默认的语法标准 C99语法标准,对C语言的扩展和增强 -std=gnu99 C11语法标准,全新的升级一、第一个C程序 #include <stdio.h> 程序员所编写的代码不是标准的C代码,需要一个程序翻译它,变成标准的C代码,负责翻译的程序叫做预处理器,翻译的过程叫做预处理,被翻译的代码叫做预处理指令,以#开头都叫做预处理指令。 #include 的功能是把一个头文件导入到当前文件中 #include <xxx.h> 从系统指定的路径下加载头文件 #include “xxx.h” 先从当前工作路径下加载头文件,如果没有则再从系统指定路径加载头文件 stdio.h 头文件:以.h结尾,里面储存一些辅助性代码,绝大多数都是函数的声明(也就是函数的开头) 源文件:以.c结尾,里面记录的是功能性代码 C语言标准委员会为C语言以函数形式提供了一套基础的功能,这些函数就被封装libc.so库中,很多头文件负责对libc.so进行说明,stdio.h就是其中一个,常用string.h stdlib.h stradard input output 负责对输入输出功能函数的说明
int main() { printf(“Hello World!\n”); return 0;
} main函数: C语言中以函数为单位来管理代码,一个函数就是一段具有某个功能的代码的集合 main函数是程序的执行入口,有且只能有一个 int 是一种数据类型,它表示main的执行结果是一个整数 return 有两个功能: 1、返回一个数给函数的调用者(main是给操作系统) 2、结束函数的执行 main函数的调用者是操作系统,它的返回值给了操作系统,反映了程序是如何结束的,通常有三种: 正数 出现异常 (别人的错误) 0 一切正常 负数 出现错误 (自己的错误) echo $? 可以查看上一个main函数的返回值 printf/scanf是标准库中的函数,负责输入、输出数据,用来调试程序 转义字符:键盘上有一些没有的符号,用一些特殊的字符来表示,这些特殊的字符就叫转义字符,\n 就是其中一个。 \t 制表符tab \r 回到行首 \b 退格键 \a 铃响 \ %% % C语言以分号作为一行代码的结束,使用大括号来划分区域
二、C代码变成可执行程序的过程: 1、预处理:把源文件翻译成预处理文件 gcc -E code.c 显示预处理结果到终端 gcc -E code.c -o code.i 生成以.i结尾的预处理文件 2、编译:把预处理文件编译成汇编文件 gcc -S code.i 生成以.s结尾的汇编文件 3、汇编:把汇编文件翻译成二进制的目标文件 gcc -c code.s 生成以.o结尾的目标文件 4、链接:把若干个目标文件合并成一个可执行程序 gcc code.o 生成默认名是a.out的可执行程序
C语言中文件类型: .h 头文件 .h.gch 头文件的编译结果,它会被优先使用 .c 源文件 .i 预处理文件 .s 汇编文件 .o 目标文件 .a 静态库 .os 共享库三、编译器 负责把人能看懂的记录代码的文本文件,翻译成计算机能看懂的二进制文件,由预处理器、编译器、链接器组成。 gcc是又GNU社区为了编译Linux代码而开发的一款免费的编译器,采用默认是C89标准,-std=gnu99来设置C99标准 常用的参数: -E:显示预处理结果 -S:生成汇编代码 -c:只编译不链接 -o:设置编译结果的名字 -I:指定头文件的加载路径 -l:指定要使用的库,-lm,使用数据库 -Wall:以严格的标准来检查代码,用来显示更多的警告提醒 -Werror:把警告当错误处理 -std:指定编译的语法标准
储存空间的单位: Bit 比特 一个二进制位,只能储存0或1,计算机储存数据的最小单位 Byte 字节 八个二进制位,计算机储存器的存储容量的基本单位 KB 1024字节 MB 1024KB GB 1024MB TB 1024GB PB 1024PB
四、数据类型 为什么要对数据进行分类: 1、现实社会中的数据自带类别属性 2、对数据进行分类可以节约储存空间、提高运行效率
C语言中的数据分为两大类:自建(程序员自己设计的,例如:结构、联合、枚举、类)和内建(C语言自带)。 整型: signed 有符号 signed char 1 -128~127 signed short 2 -32768~32767 signed int 4 正负20亿 signed long 4/8 正负20亿/9开头的19位数 signed long long 8 9开头的19位数 注意:signed 不加就代表加了 unsigned 无符号 unsigned char 1 0~255 unsigned short 2 0~65535 unsigned int 4 0~40亿 unsigned long 4/8 unsigned long long 8 1开头的20位数 注意:由于定义无符号数据比较麻烦,标准库把这些无符号的类型重新定义成以下类型: 需要包含头文件<stdint.h> uint8_t、uint16_t、uint32_t、uint64_t int8_t、int16_t、int32_t、int64_t 浮点型: float 4 double 8 long double 12/16 注意:采用科学计数法,二进制与真实的数据之间需要翻译,因此计算浮点型要比整型慢,编程时能尽量使用整型 小数点后6位有效 模拟: char:字符 其实是图案或者是符号,在内存中储存的是整数,需要显示时,根据ASCII码表,找到该整数对应的符号或图案,然后显示。 0 == '\0' 48 == '0' 65 == 'A' 97 == 'a' bool 布尔 先有了C才有了bool类型,所以C语言是不可能有真正的布尔类型,stdbool.h头文件对布尔类型进行了模拟 bool true false 可以使用sizeof来计算类型的字节数五、变量与常量 什么是变量:程序运行期间数值可以变化的叫做变量,相当于储存数据的盒子 定义:类型 变量名; int num; 取名规则: 1、由字母、数字、下划线组成 2、不能以数字作为开头 3、不能与32个关键字重名、能够默写 4、见名知意(功能、类型、作用范围) unsigned char num_u_c printf scanf bool sizeof 注意:变量定义时,一定要初始化(习惯),否则值是不确定的 使用: 赋值: num = 10; 参与运算: num * 10;
变量的输入、输出: int printf(const char *format, ...); 功能:输出数据 format:双引号包含的格式信息(提示信息+占位符) ...:变量的列表 返回值:输出字符的个数 int scanf(const char *format, ...); int ret = scanf() 功能:输入数据 format:双引号包含的格式信息(占位符) ...:变量的地址列表,变量的地址 = &变量名 返回值:成功输入的变量的个数 练习1:定义各种类型的变量并初始化,使用printf来显示 练习2:定义各种类型的变量并初始化为0,使用scanf来输入,printf来显示 类型占位符:C语言中通过占位符的方式来传递变量的类型 %hhd %hd %d %ld %lld %hhu %hu %u %lu %llu %f %lf %LF 什么是常量:程序运行期间数值不能发生变化的叫常量 字面值常量 100 默认int 100l long 100ll long long 100u unsigned int 100lu unsigned long 100llu unsigned long long 3.14 默认double类型 3.14f float 3.14l long double六、格式化输入输出 %nd 显示n个字符宽度,不够则补空格,右对齐 %-nd 显示n个字符宽度,不够则补空格,左对齐 %0nd 显示n个字符宽度,不够则补0,右对齐 %n.mf 显示n个字符宽度(小数点算一位),不够补空格,m表示小数点后m位,不够补0(四舍五入) %g 不显示小数点后多余的0
七、运算符 自变运算符:++/-- 使变量的值自动+1或者-1 前自变:立即生效 后自变:下一语句才生效 注意:不要在一行中出现多个++ --,很危险 printf("%d%d%d",num++,num++,++num);
算术运算符:+ - * / % / % :除数不为0,否则会产生浮点数例外,核心已转储,程序直接死掉 整数/整数,不会产生小数点 10/3=3 20/3=6 关系运算符: > < >= <= != == 比较的结果是 1(真)或者 0(假),比较结果还能继续参与运算 10<n<100 == 建议:变量放右边,常量放左边 逻辑运算符: && || ! 会把运算对象先转换为逻辑值,0转换假,非0都转换为真 A && B:一假即假 A || B:一真即真 !A : 求反 &&、||短路特性:当左边的值可以确定表达式的结果,那么右边就不计算了 三目运算符: 运算对象有三个部分 A?B:C 判断A是否为真,如果A为真,则执行B,如果A为假,则执行C num = i == 0?99:100; 该语句不能使用流程控制语句,因为它必须要有运算结果 赋值运算符 := += -= *= /= a+=b a=a+b 位运算符:& | ~ ^ >> <<八、类型转换 自动类型转换: 只有相同类型的数据才能进行运算,不同类型的数据转换成相同类型再进行计算。 转换规则(以不丢失数据为基础,适当地牺牲一些空间) 1、字节少的向字节多的转 2、有符号向无符号转 3、整型向浮点型转 强制类型转换: (类型)数据 有丢失数据的风险,慎用 九、条件分支 if(表达式)//单分支 { 表达式为真,则执行此处代码 }
if(表达式)//双分支 { 表达式为真,则执行此处代码 } else { 表达式为假,则执行此处代码 } if(表达式1)//多分支 { 表达式1为真,则执行此处代码 } else if(表达式2) { 否则,表达式2为真,则执行此处代码 } else if(表达式3) { 否则,表达式3为真,则执行此处代码 } else { 1、2、3都不为真,则执行此处代码 }作业: 1、输入三个整数,从大到小显示 2、输入一个年份,判断是闰年还是平年 3、输入一个年份和月份,判断该月有多少天 4、输入一个3位整数,判断是否是水仙花数 abc == aaa+bbb+ccc 5、输入一个成绩,判断级别 [100,90] A (90,80] B (80,70] C (70,60] D (60,0] E other 输入成绩有误