C语言程序设计概述

1 概论

1972年Dennis Ritchie发明了C语言,然后Dennis Ritchie又使用C语言重写了Unix系统,自那之后C语言逐渐受到了全世界大多数编程爱好者的喜好,后期的主流操做系统Linux,MacOSX,Windows的绝大部分底层都是采用C语言来实现的,主流编程语言Java,PHP,Python的底层也是C语言实现的。 
而伴随着移动互联网(Android,IOS),云计算,大数据以及物联网的不断发展,C语言会占据更加广阔的市场,所以C语言是做为一名ITMan必须深刻掌握的语言。java

2016年4月 TIOBE 编程语言排行榜(前20名) 
2016年4月 TIOBE 编程语言排行榜数据库

2 计算机体系结构

计算机一般都是由硬件软件组成的 
软件是运行在计算机硬件之上的,那么计算机硬件是由哪些部分组成的呢? 
计算机硬件主要包含CPU,内存,硬盘和网卡以及IO设备组成 
下面简要介绍下各个组件之间的做用: 
CPU主要是用来计算数据和控制各个硬件设备协助完成数据输入输出等等 
内存主要是用来临时存储运算的(少许)数据,断电后数据会丢失 
硬盘主要是用来永久存储大容量(TB)的数据 
网卡主要是用在网络上传输数据 
IO设备在CPU的控制下完成数据输入(一般是鼠标键盘完成)以及输出(一般是声卡,显卡或者打印机完成) 
在程序故障诊断时一般都须要考虑硬件的CPU,内存和磁盘以及网卡的性能瓶颈编程

软件的出现实现了人与计算机之间更好的交互方式。windows

软件分类主要分红系统软件和应用软件两种,其中系统软件有基于命令行交互方式,运行于服务器端的Unix(Solaris13),Linux(Redhat7.0),基于图形化界面,运行于PC,笔记本上的Ubuntu16,Windows10,MacOSX10.11,基于语音手势识别,触控滑动,运行于移动终端(手机,电视,嵌入式设备)的Android和IOS等主流操做系统,其中Android是基于Linux发展而来,IOS是基于MacOSX发展而来。 
操做系统主要是管理计算机系统的资源以及控制程序的执行数组

应用软件主要是运行在PC或者是移动终端的操做系统之上,用于解决生活的各类需求,例如购物,聊天,听音乐,看电影,收发邮件等等,例如,天猫京东支付宝,微信,每天动听,迅雷影音,FoxMail等等。安全

而目前主流技术趋势是基于Android和IOS的移动互联网以及未来(5-10年后)即将火爆的物联网ruby

3 编程语言发展史

想让计算机作事情就必须采用某种指令系统(它是由计算机系统的基本运算构成)来指挥计算机进行计算,存储和传输数据等任务,而大型服务器(非X86精简指令系统),PC,笔记本(X86复杂指令系统)以及手机(ARM精简指令系统)所采用的指令系统是不尽相同的,这也就意味着PC上的程序不加修改就不能到手机上运行,手机上的程序不加修改也不能到PC上运行。bash

程序就是指令系统加上数据集 组成,而每一个CPU都有本身的指令系统(由二进制的机器码010101序列组成),这也就是最先的编程语言-机器语言的由来,它的特色是高效,不能移植,不易开发和后期维护等等。服务器

随着时代和计算机技术的发展,汇编语言和编译器的出现解决了须要记住很是多的机器指令的难题,可是仍是没有从根本上解决移植性的问题,只是将机器指令转换为易懂的英文单词,而后由编译器编译成机器指令,由于计算机终归揭底只能识别0001110100110机器指令,并且汇编语言是面向机器的,不一样机器的汇编指令是不相同的。微信

演示Windows上将汇编语言嵌套在C语言中使用,完成两个变量相加的结果:

#include <stdio.h> void use_asm(){ int a, b, c=0; a = 4; b = 6; printf("a = %d \t b=%d\tc=%d \n",a,b,c); //汇编语言 _asm{ //将变量a的值移动到eax寄存器 mov eax, a; add eax, b; mov c ,eax; } printf("a = %d \t b=%d\tc=%d\n", a, b, c); } void main(){ use_asm(); getchar(); }

时光再流转,在1972年C语言的诞生,一种以面向过程,高效和可移植性编译型编程语言,C语言的出现,屏蔽了底层硬件的差别性(由编译器负责处理),使得开发人员能够集中精力在业务逻辑的实现上,适合作系统软件,驱动程序的开发,同时它也存在着对系统平台库的严重依赖,只有标准C的部分是可移植(全部的主流操做系统都实现了C语言的标准库函数),软件实现周期较长等缺点。然后期的C++,Java,C#,Objective-C等编程语言在不少方面都吸取了C语言的优势,新增了如面向对象(OO),更加完善的API接口以及提供了平常开发中所需的丰富的类库等诸多的特性,更加适合作应用软件开发。

