第一章 初识C语言
一、C语言的起源
C 语言是一种高级语言,最初由 Dennis M. Ritchie [1] 为了开发一个操作系统而设计,最早在 1972 年在 DEC PDP-11 计算机上被首次实现。
二、C语言的应用
C 语言大量应用在需要直接硬件交互的场景。比如最近很多的物联网中的嵌入式设备,底层驱动,高性能计算,游戏后端服务,图形处理等等。
三、C语言的特点
代码简洁不繁琐;
具有良好的可移植性,代码与机器底层独立(相对于汇编语言而言);
属于中层编程语言(底层的为汇编语言等,高层的为 Java 语言等);
结构化语言;
丰富的程序库可以使用;
可以直接管理内存;
运行速度快;
提供了指针操作;
可以使用递归;
具有良好的扩展性。
四、编译的过程
着重介绍下编译,其他就是字面意思
编译是把自己编写的源代码转换成可执行的程序,可执行代码是用机器语言表示的代码。这种语言由数字码表示的指令组成。
五、编码机制
1.简述
C编程的基本策略是用程序把源码变成可执行文件来运行~
2.完成机制
C语言通过编译和链接两个步骤来完成这一过程,
编译器把源码转换为中间代码(目标代码文件),连接器把中间代码和库代码、启动代码(程序和OS之间的接口)进行合并,生成可执行文件
C语言通过这样分而治之的方法方便对程序进行模块化,可以独立编译单独的模块,稍后再用链接器合并已编译的模块。通过这种方式,如果只改变某个模块,不必全部重新编译一边,大大提高了效率!
六、在UNIX系统上使用C
一般用gcc编译器来编译
以上a.out就是可执行代码
七、一些OS
1.UNIX系统
UNIX操作系统,当时的电信业巨头AT&T(美国电报电话公司)的贝尔实验室开发的操作系统。 它是一个多用户、多任务操作系统,可以运行在大量不同种类的硬件平台上。
2.Linux
Linux是一个开源、流行、类似于UNIX的OS,Linux实际上只是一个内核,我们可以获得内核的源代码,编译并安装它,然后获得并安装许多其他自由发布的软件,从而完成一个完整的Linux系统的安装。
通常这样安装所得的系统称为Linux系统,系统中大多数的工具都来自于自由软件基金会的GNU项目。自己从源代码创建Linux系统比较麻烦,所以很多人制作了准备好Linux发行版(通常称为flavor),可以通过U盘和CD进行安装,这些发行版不仅包含Linux内核,还会装载一些编程工具和应用程序,一般都会装载一个X视窗系统。
著名的商业Linux发行版 Red Hat Enterprise Linux、Fedora、Novell SuSE Linux 著名的免费的Linux发行版 openSUSE变体、Ubuntu Linux、Slackware、Gentoo、Debian GNU/Linux。
3.GNU项目和自由软件基金会
自由软件基金会(Free Software Foundation) 由Richard Stallman创立,也是Emacs, GCC, GDB的开发者,GNU项目由他发起,这个项目的宗旨是试图创建一个与UNIX系统兼容,并不受UNIX名字和源代码私有权限制的操作系统和开发环境。
GNU项目软件 GCC:GNU编译器集,它包括GNU C编译器。 G++:C++编译器,是GCC的一部分。 GDB:源代码级调试器。 GNU make:UNIX make兼容的语法分析程序生成器。 bash:命令解释器(shell) GNU Emacs:文本编辑器及环境。
4.Windows
就是我们常用的OS,在Windows开发需要借助IDE(集成开发环境)
常用的工具是Mirc Visual Stdio Express
个人比较喜欢用的是Vscode
八、复习题和小结
C语言是编译型语言。C编译器和链接器是把C语言源代码转化成可执行代码的程序
1.对编程而言,可移植性意味着什么?
完美的可移植程序是,其源代码无需修改就可以在不同计算机OS上成功编译
2.解释源代码文件、目标代码文件和可执行文件有什么区别?
源代码文件包含程序员使用任何编程语言编写的代码
目标代码文件是编译后的机器语言代码
可执行文件是经过链接器将目标文件代码和开始文件代码、库文件代码合并成完整的机器语言代码生成的一个可执行程序
3.编程的7个主要步骤是什么?
(1)定义程序目标;(2)设计程序;(3)编写程序;(4)编译程序;(5)运行程序;(6)测试和调试程序:(7)维护和修改程序。
4.编译器的任务是什么?
将源码转换为机器语言代码(也叫目标文件代码)
5.链接器的任务是什么?
链接器将目标文件代码和开始文件代码、库代码合并成完整的机器语言代码生成一个可执行程序
第二章 C语言概述
一、简单的C程序
/* 一个简单的C程序 */ #include <stdio.h> int main(void) { int num; num = 1; printf("I am a simple "); printf("computer.\n"); printf("My favorite number is %d because it is first.\n",num); return 0; }
1.快速概要
这一节先简单介绍一下作用,后面会详细讨论
#include <stdio.h> 包含另一个文件 int main(void) 函数名 /* …*/ 注释 { 函数体开始 int num 声明一个num变量 num = 1赋值表达式语句,把值1赋给名为num的变量 printf("I am a simple "); 调用一个函数 printf(“computer.\n”); 调用另一个函数,在上一条语句后面加上computer并换行,\n的作用是换行 printf(“My favorite number is %d because it is first.\n”,num); 这个printf函数是把num的值嵌套在双引号中和内容一起打印,%d告诉计算机以何种形式输出num的值 return 0; 可以先看作是结束main函数的作用 } 表示程序的结束
2.程序细节
(1)#include指令和头文件
#include <stdio.h>
#include这行代码是一条C预处理指令(preprocessor directive),什么是预处理?就是C编译器在编译之前会对源码进行一些准备工作,即预处理
stdio.h文件。这个包含许多供编译器使用的输入输出函数(printf())该文件。通常在C程序顶部的信息被称为头文件
为什么不内置输入输出函数在语言中,还要每次导入stdio.h文件?
原因之一是,并非所有的程序都会用到I/O(输入输出)包,轻装上阵是C语言的哲学
(2)main()函数
int main(void)
C程序一定从main()开始执行,除了main函数其他函数可以随便命名,main()
int是main()函数的返回值类型。这表明main()函数返回的值是整数,返回到操作系统
通常,函数后面的圆括号中包含一些传入函数的信息。这个例子没有传递任何信息。因此是单词void
没错上面的就算标准形式
不要这样写int main() ,void main()
(3)注释
/*
一个简单的C程序
*/
注释可以卸载任何地方,在注释之间的会被编译器忽略
还有单行注释
//我是单行注释
C++,Java都是一样的方式,C++还没学过,Java的确是这样的哈哈哈
(4)花括号、函数体和块
{
…
}
所有C函数都用花括号标记函数的开始和结束
(5)声明
int num;
在上面的例子中,声明完成了两件事,第一是在函数中有个名为num的变量,第二是int表名num是一个整数
int是关键字
num是标识符,也就是一个变量,函数或其他实体的名称。因此声明把特点标识符与计算机内存中的特点位置联系起来,同时确定了存储在某位置的信息类型或数据类型
C语言中所有的变量必须先声明才能使用。
int main(void) //旧规则 { int doors; int dogs; doors = 5; dogs = 3; //其他语句 return 0; } int main(void) //新规则 { int doors; doors = 5; int dogs; dogs = 3; //其他语句 return 0; }
(6)赋值
num = 1;
把值1赋值给num,不是num = 1,该表达式语句从右侧把值赋到左侧
(7)printf()函数
printf("I am a simple "); printf("computer.\n"); printf("My favorite number is %d because it is first.\n",num);
圆括号表名printf是一个函数名。圆括号中的内容是参数,是实际参数,也就是确切的值
那么形式参数就是函数中用于存储值变量
这个函数可以将括号内的内容打印到屏幕上
(8)return语句
return 0;
可以理解为代码规范,在后面会i详细解释用途
3.程序规范
函数头和函数体
见名知意
使用空行,一条语句一行
写注释
4.多个函数
#include <stdio.h> void buttler(void); //函数原型 int main(void) { printf("I will summon the butler function.\n"); butler(); printf("Yes,Bring me some tea and writeable DVDs.\n"); return 0; } void butler(void) { printf("You rang,sir?\n"); }
该程序输入如下:
I will summon the butler function. You rang,sir? Yes,Bring me some tea and writeable DVDs.
其中butler()函数出现了3次。
第一次是函数原型,作用是告诉编译器要在程序中使用该函数;
第二次调用是函数调用的形式出现在main()中;
最后一次出现在函数定义中,函数定义就是函数本身的源代码
这是因为C的标准建议,要为所有程序中应用到的所有函数提供函数原型。标准include文件为标准库文件提供了函数原型
5.调试程序
(1)语法错误
编程和数学英语有亲密的联系,学习之余可以多学学英语和数学,提高英文阅读能力和逻辑思维能力
#include <stdio.h> int main(void) ( int n,int n2,int n3; /*多行错误 n=5; n2 = n * n; n3 = n2 * n2; return 0; )
1、main()函数体用花括号
2、变量的声明应该这样写
int n , n2 ,n3;
int n;
int n2;
int n3;
3、注释有头有尾
(2)语义错误
n=5; n2 = n * n; n3 = n2 * n2;
程序出错就出现bug,解决bug叫调试程序
6.关键字和保留标识符
就是你不能在起这个名字了,这些词已经被计算机用了
7.小结
(1)C程序由一个或多个C函数组成。每个C程序必须包含一个main()函数,这是C程序要调用的第一个函数
(2)在C语言中,大部分语句都以分号结尾。
(3)声明为变量创建变量名和标识该变量中储存的数据类型。
(4)变量名是一种标识符。
(5)赋值表达式语句把值赋给变量,或者更一般地说,把值赋给存储空间。
(6)函数表达式语句用于调用指定的已命名函数。调用函数执行完毕后,程序会返回到函数调用后面的语句继续执行。
(7)关键字是C语言的词汇!!!
8.编程练习
纸上得来终觉浅,绝知此事要躬行。
#include <stdio.h> int main(void) { printf("Gustav Mahler\n"); printf("Gustav\n"); printf("Gustav\n"); printf("Gustav "); printf("Mahler"); return 0; }
结果:
Gustav Mahler Gustav Gustav Gustav Mahler
这一题还是挺简单的,掌握换行符\n就可以了
#include <stdio.h> int main(void) { printf("My name is pengyuyan.\n"); printf("My address is beijing.\n"); return 0; } My name is pengyuyan. My address is beijing. 3、 #include <stdio.h> int main(void) { int age = 21; int year = 365; int days = age * year; printf("Days are %d",days); return 0; } Days are 7665 4、 #include <stdio.h> void jolly(void); void deny(void); int main(void) { jolly(); jolly(); jolly(); deny(); return 0; } void jolly(void) { printf("For he's a jolly good fellow!\n"); return; } void deny(void) { printf("Which nobody can deny!\n"); return; } For he’s a jolly good fellow! For he’s a jolly good fellow! For he’s a jolly good fellow! Which nobody can deny! 5、 #include <stdio.h> void br(void); void ic(void); int main(void) { br(); printf(", "); ic(); printf("\n"); ic(); printf(",\n"); br(); return 0; } void br(void) { printf("Brazil, Russia"); return; } void ic(void) { printf("India, China"); return; } #include <stdio.h> int main(void) { int toes = 10; printf("toes = %d\n", toes); printf("toes * 2 = %d\n", toes * 2); toes = toes * toes; printf("toes ^ 2 = %d\n", toes); return 0; #include <stdio.h> void smile(void); int main(void) { smile(); smile(); smile(); printf("\n"); smile(); smile(); printf("\n"); smile(); printf("\n"); return 0; } void smile(void) { printf("Smile!"); return; #include <stdio.h> void one_three(void); void two(void); int main(void) { printf("Starting now:\n"); one_three(); printf("Done!\n"); return 0; } void one_three(void) { printf("one\n"); two(); printf("three\n"); return; } void two(void) { printf("two\n"); return; }
第三章 数据和C
一、示例程序
#include <stdio.h> int main(void) { float weight; float value; printf("Are you worth your weight in platinum\n"); printf("Let`s check it out.\n"); printf("Pleasee enter your weight in pounds:\n"); /* 获取用户输入 */ scanf("%f",&weight); value = 1700.0 * weight * 14.55833; printf("Your weight in platinum is worth $%.2f.\n",value); printf("You are easily worth that! If platinum prices drop,\n"); printf ( "eat more to maintain your value. \n"); return 0; }
结果为:
Are you worth your weight in platinum Let`s check it out. Pleasee enter your weight in pounds: 123 Your weight in platinum is worth $3044146.75. You are easily worth that! If platinum prices drop, eat more to maintain your value.
欧美日常使用的度量衡单位是常衡盎司( avoirdupois ounce ),而欧美黄金市场上使用的黄金交易计量单位是金衡盎司( troy ounce )。国际黄金市场上的报价,其单位“盎司”都指的是黄金盎司。常衡盎司属英制计量单位,做重量单位时也称为英两。相关换算参考如下:1常衡盎司=28.350克,1金衡盎司=31.104克,16常衡盎司=l磅。该程序的单位转换思路是:把磅换算成金衡盎司,即28.350÷31.104×16=14.5833。——译者注
1.程序细节
为了打印新类型的变量,在printf()中使用%f来处理浮点值。%.2中的.2用来精确控制,指定输出的浮点数只显示小数点后两位
%f说明scanf()要读取user键盘录入的浮点数,&weight告诉scanf()把输入的值赋给weight变量,scanf()使用&找到变量weight的地点。后面会详细说明&的作用
二、变量与常量数据
1.常量
有些数据类型,在程序运行前就已经定义好了,在运行过程中没有变化,这些称为常量
2.变量
其他数据类型在程序的运行过程中可能被改变和赋值,这些称为变量
三、数据类型关键字
位、字节、字和字长
弄了好久都没分清,看了这书后,我可以了
当然不用清除到底,就像刚学开车不需要掌握汽车的原理一样
首先,位、字节、字都是计算机数据单元或存储单元的术语
位是计算机存储的最小单位要么是0或1
字节是计算机常用的存储单位,1个字节(Byte)等于8位(bit)
计算机每个字所包含的位数称为字长,指计算机一次能处理的二进制数字的数目,字长越大计算机处理的越快
字(word)是计算机的自然存储单位,对于8位的计算机1个字长只有8位