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技術乾貨。 
藝無止境

相關文章
相關標籤/搜索