目前流行的NoSQL数据库Redis就是采用标准C开发的,而MongDB是采用C++语言开发的。

4 C语言编程环境

由C语言编写的程序能够运行在各大主流操做系统之上,并且标准C的部分是可移植的。并且为了方便开发人员开发,测试和部署应用程序等,还提供了强大的集成开发环境,在C语言学习初期能够采用Windows10+VisualStudio2015的C语言环境,后面的博文将会使用VisualStudio2015(后面都会简称为VS2015)做为开发C语言的IDE,在讲到C语言的平台差别性时会使用Linux系统的VIM编辑器(该编辑器只能写简单的C程序)。

下面是各大主流操做系统对应的IDE

操做系统 IDE
Windows10 VisualStudio2015
Linux(Ubuntu16) QT5.5
MacOSX10.11/IOS9 XCode7.2
Android6 AndroidStudio2.0

除此以外还有些跨平台的IDE,例如CodeBlocks,Eclipse等等。读者们能够根据本身的喜爱以及平台来选择对应的IDE。

5 使用VS2015开发C语言版本的HelloWorld

helloworld程序一般是学习一门语言的入门程序,若是可以正常编译运行helloworld,就表示编译和运行环境已经搭建完成。

1 VS2015安装说明

VS2015安装时能够选择指定的模块安装,个人机器是i5+12G内存,安装全部的模块大概耗时6个小时,使用VS2015还能够开发Anndroid IOS程序。 
安装完成以后须要使用Microsoft公司的帐号登陆以后才能无偿使用,这里提供一个企业版的激活码:HM6NR-QXX7C-DFW2Y-8B82K-WTYJV,过了免费的时间以后可使用该激活码激活。

VisualStudio2015启动界面: 
VS2015启动界面

2 使用VS2015建立C语言的Project

可使用Ctrl+Shift+N快捷键实现建立一个新的工程 
VS2015建立C语言的项目

点击肯定以后就会看到如图所示的内容了: 
C语言项目结构说明

下面对该项目的目录结构作一个说明: 
VS2015有个解决方案的概念,一个解决方案下面能够存在多个项目,例如这里已经建立了一个和解决方案同名的项目WindowsC,该项目下有两个重要的目录,分别是头文件和源文件,头文件用于存放函数声明,源文件就是存放开发人员编写代码的目录了。 
须要注意的是同一个解决方案下不能存在相同名字的源文件,当一个解决方案下存在多个项目时若是要运行指定的项目,须要将其设为启动项后运行,并且同一个项目项目只能有一个main函数,不然没法编译经过

3 使用VS2015实现C语言的helloworld

helloworld的本质就是在控制台上打印一串字符串,windows的命令行下可使用echo命令实现相似的功能。 
echo hello world

