那些主流編程語言的知識,C語言(Ⅰ)

前言

對於編程語言來講,常常看到有由於各自支持的語言陣營而互懟的,其實根本沒那個必要,都只是一種工具而已。當多數主流語言都會使用時也許你就不會有偏見了,本質不過都是用來描述計算機的一個任務,只是每門語言設計時考慮的側重點不同而已。你們最好不要停留在語言層面去爭執,不如把時間花在計算機實現原理和結構的本質上,這樣更能理解編程語言每一行描述的東西在計算機是幹什麼的。本系列將總結如今IT領域主流的那些編程語言的相關知識。linux

關於C語言

C語言是最經典的語言,不少其餘語言的運行環境也是用C來寫的,對於寫程序的人則能不懂C語言呢!提到C首先必然會讓人關聯到指針,當年在大學讓你困惑的指針倒是C語言威力無窮的基礎。C語言可能從更高層面的設計和編寫效率上有所欠缺,但卻足夠經典且容易操控底層。指針雖然風險不小,但卻十分強大。此外ANSI C也加強了C程序在不一樣操做系統的遷移性,下面列一些C語言的一些基礎知識。算法

C語言

翻譯階段

編寫好的C程序須要先編譯成可執行的機器指令才能運行,這即是翻譯工做。翻譯的主要步驟是編譯和連接,編譯就是源代碼到目標代碼,而連接是將各個目標文件連接起來從而造成一個可執行的程序,固然連接器也會引入被程序所用到的全部標準C函數庫的函數。有時編譯過程還會將預處理做爲一個階段,它主要是對源文件進行一些處理,好比將#define替換成實際值、將#include指定的文件內容填充進來。下面是使用gcc來編譯並連接的例子,通過編譯和連接後獲得可執行程序,這兩個步驟經過gcc來完成,命令爲gcc hello.c -o hello,最終運行./hello會輸出「hello world」。編程

#include<stdio.h>

int main()
{
    printf("hello world");
}

複製代碼

編譯連接

假如咱們編寫了多個c文件,則編譯器會分別編譯成多個obj目標文件,而後再經過連接器將全部目標文件連接起來生成可執行文件。windows

關於擴展名

注意windows系統的目標文件擴展名爲obj,通常連接完成後也不會被刪除。而unix-like系統的目標文件擴展名爲o,通常在連接完成後會被刪除。windows系統的可執行文件擴展名爲exe,而unix-like系統的可執行文件名能夠任意命名。此外,C語言源文件通常後綴爲c,而頭文件後綴爲h,雖然沒有強制規定但你們都會去遵照這個約定。bash

關於編譯器

翻譯階段須要將C語言代碼變爲可執行程序,這些工做由C編譯器完成。C編譯器也有不少,常見的以下:數據結構

  • GCC,GCC即(GNU Compiler Collection,GNU編譯器套件),由GNU開發的GPL許可的編譯器自由軟件。剛開始只做爲C語言編譯器,但後來發展成多種語言編譯器,好比C、C++、Java、Android、Objective-C和Fortran等等。如今不少unix-like操做系統自帶GCC,將其做爲標準編譯器。
  • MS C,與微軟的Visual Studio一塊兒集成發佈,由微軟提供的一套完整的集成開發環境,編譯後能在微軟的全部操做系統上運行。好比VS通常會使用CL編譯器。
  • Clang,它是一個基於LLVM的C/C++/Objective-C輕量級編譯器,經常使用於Mac系統下。
  • Turbo C,這是一個比較流行的C編譯器,小巧快速。
  • cc,即C Compiler,這是一個unix系統古老的編譯器,不少經典書籍會看到這個編譯器。爲保持兼容,如今的linux系統會將cc做爲一個符號鏈接指向gcc,即/usr/bin/cc -> gcc。

gcc編譯例子

以linux系統的gcc爲例,看幾個編譯例子。假如hello.c的代碼以下,機器學習

#include<stdio.h>

int main()
{
    printf("hello world");
}
複製代碼

咱們直接使用以下的gcc命令對其進行編譯,並且不帶任何參數,此時將生成一個名爲out.a的可執行文件,經過./a.out可以輸出「hello world」。編程語言

gcc hello.c
複製代碼

假如添加name.h/name.c和adder.h/adder.c兩對頭文件和源文件,並且將hello.c稍做修改,三個文件代碼分別以下。分佈式

//name.h
char* get_name();

//name.c
char* get_name() {
	char* name = "seaboat : ";
	return name;
}
複製代碼
//adder.h
int add(int a, int b);

//adder.c
int add(int a, int b) {
	return (a + b);
}
複製代碼
//hello.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include"adder.h"
#include"name.h"
int main()
{
	char* name = get_name();
	char* hello = "hello world";
	char* output = (char*)malloc(strlen(hello) + strlen(name));
	sprintf(output, "%s%s", name, hello);
	printf("%s\n", output);
	int a = 1;
	int b = 3;
	printf("a + b = %d\n", add(a, b));
}
複製代碼

