本章介绍以下内容:
- 计算机系统架构:硬件和软件
- 编程语言的发展历程及其特性和使用场景
- 主流桌面系统(Windows,Linux,Mac)的C语言开发环境的搭建
- C程序运行在各大操作系统
- C语言运行原理
- C语言的实用小程序
- 软件开发流程
- C语言模块化编程的思想
计算机系统架构通常是由硬件系统和软件系统两大部分组成。
通常是应用软件(微信,迅雷)运行在系统软件-操作系统(Windows,Linux,MacOS)之上,而操作系统负责和底层硬件系统(CPU,内存,硬盘)交互。软件开发就是指的运用某种程序设计语言(例如C/C++/Java/Pyhton/Go…)编写系统软件或者是应用软件,目前主流的技术趋势是移动互联网(Android,IOS,手游),云计算和大数据,物联网,以及即将火爆的人工智能和机器学习。
通常计算机核心硬件包含CPU,内存,硬盘以及IO设备组成。
下面来认识下各大组件的作用:
CPU:也被称为中央处理器,由运算器和控制器组成,其主要作用是用来计算数据(从内存中获取指令并执行后将结果返回给内存或者写入到磁盘)和控制其他设备协同工作。
内存:其主要作用是用来作为程序的工作区,程序运行时会被加载到内存,断电后数据会丢失。
硬盘:其主要作用是永久性存储海量(PB)的数据,分为机械式硬盘(HDD)(7500rpm,15000rpm)和固态硬盘(SSD)两大类。
IO设备:其主要作用是用来数据的输入输出,常见的输入设备包括鼠标键盘,常见的输出设备包含声卡,显卡,打印机等等。还有个典型输入输出设备:网卡主要是负责数据在网络上的传输。
在程序故障诊断或者做程序性能优化是时除了考虑程序自身之外还需要考虑CPU,内存,磁盘和网卡的状况。
组件名称 | 延时、带宽 |
---|---|
CPU | |
Cache L1,L2,L3 | 0.5-15ns、20-60GB/S |
内存 | 30-100ns、2-12GB/S |
SSD硬盘 | 10us-1ms、50MB-2GB/S |
普通硬盘 | 5-20ms、50-200MB/S |
网卡-网卡 | 100us-1ms、10MB-10GB/S |
从该表格中可以看出CPU延时(最低)和带宽(最高),而普通硬盘是性能最差的,根据木桶效应,在性能优化时应该优先优化磁盘。
软件的出现实现了人和计算机之间更好的交互
计算机软件分为系统软件和应用软件两大类,如下列表中包含常见的软件及其运行平台。
人机交互方式 | 系统名称 | 平台 |
---|---|---|
命令行界面 | Unix(Solaris,HP Unix,AIX),Linux(CentOS) | 服务器 |
图形界面 | Windows10,MacOS10.13,Linux(Ubuntu16.04) | 桌面 |
自然交互界面 | Android8.0,IOS11 | 嵌入式(手机、汽车、电视) |
类型 | 名称 | 平台 |
---|---|---|
通讯 | 微信 | Windows,MacOS,Android,IOS |
购物 | 京东、天猫 | Windows,Android,IOS |
办公 | WPS,Office | Windows,Mac |
目前在典型的中小型互联网公司的应用软件的后台业务逻辑通常都是采用Java或者Python,C/C++/Go实现。前台展示通常包含PC,H5,android,ios和微信小程序。
系统软件主要实现和底层硬件交互,给应用软件提供运行平台。操作系统、编译器等都是属于系统软件,目前主流的桌面操作系统是Windows,Linux(Ubuntu),MacOS,主流的移动端操作系统是Android,IOS,主流的服务端操作系统是Linux(CentOS,Ubuntu)。
应用软件主要是运行在PC或者是移动终端的操作系统之上,用于解决工作和生活的各种需求,例如购物(淘宝、天猫、京东),聊天(微信、QQ),听音乐(QQ音乐、网易云音乐),看电影(爱奇艺、暴风影音),收发邮件(Foxmail)等等。
Windows/Linux(Ubuntu):Razer雷蛇 灵刃专业版
硬件配置一览
MacOS:MacBookPro 15
配置和价格一览
开发者推荐最低硬件配置:i7 CPU+ 512G固态硬盘+16G内存+GTX1070
Windows | MacOS | 功能描述 |
---|---|---|
VMWareWorkStataion12 Pro | Parallels Desktop 12 Pro | 虚拟机 |
微信 | 微信 | 及时通讯 |
钉钉 | 钉钉 | 企业办公 |
WPS/Office | Office | 办公软件 |
Ultraedit | Ultraedit | 文本编辑 |
福昕PDF阅读器 | PDF Expert | PDF阅读器 |
百度网盘 | 百度网盘 | 文件存储 |
QQ音乐 | QQ音乐 | 音乐播放 |
Teamviewer | Teamviewer | 远程控制 |
XMind | XMind | 思维导图 |
KMPlayer | KMPlayer | 视频播放 |
迅雷 | 迅雷 | 下载 |
Chrome | Chrome | 浏览器 |
IntelliJ IDEA | IntelliJ IDEA | Java开发 |
VisualStudio2017 | VisualStudio2017 | C/C++开发 |
Git | Git | 源码版本控制 |
MySQL | MySQL | 数据库 |
SecureCRT | SecureCRT | Linux SSH客户端 |
Axure RP 8 | Axure RP 8 | 原型图 |
如果是想开发Windows和Linux程序
推荐在Windows开发机上先安装Windows10 x64企业版,然后通过安装的VMWareWorkStation12虚拟机上安装Linux/CentOS7.3、Linux/OpenSUSE42.2和Linux/Ubuntu16.04三个常见的Linux发行版。
如果是想开发MacOS程序
MacBookPro则是安装了最新的MacOS10.13,由于极少数必备软件(例如RedisDesktopManager,WPS),同时通过Mac平台上的虚拟机Parallels Desktop 12 安装了Windows10以及一些Mac平台上缺失的软件。
这样基本就可以覆盖所有主流的PC/服务端操作系统。
如果想测试Android或者是IOS,再买个三星Note8和iPhone 8,安装最新版的操作系统即可。
再推荐一些MacOS平台上非常好用的软件
- XCode(开发IOS,Mac,Apple Watch应用的利器)
- iTem2(shell client)
- Atom(文本编辑器)
- CleanMyMac(系统清理优化)
- GitBook(开源的写书软件)
- MWeb(MarkDown写作)
- 2Do(任务计划)
- Dash(帮助文档)
- Charles(HTTP网络监视、代理)
- Tower(Git客户端)
- ScreenFlow(录屏)
- Adobe PhotoShop 2017
- StartUML(UML)
编程语言经历了机器语言-汇编-高级程序设计语言三个阶段,其显著的变化特点就是程序的开发、测试、运维越来越变得更加简单。
先了解下2017年 7月 TIOBE 编程语言排行榜
目前主流的语言是C/C++/Java/Python/C#/PHP/Go/Swift/Objective-C
机器语言
想让计算机做事情就必须采用某种指令系统(它是由计算机系统的基本运算构成)来指挥计算机进行计算,存储和传输数据等任务,而大型服务器(非X86精简指令系统),PC,笔记本(X86复杂指令系统)以及手机(ARM精简指令系统)所采用的指令系统是不尽相同的,这也就意味着PC上的程序不加修改就不能到手机上运行,手机上的程序不加修改也不能到PC上运行。
程序就是指令系统加上数据集组成,而每个CPU都有自己的指令系统(由二进制的机器码010101序列组成),这也就是最早的编程语言-机器语言的由来,它的特点是特别高效,不能移植,不易开发和后期维护等等。
汇编语言
随着时代和计算机技术的发展,汇编语言和编译器的出现解决了需要记住非常多的二进制机器指令的难题,但是还是没有从根本上解决移植性的问题,只是将机器指令转换为易懂的英文单词,然后由编译器编译成机器指令,因为计算机终归揭底只能识别0001110100110机器指令,而且汇编语言是面向机器的,不同机器(Intel,ARM平台)的汇编指令是不相同的。 而汇编的使用场景只有在追求绝对性能的场合中使用。
C语言嵌套汇编语言的案例
#include
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/14/15/11
程序说明:C语言嵌套汇编的案例
*****************************/
void use_asm() {
int a, b, c = 0; //初始化声明三个整数变量并赋值为0
a = 4;
b = 6;
printf("before a=%d\tb=%d\tc=%d\n", a, b, c);
_asm {
//将变量a的值赋值给eax寄存器
mov eax, a;
//将变量b的值和寄存器eax相加
add eax, b;
//将相加的结果赋值给c
mov c, eax;
}
printf("after a=%d\tb=%d\tc=%d\n", a, b, c);
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/14/15/10
程序说明:入口方法
*****************************/
void main() {
use_asm();
getchar();
}
C语言经历了45年的发展,已经广泛用于操作系统(Windows,Linux,MacOS)、计算机编程语言(Java,Python…)、游戏、PC应用等领域开发,后期出现的C++,Python,Go等程序设计语言在许多方法都借鉴了它的优势。
C语言在1972年诞生于美国的贝尔实验室,由Dennis Ritch和Ken Thompson在开发Unix操作系统时设计的,该操作系统的90%以上的代码都是由C语言实现。
优点
缺点
操作系统
驱动程序
游戏引擎
网站后台
程序设计语言
物联网
云计算、大数据
C语言的产品:操作系统(Unix,Linux,Windows,MacOS,Android),Web服务器(Nginx),NoSQL数据库(Redis),分布式版本控制系统(Git)。
目前主流操作系统(Windows,Linux,MacOS)都有完善的C语言集成开发环境,用于编辑、编译、调试、打包部署C程序。
操作系统 | 开发工具 |
---|---|
Windows | VisualStudio2017 |
Linux(Ubuntu) | QT5.9 |
MacOS | XCode8.3 |
Windows作为最流行的桌面操作系统,最新版本为Windows10,VisualStudio作为Windows上最强大的集成开发环境,可以开发Windows软件,游戏,Web应用等等,最新版本为VisualStudio2017。
Ubuntu作为最受欢迎的桌面版Linux系统之一,推荐采用跨平台的QT来编写C/C++程序。
MacOS平台推荐使用XCode来编写C/C++程序。
在安装好Windows10创意者正式版和从VisualStudio官网下载ViualStudio2017的安装文件(vs_Enterprise.exe)之后,便可以开始安装VisualStudio2017。
接下来采用图文并茂的形式展现VisualStudio2017在Windows10上的安装过程
1 双击下载的VS_Enterprise.exe文件
2 同意条款,继续
3 选择VisualStudio的安装组件并安装
4 开始下载组件并安装
此过程耗时较长,因机器的性能而异
5 完成安装并启动
6 登录VisualStudio2017
如果没有Microsoft账号,去官网注册一个即可
7 启动界面
在编写HelloWorld之前,为了团队协作的考虑,通过插件将GitHhub集成到VisualStudio中来。
1 启动VisualStudio2017并找到工具-扩展和更新
2 联机搜索GitHub并下载
1 启动Visual Studio后在团队资源管理器视图找到连接管理
点击Connect…
后续的代码都会存储在CoreProject仓库,并会推送到https://github.com/tonytimemachine/CoreProject。
下载地址:https://www.wholetomato.com/downloads/downloadTrial.asp
安装过程十分简单:直接双击安装文件安装即可
1 选择菜单 VAssistX->Visual Assist Options
3 创建新的模板
QT5.9下载地址:http://download.qt.io/official_releases/qt/5.9/5.9.1/qt-opensource-linux-x64-5.9.1.run 只需要将该地址复制到浏览器中即可下载。
2 更改用户密码,切换root用户,修改下载文件的执行权限
tony@ubuntu:~$ sudo passwd
[sudo] password for tony:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
3 切换root用户
tony@ubuntu:~$ su root
Password:
4 进入下载目录并查看文件
root@ubuntu:/home/tony# cd Downloads/
root@ubuntu:/home/tony/Downloads# ls -al
total 1008576
drwxr-xr-x 2 tony tony 4096 Aug 10 13:10 .
drwxr-xr-x 17 tony tony 4096 Aug 10 13:15 ..
-rw-rw-r-- 1 tony tony 1032768780 Aug 10 13:10 qt-opensource-linux-x64-5.9.1.run
5 执行安装
发现权限不允许,使用chomd u+x添加执行权限
root@ubuntu:/home/tony/Downloads# ./qt-opensource-linux-x64-5.9.1.run #执行安装
bash: ./qt-opensource-linux-x64-5.9.1.run: Permission denied
root@ubuntu:/home/tony/Downloads# chmod u+x qt-opensource-linux-x64-5.9.1.run
root@ubuntu:/home/tony/Downloads# ./qt-opensource-linux-x64-5.9.1.run
QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0
MacOS的Xcode通常都是随系统自带,无需额外的安装。
helloworld程序通常是学习一门编程语言的入门程序,如果能够正常编译运行helloworld,就表示编译和运行环境已经搭建完成。
本程序的目的是为了使用C语言实现HelloWorld在Windows上运行
1 在团队资源管理器视图的CoreProject仓库下创建一个解决方案:Chapter1
源码如下:
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/14/15/33
程序说明:向控制台输出一段指定的内容后等待用户输入任意字符退出程序
*****************************/
void main() {
printf("Hello World In Window10 With Visual Studio 2017 Enterprise");
getchar();
}
1 New Project
2 Non-Qt Project
Plain C Application
3 Project Location
设置项目名称和项目路径
4 Define Build System
5 Kit Selection
6 Project Management
HelloWorld源码:
#include
int main()
{
printf("Hello World!\n");
getchar();
return 0;
}
7 程序运行结果
1 创建项目
2 选择项目模板
3 设置项目信息
4 添加版本控制
自动生成的源码如下:
//
// main.c
// C
//
// Created by tony on 2017/8/10.
// Copyright © 2017年 tony. All rights reserved.
//
#include
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
getchar();
return 0;
}
5 编译并运行
在使用VS2017编写helloworld的源代码以及相关的头文件时,使用其提供的快捷键F5编译并运行了程序,但这背后实际上还包含了预编译,转汇编,编译,链接四个步骤。
接下来将采用Linux(CentOS7)操作系统的C语言环境结合GCC编译器的一些编译选项来解剖C语言的运行原理。
[root@tony Desktop]# cd /home/guanglei/Desktop/ #进入桌面
[root@tony Desktop]# gedit helloworld.c #使用gedit编辑c语言的源文件
helloworld.c源代码如下:
#include //引入跨平台的标注输入输出头文件
#include //引入跨平台的标准库头文件
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 19:32
修改日志:
*****************************/
int main(){
printf("This program is running CentOS7 \n!!!");
system("date"); //显示当前系统日期
system("ps -ef|grep java");//查看运行的java进程
return 0;// 返回0表示正常退出
}
第一步 预编译
预编译就是将include包含的头文件的内容替换到源文件中,同时将代码中注释的内容删除,使用gcc编译器的-E选项实现预编译:
[root@tony Desktop]# gcc -E helloworld.c -o helloworld.e #-o表示输出的文件名称
[root@tony Desktop]# gedit helloworld.e #使用geit查看预编译后的结果
第二步 转汇编
C语言的源代码计算机是不能识别的,因此在运行之前需要将其转换成汇编语言,可以通过gcc编译器的-S选项来实现转换成汇编:
[root@tony Desktop]# gcc -S helloworld.c -o helloworld.e
第三步 编译
计算机只能识别二进制的机器码,编译器会将汇编指令转换成二进制的机器码,可以使用gcc编译器的-c选项来实现转换成二进制:
[root@tony Desktop]# gcc -c helloworld.c -o helloworld.o #编译成二进制
第四步 链接
在编译成机器码之后程序还不能够直接运行,还需要一个链接的过程,就是将C语言库函数、启动代码以及源码转换后的二进制文件打包到一起组成可执行的文件。
这些步骤可以一次实现(预编译,编译和链接)
[root@tony Desktop]# gcc -o helloworld.o helloworld.c
[root@tony Desktop]# ./helloworld.o #运行改程序并显示结果
Windows系统包含大量的系统命令,提供了日常使用的绝大部分功能,实际上Windows系统图形化界面操作的背后就是在调用这些系统命令,学会这些常用的命令可以让我们更加方便和快捷的使用Windows系统提供的功能。
要想使用命令,必须启动一个cmd命令窗口,使用Windows+R,输入cmd后即可启动命令行窗口,
cmd运行示意图:
当看到如上图所示的命令行界面之后就可以输入Windows提供的命令来完成日常绝大部分操作的功能了。
下面将介绍常用的Windows命令行提供的指令
文件管理命令集
dir #列出当前目录列表
md #创建目录
rd #删除目录
cd #进入指定的目录(windows只能在当前盘符下切换)
del #删除文件
exit #退出cmd命令行
type #显示文件内容
实用程序和系统管理命令集
calc #计算器
notepad #记事本
mspaint #画图
timedate.cpl #日期和时间
cleanmgr #磁盘清理工具
CompMgmtLauncher #计算机管理
desk.cpl #屏幕分辨率
perfmon #计算机性能检测器
powercfg.cpl #电源选项
regedit #注册表编辑器
shutdown -s
services.msc #本地服务设置
Msconfig #系统配置
msinfo #系统信息
mstsc #远程连接
explorer #资源管理器
firewall.cpl #防火墙
taskkill /f /im process.exe #关闭指定的进程
appwiz.cpl 程序和功能(添加或者卸载程序)
control 控制面板
除了在cmd命令行窗口调用这些程序之外,C语言提供了一个位于stdlib.h头文件的system函数来调用各大操作系统(Windows,Linux,MacOSX,Android,IOS都可以)。
使用system函数调用Windows命令示例:
#include
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 20:24
程序说明:根据传递的命令字符串调用系统命令
*****************************/
void call_system(char str[]) {
printf("你输入的要执行的命令是%s\n", str);
system(str);
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 20:34
程序说明:程序入口
*****************************/
void main() {
char str[100] = { 0 }; //定义一个字符数组 数组中的每个元素初始化为0
printf("请输入system函数调用windows系统命令的名称\n");
scanf("%s", str); //将输入的命令字符串赋值给str
call_system(str);
call_system("pause");
}
call_system()方法用于读取输入的指令并调用,main方法主要是提示用户输入命令,然后执行并暂停,等待输入任意字符退出。
默认system函数是同步执行的:
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 21:00
程序说明:system函数的同步
*****************************/
void main() {
system("notepad");//打开记事本
system("calc&pause");//打开计算器并暂停
}
当运行以上程序时,程序只会打开记事本,而不会执行打开计算器并暂停的代码,因为system函数默认是同步执行的,如果想要异步执行,可以在执行的命令前面加上start,但是start后面不能跟路径,如果是带路径的命令必须先提前进入该命令或者程序所在的目录。
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 21:12
程序说明:system函数的异步
*****************************/
void main() {
system("start notepad"); //异步打开记事本
system("calc&pause");
}
当运行程序时,会同时打开记事本以及计算器程序。
使用Windows系统库函数ShellExecuteA函数实现异步打开和关闭程序
#include
#include
#incldue
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 21:24
程序说明:根据传递的字符串执行system函数调用系统命令
*****************************/
void start_process(char str[]) {
printf("你输入的要执行的命令是%s\n",str);
char execute_str[100] = {0};
strcpy(execute_str, "start ");
ShellExecuteA(0,"open",str,0,0,1); //异步执行打开指定的进程
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 21:34
程序说明:关闭指定的进程
*****************************/
void kill_process(char str[]) {
printf("你要终止的进程名称为%s\n",str);
char kill_str[100] = { 0 };
strcpy(kill_str,"start ");
strcat(kill_str, "taskkill /f /im ");
strcat(kill_str,str);
strcat(kill_str, ".exe");
printf("执行结束进程的字符串内容是%s",kill_str);
system(kill_str);
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 21:52
程序说明:定义程序主入口
*****************************/
void main() {
char str[100] = {0}; //定义一个字符数组 数组中的每个元素初始化为0
printf("请输入system函数调用windows系统命令的名称\n");
scanf("%s",str); //将输入的命令字符串赋值给str
start_process(str);
Sleep(5000); //程序此处会暂停5S
kill_process(str);
system("pause");
}
在互联网公司中,软件一般会由产品经理和市场运营的同事沟通需求,并形成PRD需求文档,然后由UI设计素材形成PSD,然后由负责前台开发的人员制作成HTML,再由后台开发人员(Java,PHP)实现业务逻辑,测试人员进行业务测试,压力测试以及系统集成测试,运维人员实现环境搭建和部署。
而软件在开发阶段除了编码之外最常见的就是查找Bug了,通常都是在代码的某行可能出现错误的地方通过设置断点来观察程序执行的过程中变量的值发生变化来查找错误。
这里编写一个简单的C语言程序,通过设置断点借用VisualStudio2017强大的调试功能来观察程序运行的过程,源代码如下:
#include
#include
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 22:24
程序说明:程序调试
*****************************/
void main() {
int age = 28;
printf("整数变量age的值为%d\n",age);
printf("整数变量age的地址为%p\n",&age);
system("pause");
}
使用VisualStudio2017强大的调试功能观察简单C程序的运行过程
C语言的程序由众多的函数组成,而在日常的开发中,可以将一个完整的业务逻辑封装在多个函数中,例如下面的开启和关闭QQ。
#include
#include
#include
/*C语言模块化编程*/
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 22:22
程序说明: 打开QQ
*****************************/
void openQQ() {
system("\"C:/Program Files (x86)/Tencent/QQ/Bin/QQScLauncher.exe\"");
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 22:32
程序说明: 按照指定的时间中断
*****************************/
int sleep() {
printf("请输入关闭QQ的时间");
int seconds = 0;
scanf("%d",&seconds); //读取输入的秒数
return seconds;
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 22:42
程序说明: 关闭QQ
*****************************/
void close() {
system("taskkill /f /im QQ.exe");
}
/*****************************
作者:刘光磊
联系方式:[email protected]
创作日期:2017/8/10/ 22:12
程序说明: 程序主入口
*****************************/
void main() {
openQQ();
int seconds = sleep();
Sleep(seconds*1000);
printf("QQ将在%d秒后关闭",seconds);
close();
system("pause");
}
openQQ()只是用system函数来打开QQ,而不关心其他的事情,
sleep()函数获取在多少秒之后关闭QQ
而close()函数用于关闭QQ进程
这样实现的程序结构清晰,易于维护和扩展。