主頁 > 後端開發 > 高效c語言1快速入門

高效c語言1快速入門

2023-05-10 10:22:59 後端開發

本章將開發你的第一個C語言程式:傳統的 "Hello, world!"程式,然后討論一些編輯器和編譯器的選項,并闡述移植性問題,

Hello, world!

#include <stdio.h>
#include <stdlib.h>

int main(void) {
puts("Hello, world!");
return EXIT_SUCCESS;
}

在Linux和其他類似Unix的作業系統上,你可以用cc命令呼叫系統編譯器:

$cc hello.c
$ls
a.out hello.c
$./a.out
Hello, world!
% cc -o hello hello.c
% ./hello
Hello, world!

cc命令有許多標志和編譯器選項,例如,-o檔案標志讓你給可執行檔案起名字,而不是a.out,

hello.c程式的前兩行使用了#include前處理器指令,它的行為就像你在完全相同的位置用指定檔案的內容替換它一樣,我們包括<stdio.h>和<stdlib.h>頭檔案來訪問這些頭檔案中宣告的函式,然后我們可以在程式中呼叫這些函式,puts函式在<stdio.h>中宣告,而EXIT_SUCCESS宏在<stdlib.h>中定義,正如檔案名所示,<stdio.h>包含了C語言標準I/O函式的宣告,而<stdlib.h>則包含了一般實用函式的宣告,

C定義了兩種可能的執行環境:獨立的和托管的,獨立環境可能不提供作業系統,通常用于嵌入式編程,這些執行環境提供了一套最小的庫函式,程式啟動時呼叫的函式的名稱和型別是執行環境定義的,

我們定義main回傳int型別的值,并將void放在括號內,表示該函式不接受引數,int型別是有符號的整數型別,可以用來表示正、負整數值以及零,與其他程式性語言類似,C語言程式由可以接受引數和回傳值的程序(稱為函式)組成,每個函式都可重用,你可以根據需要在程式中頻繁呼叫,在本例中,主函式回傳的值表示程式是否成功終止,

puts("Hello, world!")列印出"Hello, world!", puts函式是標準庫函式,它將字串引數寫入stdout(通常代表控制臺或終端視窗),并在輸出中附加換行符,如果不需要換行可以使用fputs,

return陳述句退出程式,向主機環境或呼叫腳本回傳一個整數值,EXIT_SUCCESS是類似物件的宏,通常擴展為0,通常定義為:#define EXIT_SUCCESS 0,

檢查函式的回傳值

函式通常會回傳一個計算結果的值,或者表示函式是否成功完成了它的任務,例如,我們在 "Hello, world!"程式中使用的puts函式需要列印字串并回傳int型別的值,如果發生寫入錯誤,puts函式回傳宏EOF的值(負整數);否則,它回傳非負的整數值,

盡管對于我們的簡單程式來說,puts函式不太可能失敗并回傳EOF,但這是可能的,因為對puts的呼叫可能會失敗并回傳EOF,這意味著你的第一個C程式有bug,或者,可以按以下方法改進,

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  if (puts("Hello, world!") == EOF) {
    return EXIT_FAILURE;
    // code here never executes
  }
  return EXIT_SUCCESS;
  // code here never executes
}