而要使用C语言完成这个功能则须要借助于printf函数来实现,而要想使用该函数,必须使用#include <stdio.h> 
指令将头文件其包含到源代码中(#include的实质就是将头文件的内容原封不动的复制到源文件中),而printf函数的声明正是位于名为stdio.h的头文件中。为了后期的编写程序方便,这里编写一个共同的头文件,将那些经常使用的标准C语言的库函数都引入到该文件中,源文件只须要引用该头文件便可。

建立头文件如图所示:

共通的头文件

共同的头文件内容以下:

#include <stdio.h>//引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准输入输出头文件 #include <stdlib.h> //引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准库函数头文件

头文件编写完成以后就能够编写源文件用于实现helloworld了 
建立源文件

helloworld源码实现:

#include "common.h" /* 定义程序主入口 @author Tony 18601767221@163.com @since 20160512 19:26 */ void main() { printf("Hello World \n"); system("echo Hello World Again\n"); system("pause"); return; }

HelloWorld源程序解析

#include "common.h" //包含共通的头文件,会将头文件的内容替换到HelloWorld.c源文件中 当须要包含系统路径下的头文件时使用<> /* 每一个C程序要想运行,必须定义一个入口点,即main方法,方法的参数能够为空 Windows平台的编译器规定main方法的返回值为空 Linux平台的编译器规定main方法的返回类型为int @author Tony 18601767221@163.com @since 20160514 19:32 */ void main() { printf("Hello World \n");//打印字符串Hello World并换行 system("echo Hello World Again\n");//调用系统的echo命令输出指定的字符串 system("pause"); //程序暂停,输入任意键程序会退出 return; //返回为空 return以后的语句都不会执行! }

上述代码中使用了C语言的两种注释,分别是单行注释和多行注释,注释是描述程序的意图,方便后期维护,编译器会删掉注释的内容,而不影响程序的逻辑。

编写完成helloworld以后就是运行程序观察执行结果了,固然这中间包括了很是复杂的过程,后续博文会详细讲解背后的原理,如今只要按下F5就能够观察到以下的运行结果了。 
helloworld运行效果

6 C语言的运行原理

在使用VS2015编写helloworld的源代码以及相关的头文件时,使用其提供的快捷键F5编译并运行了程序,但这背后实际上还包含了预编译,转汇编,编译,连接四个步骤。

接下来将采用Linux(CentOS7)操做系统的C语言环境结合GCC编译器的一些编译选项来解剖C语言的运行原理。

环境说明: 
宿主机操做系统:Windows10 企业版 
虚拟机:CentOS7 企业版 
编辑器:gedit 
SSH远程链接工具:XShell,XManager

[root@tony Desktop]# cd /home/guanglei/Desktop/ #进入桌面 [root@tony Desktop]# gedit helloworld.c #使用gedit编辑c语言的源文件

helloworld.c源代码以下:

#include "common.h" #include <stdio.h>//引入跨平台的标注输入输出头文件 #include <stdlib.h> //引入跨平台的标准库头文件 /* 定义程序主入口 @author Tony 18601767221@163.com @since 20160514 19:45 */ int main(){ printf("This program is running CentOS7 \n!!!"); system("date"); //显示当前系统日期 system("ps -ef|grep java");//查看运行的java进程 return 0;// 返回0表示正常退出 }

使用gedit编辑helloworld.c效果示意图: 
使用gedit编辑helloworld.c效果示意图

编写完源码以后就可使用Linux(CentOS7)提供的gcc编译器来编译源程序了。

第一步 预编译 
预编译就是将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 #运行改程序并显示结果 This program is running CentOS7 Wed May 11 22:33:05 PDT 2016 root 6208 6206 0 22:33 pts/0 00:00:00 sh -c ps -ef|grep java root 6210 6208 0 22:33 pts/0 00:00:00 grep java 

Unix系统上完整的C语言运行原理如图所示: 
C语言运行原理

7 Windows系统经常使用命令

Windows系统包含大量的系统命令,提供了平常使用的绝大部分功能,实际上Windows系统图形化界面操做的背后就是在调用这些系统命令,学会这些经常使用的命令可让咱们更加方便和快捷的使用Windows系统提供的功能。

要想使用命令,必须启动一个cmd命令窗口,使用Windows+R,输入cmd后便可启动命令行窗口, 
启动cmd

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命令示例:

共通的头文件

#define _CRT_SECURE_NO_WARNINGS//关闭VS2015的安全检查 #include <stdio.h>//引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准输入输出头文件 #include <stdlib.h> //引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准库函数头文件 #include <Windows.h> //引入Windows头文件

源代码

#include "common.h" /* *根据传递的命令字符串调用系统命令 *@author Tony 18601767221@163.com * @since 20160514 19:58 */ void call_system(char str[]) { printf("你输入的要执行的命令是%s\n", str); system(str); } /* 程序主入口 @author Tony 18601767221@163.com @since 20160515 09:12 */ void main() { char str[100] = { 0 }; //定义一个字符数组 数组中的每一个元素初始化为0 printf("请输入system函数调用windows系统命令的名称\n"); scanf("%s", str); //将输入的命令字符串赋值给str call_system(str); call_system("pause"); }

使用Windows系统库函数ShellExecuteA函数实现异步打开和关闭程序

共通的头文件

#define _CRT_SECURE_NO_WARNINGS//关闭VS2015的安全检查 #include <stdio.h>//引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准输入输出头文件 #include <stdlib.h> //引入位于系统路径(C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt)标准库函数头文件 #include <string.h> //引入字符串头文件 #include <Windows.h> //引入Windows头文件
#include "common.h" /* 根据传递的字符串执行system函数调用系统命令 @author Tony 18601767221@163.com @since 20160515 09:29 */ 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); //异步执行打开指定的进程 } /* 关闭指定的进程 @author Tony 18601767221@163.com @since 20160515 09:35 */ 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); } /* *定义程序主入口 *@author Tony 18601767221@163.com *@since 20160516 09:46 */ 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"); }

8 最佳实践

1 在编写c语言程序时,考虑到编译器的兼容性(例如兼容vc和gcc),不使用中文内容编写程序,包括使用中文变量命名,方法名以及参数名等等。并且c语言的源程序中除了字符串外不支持中文内容。 
2 若要使用c语言的标准库函数,必须在原文件中预包含(#include)函数生命所在的头文件。 
3 预处理语句(例如#include和#define)是以换行做为结束的,所以不须要再使用分号来结束。 
4 编写代码时应该多写注释,一般添加到方法或者代码块上,便于往后程序的维护。

欢迎扫描下方的二维码,关注微信公众服务号-艺无止境,分享IT技术干货。 
艺无止境

相关文章
相关标签/搜索