为什么学习C语言
- 操作系统编程
- 内存管理、服务器
- 操作系统设计
- 大部分系统使用C语言实现
- 网络协议实现
- 局域网、互联网数据传输
- 物联网和嵌入式编程
- Linux编程
- 实现其他语言
- 解释形
- 解析器实现大多数都是C/C++
- 编译型
- 高效率编译器的实现也离不开C语言
- 解释形
C语言历史
为了玩游戏编写了一套操作系统
C 语言的产生,还是有一些故事的。在很久很久以前,那个时期的计算机系统还处在批处理阶段,技术不发达导致了运算速度十分缓慢,也使得程序员工作效率低下。当时他们只能在运算速度缓慢笨重的大型机器上工作,操作也十分繁琐:需要先将程序卡片装入设备,然后等一个多小时才能获取运算结果。……在知名的贝尔实验室,有一个叫 Ken Thompson 和另一个叫 Dennis M. Ritchie 的工程师,他们被共同称为“C 语言之父”。
他们为了在实验室角落里一台 PDP-7 小型机上写一个让自己可以不用花多少钱就可以玩的《星际旅行(Star Travel)》的游戏,用汇编语言编写了一个操作系统,并把这个系统命名成了 Unix。
后面又出现了B语言替代了汇编,因为B语言编写的程序无法移植到其他类型的机器上,当PDP-11出来后,为了将PDP-7上的B语言移植到PDP-11上又开发了NB语言,这就是C语言的前身,1972年NB语言改名为C语言。在1973年Dennis和Ken一起使用C语言重写了Unix系统。
后又有大神Linus
Early C
- 1969: B created, based on BCPL, to replace PDP-7 assembler as the system programming language for Unix
- 1971: NB ("new B") created when porting B to PDP-11
- 1972: Language renamed to C
- 1973: Unix re-written in C
- 1978: The C Programming Language, 1st edition
Standard C
- 1988: The C Programming Language, 2nd edition
- 1989: C89, the ANSI C standard published
- 1990: C90, the ANSI C standard accepted as ISO/IEC 9899:1990
- 1995: C95 (ISO/IEC 9899:1990/Amd.1:1995) (online store)
- 1999: C99 (ISO/IEC 9899:1999)
- 2011: C11 (ISO/IEC 9899:2011) (ISO store) (ANSI store) (April 12, 2011 draft)
- 2018: C17 (ISO/IEC 9899:2018) (ISO Store) (Final draft)
- 2023: C23 Next major C language standard revision
环境准备
C 语言即可以在Windows、也可以在macOS(Unix内核)或者Linux(类Unix)上进行开发, 需要注意平台之间的差异, 例如Windows环境下的一些库文件和函数有些"特立独行", 除了系统的差异, 也存在编译工具的差异,例如微软平台下的宇宙第一IDE的Visual Studio与其他IDE相比就存在明显的区别。
C 语言在 Unix 上被设计出来,也被基于 Unix 的操作系统更好地支持。如果你希望更顺利地学习 C 语言,使用基于 Unix 的操作系统将会是很好的选择。同时,多数情况下你将会需要使用命令行工具来进行操作。
Windows环境配置
一般IDE会自带编译环境。你也可以选择使用自己的编译环境,一般Windows上常用的C/C++编译环境是MinGW(Minimalist GNU for Windows)。为了安装 MinGW,请访问 MinGW 的主页 ,进入 MinGW 下载页面,下载最新版本的 MinGW 安装程序,命名格式为 MinGW-
Linux环境配置
macOS环境配置
文本编辑器和IDE选择
对于程序语言的初学者来说,不要轻易地使用太复杂的IDE(integrated development environment,集成式开发环境),如:
-
Visual Studio Conmmunity(IDE)
-
Visual Studio Code(IDE)
-
JetBrain CLion
因为IDE 会隐藏很多本来应该让你学习到的知识,如果坚持要使用 IDE,对于初学者推荐你使用 Dev C++ 或 Code::Blocks 这种相对轻量的 IDE),像VC6.0这种古老的IDE就不推荐使用了。
-
Dev-C++(IDE)
-
Code Blocks(IDE)
也推荐使用 Atom、Sublime、NotePad++、Gedit、Nano、Emacs、Vim 这些编辑器,其中Vim、Atom、Sublime经过适当的配置也是可以达到接近IDE的效果的。如果可能,你都可以试一试,找到你最顺手的那个。
-
Sublime
-
Vim(Editor)
Windows系统运行Linux
- 运行Linux虚拟机
- VMwareStation/VirtualBox
- Centos 7
- 运行WSL(WindowSubLinux)
- Win10
Hello World 程序代码及说明
C语言版本
1 2 3 4 5 6 |
#include <stdio.h> int main() { printf("hello, world!\n"); return 0; } |
#
编译预处理行#include
文件预处理命令 – 包含文件#include<stdio.h>
让C语言负责标准输入输出流库的头文件包含到此处main()
主函数,代表程序的执行入口, 主函数有一个整数返回值printf()
格式化输出函数, 声明自stdio.h
头文件return 0;
退出main()
函数,向调用线程返回执行结果(返回0代表程序正常退出, 返回非0代表异常退出).
C++语言版本
C++介绍
从C++(读作 C Plus Plus)的名字看, 就知道它比标准C多出太多东西了, C几乎是C语言的超集, 但也有少量特性是C所不支持的。C++ 比 C 多了 classes、templates、exceptions 这些部分,而每个部分也有很多新增的东西。这还只是语言部分,还未谈及标准库。C 有 29 个标准库头文件,C++ 有 87 个,除了量,C++ 标准库的功能要复杂得多。是目前最难掌握也是最为复杂的语言。
我们课程学习所使用的C++只用到C++特性中最简单的部分,并且不涉及面向对象、模板、异常等复杂的部分。
编写C++的hello world
程序很简单, 注意后缀使用cpp或者cc, 表示这是C++的源代码文件.
1 2 3 4 5 6 7 8 |
#include <iostream> using namespace std; int main() { cout << "hello world" << endl; return 0; } |
iostream
C++定义的输入输出流库, 定义了输入流对象cin和输出流对象cout对象using namespace std;
使用std命名空间, 命名空间用于避免命名冲突问题, std是C++自带的名称空间, 其种cout,cin和endl都位于这个名称空间下.cout
是iosteam
库中ostream
类型对象,用于将<<
右侧的内容输出到显示屏endl
是iostream
库中定义的IO操纵符,表示换行并刷新流
GCC
GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、Java、Fortran、Pascal、Object-C、Ada等语言。
- gcc是GCC中的GUN C Compiler(C 编译器)
- g++是GCC中的GUN C++ Compiler(C++编译器)
gcc和g++的主要区别
- 对于 .c和.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法是不一样的)
- 对于 .c和.cpp文件,g++则统一当做cpp文件编译
- 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
主要参数
1 2 3 4 5 6 7 8 |
-g - turn on debugging (so GDB gives morefriendly output) -Wall - turns on most warnings -O or -O2 or -O3 - turn on optimizations level 1~3 -o - name of the output file -c - output an object file (.o) -I - specify an includedirectory -L - specify a libdirectory -l - link with librarylib.a |
GCC编译的4个阶段
-
预处理阶段:预处理器(cpp)
123$ gcc -E hello.c -o hello.i# 加上-P可以生成内容弄个更精简的文件$ gcc -E -P hello.c -o hello.i预处理阶段主要做的事情是:
- 删注释
- 替换宏定义
- 替换#inlcude文件
-
编译阶段:编译器(ccl)
1$ gcc -S hello.i -o hello.s编译器将预处理的文件编译成汇编指令。
-
汇编阶段:汇编器(as)
1$ gcc -c hello.s -o hello.o汇编器将汇编指令转换为二进制目标文件。
也可以把汇编和链接阶段合称为编译阶段,生成的.o目标文件可以使用nm命令列出所有符号,其中U表示的是未定义的符号。12345➜ nm hello.oU _GLOBAL_OFFSET_TABLE_0000000000000000 T mainU puts -
链接阶段:链接器(ld)
1$ gcc hello.o -o hello也可以使用-save-tmps选项保存中间生成的临时文件,如:
123➜ gcc -Wall -save-temps hello.c -o hello➜ lshello hello.c hello.i hello.o hello.out hello.s-Wall
显示所有编译警告信息
如果编译成功,我们在同一个目录下可以得到一个编译后的可以执行的hello文件,可以在同一目录下使用./hello
命令运行。
如果你选择了使用 IDE,你需要了解一下自己的 IDE 的编译和运行功能被设计成了什么样的菜单选项或按钮。每次先编译,确认编译通过后再运行。
输出流对象cout
cout
是C++中 ostream
类型的对象,该类被封装在 <iostream>
库中,该库定义的名字都在命名空间 std
中,所以 cout
全称是 std::cout
。
cout
使用方式
std::cout
1std::cout << "Welcome to Tsinghua" << std::endl;- 使用 std 命名空间后,简写成
cout
123use namespace std;......cout << "Welcome to Tsinghua" << endl;
算术运算符
C/C++支持5种常见的算术运算符(operator),分别是:
+
加-
减*
乘/
除%
取余(取模)
除了取余运算符要求两边的操作数(operand)是整数外,其余加、减、乘、除运算要求两边操作数是实数即可。
数学函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* 计算 sin(20°) + cos(20°) - cos(20°) / tan(20°) 需要引入cmath库的三角函数, 参数单位为弧度 弧度与角度之间的转换公式: 弧度=角度 /180 × π */ #include <iostream> // 预编译 - io流库 - 输入输出 #include <cmath> // 预编译 - cmath库 - 三角函数 using namespace std; // 使用命名空间 int main() { // 主函数 const float PI = 3.14159; printf("%f \n", sin(30.0 / 180 * PI)); cout << sin(20.0 / 180 * PI) + cos(20.0 / 180 * PI) - cos(20.0 / 180 * PI) / tan(20.0 / 180 * PI) << endl; return 0; // 返回0 代表程序正常结束 } |
注意,上面程序30.0/180
如果改成30/180
则结果为0,这时因为计算时发生了隐式类型转换
其他常用数学函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
**************************************** Author: Delucia Ver.: 0.0 Date: 2020年1月5日01:06:14 Description: 附录B - 库函数 B.1数学函数 弧度转角度 2π = 360° 正弦函数, 参数x为弧度值 - double sin (double x) *****************************************/ #include <iostream> #include <cmath> #include <cstdlib> using namespace std; int main() { // 对不同类型的 n, 计算 |n| cout << abs(-4294967295) << endl; cout << labs(-4294967296L) << endl; cout << fabs(-3.1415926535) << endl; // sin 90 = 1 cout << sin(3.1415926/2.0) << endl; cout << asin(1) << endl; cout << cos(3.1415926535/2.0) << endl; cout << acos(4.48966e-011) << endl; cout << tan(45.0*3.1415926535/180.0) << endl; cout << atan(1) << endl; cout << exp(1) << endl; cout << exp(2.302585093) << endl; cout << log(exp(1)) << endl; cout << log10(10) << endl; cout << pow(2.0, 3.0) << endl; cout << sqrt(25.0) << endl; cout << floor(4.8) << endl; cout << floor(-4.8) << endl; return 0; } |
注释
文件头注释
1 2 3 4 5 6 7 8 9 10 11 |
//*************************************** // FileName: 2-4-1comments.cpp * // Author: Delucia * // Date: 2020年1月4日20:13:03 * // Description: How to use Comments * //*************************************** int main() { return 0; } |
单行注释
1 |
// 被注释的行 |
多行注释
1 2 3 4 |
/* 被注释的行 被注释的行 /* |
- 编程初学者尽量多写注释
- 有经验的程序员会尽量让代码达到自解释效果,只对必要的地方写上注释
- 建议养成写注释的习惯(难)
作业
将上面练习改写为C++的版本,并手动编译运行.
学习资源参考
- NIIT云课堂
- 慕课网(imooc)
- 网易云课堂
学习文档资源参考
- Google/Baidu
- StackOverFlow
- GitHub
- CSDN
- 菜鸟教程
- Cpp Reference
Views: 28