則經過以下的命令能夠對多個源文件進行編譯和連接,最終生成一個名爲a.out的可執行文件。當咱們經過./a.out執行可執行文件時,它將輸出「seaboat : hello world a + b = 4」。函數

gcc name.c adder.c hello.c
複製代碼

咱們還能夠經過下面兩個命令對name.c和adder.c兩個文件編譯生成目標文件,分別爲adder.o和name.o。而後再經過下面第三行命令來編譯hello.c源文件,編譯完後它會自動與name.o和adder.o兩個目標文件進行鏈接。

gcc -c adder.c
gcc -c name.c
gcc name.o adder.o hello.c
複製代碼

此外,還可以經過下面的命令來給多個源文件進行編譯並生成各自對應的目標文件,這意味着不對它們進行連接。

gcc -c  name.c adder.c hello.c
複製代碼

對於多個目標文件,若是要將他們連接能夠經過下面的命令,便可以生成可執行文件。

gcc  name.o adder.o hello.o
複製代碼

若是咱們想對生成的可執行文件進行命名,那麼能夠經過下面第一行命令來實現,將生成一個名爲hello的可執行文件。相似地,也能夠對多個目標文件進行鏈接時指定可執行文件名,以下面第二行命令,將生成一個名爲hello2的可執行文件。

gcc name.c adder.c hello.c -o hello

gcc  name.o adder.o hello.o -o hello2
複製代碼

關於字符集

編寫C語言時源代碼能夠包括以下字符集:

  1. 英語大寫小寫字母
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
複製代碼
  1. 十進制的阿拉伯數字
0 1 2 3 4 5 6 7 8 9
複製代碼
  1. 其它符號
! " # % & ' () * + , - . / : ; < = > ? [ ] \ ^ _ { } | ~ 複製代碼
  1. 空白符
空格、水平製表符、垂直製表符、換行、換頁
複製代碼

關於註釋

C語言提供的註釋方式有兩種:以/*開始而以*/結束來註釋多行代碼,以//開始來註釋單行代碼。通常來講對源碼中進行註釋則意味着編譯時會被預處理器清除掉,用空格來替代。

/*
第一種註釋方式
*/

//第二種註釋方式
複製代碼

關於標識符與關鍵詞

標識符就是咱們開發人員對變量、函數、類型、結構體、宏等等的起名,C語言也要求咱們要按照它的規定來取名。按照規定,標識符能夠由英文大小寫字母(A~Z, a~z)、阿拉伯數字(0~9)、和下劃線(_)組成。須要注意如下幾點:

  • 要求不能以字母開頭。
  • C語言對大小寫字母敏感。
  • C語言不會對標識符的長度進行限制,但標準容許編譯器忽略第31位之後的字符,具體截取前多少位則由不一樣的編譯器來實現,當截取的字符串相同時則認爲是同一個標識符。
  • 標識符不該該亂取名,儘可能要讓標識符名字具備相應的意義。

固然C語言還保留了32個特殊的關鍵詞,咱們命名的標識符不能與它們相同,不然就會報錯。這32個關鍵詞以下:

關鍵字 說明
auto 聲明自動變量
break 跳出當前循環
case 開關語句分支
char 聲明字符型變量或函數
const 聲明只讀變量
continue 結束當前循環,開始下一輪循環
default 開關語句中的「默認」分支
do 循環語句的循環體
double 聲明雙精度變量或函數
else 條件語句否認分支(與if連用)
enum 聲明枚舉類型
extern 聲明變量或函數是在其它文件中聲明
float 聲明浮點型變量或函數
for 一種循環語句
goto 無條件跳轉語句
if 條件語句
int 聲明整型變量或函數
long 聲明長整型變量或函數
register 聲明寄存器變量
return 子程序返回語句(能夠帶參數,也可不帶參數)
short 聲明短整型變量或函數
signed 聲明有符號類型變量或函數
sizeof 計算數據類型或變量長度(所佔字節數)
static 聲明靜態變量
struct 聲明結構體變量或函數
switch 用於開關語句
typedef 用以給數據類型取別名
unsigned 聲明無符號類型變量或函數
union 聲明共用體類型
void 聲明函數無返回值或無參數,聲明無類型指針
volatile 說明變量在程序執行中可被隱含地改變
while 循環語句的循環條件

做者簡介:筆名seaboat,擅長人工智能、計算機科學、數學原理、基礎算法。書籍:《Tomcat內核設計剖析》、《圖解數據結構與算法》、《人工智能原理科普》。

專一於人工智能、讀書與感想、聊聊數學、計算機科學、分佈式、機器學習、深度學習、天然語言處理、算法與數據結構、Java深度、Tomcat內核等。

相關文章
相關標籤/搜索