注意(puts("Hello, world!")一定要有括號,否則編譯會報錯:

c$ cc hello2.c
hello2.c: In function ‘main’:
hello2.c:5:5: error: expected ‘(’ before ‘puts’
5 | if puts("Hello, world!") == EOF {
| ^~~~
| (

格式化的輸出

puts函式是一種將字串寫入stdout的簡單好方法,但最終你會需要使用printf函式來列印格式化的輸出--例如,列印字串以外的引數,printf函式接收定義輸出格式的格式化字串,然后是可變數量的引數,這些引數是你想列印的實際數值,例如,如果你想用printf函式來列印Hello, world!,你可以這樣寫,
printf("%s\n", "Hello, world!"),

第一個引數是格式字串"%s\n",%s是轉換規范,指示printf函式讀取第二個引數(字串字面)并將其列印到stdout,\n是一個字母轉義序列,用于表示非圖形字符,并告訴函式在該字串后面包括新行,

注意不要將用戶提供的資料作為第一個引數的一部分傳遞給printf函式,因為這樣做會導致格式化輸出的安全漏洞(Seacord 2013),

編輯器和集成開發環境

可以使用各種編輯器和集成開發環境來開發你的C語言程式,圖1-1顯示了最常用的編輯器,根據2018年JetBrains的調查,

對于Microsoft Windows,Microsoft的Visual Studio IDE(https://visualstudio.microsoft.com/)是不錯的選擇,Visual Studio有三個版本,社區版、專業版和企業版,社區版的優點是免費,而其他版本的功能則需要付費,

對于Linux來說,Vim、Emacs、Visual Studio Code和Eclipse都可選擇,Vim是許多開發者和高級用戶的首選編輯器,它是一個基于vi編輯器的文本編輯器,由Bill Joy在1970年代為Unix的一個版本撰寫,它繼承了vi的按鍵系結,但也增加了原vi所缺少的功能和可擴展性,你可以選擇安裝Vim插件,如YouCompleteMe(https://github.com/Valloric/YouCompleteMe/)或deoplete(https://github.com/Shougo/deoplete.nvim/),為C語言編程提供本地語意完成,

GNU Emacs是可擴展的、可定制的、免費的文本編輯器,它的核心是Emacs Lisp的解釋器,這是一種Lisp編程語言的方言,具有支持文本編輯的擴展功能--盡管我從未發現這是個問題,

Visual Studio Code(VS Code)是精簡的代碼編輯器,支持開發操作,如除錯、任務運行和版本控制,它提供了開發人員所需的工具,以實作快速的代碼構建--除錯回圈,VS Code可以在macOS、Linux和Windows上運行,對私人或商業使用都是免費的,

編譯器

現在有很多C語言編譯器,他么編譯器實作了不同版本的C標準,許多用于嵌入式系統的編譯器只支持C89/C90,用于Linux和Windows的流行編譯器更努力地支持現代版本的C標準,直到并包括對C2x的支持,

  • GNU 編譯器集
    GNU編譯器集合(GCC)包括C、C++和Objective-C以及其他語言的前臺(https://gcc.gnu.org/),GCC的開發在GCC指導委員會的指導下遵循明確的開發計劃,

GCC已經被采納為Linux系統的標準編譯器,盡管也有用于微軟Windows、macOS和其他平臺的版本,在Linux上安裝GCC很容易,例如,下面的命令在Ubuntu上安裝GCC 8,

$ sudo apt-get install gcc-9
$ gcc --version
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ sudo dnf install gcc # Fedora
  • Clang
    另一個流行的編譯器是Clang(https://clang.llvm.org/),在Linux上安裝Clang也很容易,例如,下面的命令應該在Ubuntu上安裝Clang,
$ sudo apt-get install clang

你可以用下面的命令測驗你所使用的Clang的版本,
% clang --version
$ clang --version
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
  • 微軟Visual Studio

Windows最流行的開發環境是Microsoft Visual Studio,它包括IDE和編譯器,它與Visual C++ 2019捆綁在一起,其中包括C和C++編譯器,
你可以在專案屬性頁上為Visual Studio設定選項,在C/C++下的高級選項卡上,確保你通過使用編譯為C代碼(/TC)選項而不是編譯為C++代碼(/TP)選項來編譯為C代碼,默認情況下,當你命名一個以.c為擴展名的檔案時,它是用/TC編譯的,如果檔案被命名為.cpp、.cxx或其他一些擴展名,則用/TP編譯,

參考資料

  • 本文涉及的python測驗開發庫 謝謝點贊! https://github.com/china-testing/python_cn_resouce
  • python精品書籍下載 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
  • 本書英文原版: Effective C An Introduction to Professional C Programming 2020 a4.5-103--.epub

https://url97.ctfile.com/f/18113597-810419181-1f9306 下載密碼 訂閱號pythontesting 發送 密碼 ,

移植性

每個C語言編譯器的實作都至少有一點不同,編譯器不斷發展,因此,例如,像GCC這樣的編譯器可能提供對C17的完全支持,但正在努力實作對C2x的支持,在這種情況下,它可能有一些C2x的功能實作,但沒有其他,因此,編譯器支持全部的C標準版本(包括中間的版本),C語言實作的總體發展是緩慢的,許多編譯器明顯落后于C標準,

如果為C語言撰寫的程式只使用標準中規定的語言和庫的那些功能,就可以認為是嚴格符合標準的,這些程式的目的是為了最大限度地提高可移植性,然而,由于實作行為的范圍,現實世界中沒有一個C語言程式是嚴格符合要求的,也不會是(可能也不應該是),相反,C標準允許你撰寫符合要求的程式,這些程式可能依賴于非可移植的語言和庫特性,

通常的做法是為一個參考實作撰寫代碼,或者有時為幾個實作撰寫代碼,這取決于你打算在哪個平臺上部署你的代碼,C標準是確保這些實作不會有太大的差異,并允許你一次針對幾個實作,而不必每次都學習一種新的語言,
在C標準檔案的附件J中列舉了五種可移植性問題,

  • 實作定義的行為

  • 未指定的行為

  • 未定義的行為

  • 針對本地的行為

  • 常見的擴展

  • 實作定義的行為
    實作定義的行為是指C語言標準中沒有規定的程式行為,它可能在不同的實作中提供不同的結果,但在一個實作中具有一致的、有記錄的行為,實作定義的行為的一個例子是一個位元組中的位數,

實作定義的行為大多是無害的,但在移植到不同的實作時可能會導致缺陷,在可能的情況下,避免撰寫依賴于實作定義的行為的代碼,這些行為在你可能用來編譯你的代碼的C實作中是不同的,C標準的附件J.3中列舉了實作定義行為的完整串列,你可以通過使用static_assert宣告來記錄你對這些實作定義的行為的依賴,

  • 未指定的行為

未指定的行為是指標準提供了兩個或多個選項的程式行為,該標準對在任何情況下選擇哪個選項沒有要求,每次執行一個給定的運算式可能會有不同的結果,或者產生與之前執行相同運算式不同的值,未指定行為的一個例子是函式引數存盤布局,它在同一程式中的不同函式呼叫中可能會有所不同,避免撰寫依賴于C標準附件J.1中列舉的非指定行為的代碼,

  • 未定義的行為
    未定義的行為是指C標準沒有定義的行為,或者說是 "在使用不可移植的或錯誤的程式結構或錯誤的資料時,標準沒有規定的行為",未定義行為的例子包括有符號的整數溢位和解讀一個無效的指標值,具有未定義行為的代碼往往是錯誤的,但比這更有細微差別,標準中對未定義行為的識別如下,

  • 當違反了 "應當 "或 "不應當 "的要求,并且該要求出現在約束條件之外時,該行為是未定義的

  • 當行為被明確規定為 "未定義行為 "時

  • 通過省略任何明確的行為定義
    前兩種未定義行為經常被稱為顯式未定義行為,而第三種則被稱為隱式未定義行為,這三者之間的重點沒有區別,它們都描述了未定義的行為,C語言標準附件J.2 "未定義行為 "包含了C語言中顯式未定義行為的串列,

開發者經常誤認為未定義的行為是C標準中的錯誤或遺漏,但將行為歸為未定義的決定是有意的,也是經過考慮的,C標準委員會將行為歸類為未定義的行為是為了做到以下幾點,

  • 給予實作者許可,使其不去捕捉難以診斷的程式錯誤
  • 避免定義晦澀難懂的案例,使之有利于一種實作策略而不是另一種策略
  • 識別可能的符合要求的語言擴展領域,在這些領域中,實作者可以通過提供官方未定義行為的定義來增強語言,
    這三個原因實際上是完全不同的,但都被認為是可移植性問題,編譯器(實作)有做以下事情的余地,
  • 完全忽略未定義的行為,產生不可預測的結果
  • 以環境特征的檔案方式行事(有或沒有發出診斷書),
  • 終止翻譯或執行(發出診斷),

這些選項都不是很好(尤其是第一個),所以最好避免未定義的行為,除非實作指定這些行為的定義是為了讓你呼叫一個語言增強功能,

  • 特定于本地的行為和通用擴展

特定于本地的行為取決于每個實作所記錄的國籍、文化和語言的本地慣例,通用擴展在許多系統中被廣泛使用,但并不能移植到所有的實作中,

小結

在這章中,你學會了如何撰寫簡單的C語言程式,編譯它,并運行它,然后,我們看了幾個編輯器和互動式開發環境,以及一些編譯器,你可以用它們來開發Windows、Linux和macOS系統上的C語言程式,一般來說,你應該使用較新版本的編譯器和其他工具,因為它們往往支持C編程語言的較新功能,并提供更好的診斷和優化,如果較新版本的編譯器破壞了你現有的代碼,或者你正準備部署你的代碼,你可能不想使用較新版本的編譯器,以避免在你已經測驗過的應用程式中引入不必要的變化,在本章的最后,我們討論了C語言程式的可移植性,

釘釘或微信號: pythontesting 微信公眾號:pythontesting

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/552079.html

標籤:C++

上一篇:怎樣成為優秀的后端工程師

下一篇:返回列表

標籤雲
其他(158756) Python(38124) JavaScript(25412) Java(18024) C(15224) 區塊鏈(8263) C#(7972) AI(7469) 爪哇(7425) MySQL(7175) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5338) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4570) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2432) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1972) 功能(1967) Web開發(1951) HtmlCss(1934) python-3.x(1918) 弹簧靴(1913) C++(1913) xml(1889) PostgreSQL(1875) .NETCore(1860) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 高效c語言1快速入門

    本章將開發你的第一個C語言程式:傳統的 "Hello, world!"程式。然后討論一些編輯器和編譯器的選項,并闡述移植性問題。 Hello, world! #include <stdio.h> #include <stdlib.h> int main(void) { puts("Hello, wo ......

    uj5u.com 2023-05-10 10:22:59 more
  • 怎樣成為優秀的后端工程師

    本文翻譯自國外論壇 medium,原文地址:https://medium.com/@pradeesh-kumar/how-to-become-a-good-backend-engineer-9da75202a104 讓我們一起看看國外開發者認為優秀后端工程師需要掌握哪些技能。 誰是后端工程師? 本質 ......

    uj5u.com 2023-05-10 07:38:38 more
  • Django筆記三十九之settings配置介紹

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記三十九之settings配置介紹 這一篇筆記介紹 Django 里 settings.py 里一些常用的配置項,這些配置有一些是在之前的筆記中有過介紹的,比如 logging 的日志配置,session 的會話配置等,這里就只做一下簡單的 ......

    uj5u.com 2023-05-10 07:37:28 more
  • 【redis】哨兵監控原理

    redis-主從模式弊端: 一、master節點例外shutdown后,從機原地待命,從機資料可以查詢(不可以寫入),等待主機重啟歸來 二、復制延時,信號衰減 redis-哨兵監控: 是什么? 哨兵即為吹哨人,可以巡查監控后臺master主機是否故障,如果故障可以根據投票數自動將一個從庫轉換為新的m ......

    uj5u.com 2023-05-10 07:32:04 more
  • 實驗五 Java多執行緒程式設計

    實驗五 Java多執行緒程式設計

    實驗目的
    1. 掌握Runnable介面實作多執行緒的方法
    2. 掌握Thread類實作多執行緒的用法
    3. 掌握Java語言中多執行緒編程的基本方法 ......

    uj5u.com 2023-05-10 07:26:53 more
  • 分享一個提高運維效率的 Python 腳本

    哈嘍大家好我是咸魚,今天給大家分享一個能夠提升運維效率的 python 腳本 咸魚平常在作業當中通常會接觸到下面類似的場景: 容災切換的時候批量對機器上的組態檔內容進行修改替換 對機器批量替換某個檔案中的欄位 對于 Linux 機器,咸魚可以寫個 shell 腳本或者直接批量使用 sed 命令就能 ......

    uj5u.com 2023-05-10 07:26:45 more
  • Spring AOP官方檔案學習筆記(四)之Spring AOP的其他知識點

    1.選擇哪種AOP (1) 使用Spring AOP比使用完整版的AspectJ更方便簡單,因為不需要在開發和構建程序中引入AspectJ編譯器以及織入器,如果我們只希望通知能夠在Spring Bean上執行,那么選用Spring AOP就可以了,如果我們希望通知能夠在不由Spring所管理的物件上 ......

    uj5u.com 2023-05-10 07:26:24 more
  • 關于并發編程與執行緒安全的思考與實踐

    并發編程的意義是充分的利用處理器的每一個核,以達到最高的處理性能,可以讓程式運行的更快。而處理器也為了提高計算速率,作出了一系列優化 ......

    uj5u.com 2023-05-10 07:21:07 more
  • 由淺入深學MySQL之事務全攻略

    前言 從今天開始本系列就帶各位小伙伴學習資料庫技術。資料庫技術是Java開發中必不可少的一部分知識內容。也是非常重要的技術。本系列教程由淺入深, 全面講解資料庫體系。 非常適合零基礎的小伙伴來學習。 全文大約 【1707】 字,不說廢話,只講可以讓你學到技術、明白原理的純干貨!本文帶有豐富案例及配圖 ......

    uj5u.com 2023-05-10 07:19:57 more
  • Python3.10動態修改Windows系統(win10/win11)本地IP地址(靜態IP)

    一般情況下,局域網里的終端比如本地服務器設定靜態IP的好處是可以有效減少網路連接時間,原因是程序中省略了每次聯網后從DHCP服務器獲取IP地址的流程,缺點是容易引發IP地址的沖突,當然,還有操作層面的繁瑣,如果想要切換靜態IP地址,就得去網路連接設定中手動操作,本次我們使用Python3.10動態地 ......

    uj5u.com 2023-05-09 08:37:46 more