C入門筆記

1. c文件執行過程

C語言程序的執行過程可以分為四個基本步驟:預處理、編譯、匯編和鏈接。下面是這些步驟的簡要概述:

預處理:在這個步驟中,預處理器將源代碼中以 # 開頭的指令進行處理,例如 #include 和 #define。預處理器還可以執行條件編譯,將一些代碼包含或排除在編譯過程中。

編譯:在這個步驟中,編譯器將經過預處理的源代碼轉換成匯編語言。編譯器會進行詞法分析、語法分析和語義分析,生成相應的中間代碼。

匯編:在這個步驟中,匯編器將中間代碼轉換成可執行的機器碼。匯編器會將每條匯編指令翻譯成一條或多條機器指令,并生成目標文件。

鏈接:在這個步驟中,鏈接器將目標文件和庫文件組合在一起,生成可執行文件。鏈接器會解決符號引用問題,將代碼和數據段放置在內存中的正確位置,并生成可執行文件的元數據(如入口地址和符號表)。

一旦完成了這些步驟,可執行文件就可以被操作系統加載和執行了。操作系統會將程序加載到內存中,并將控制權轉移到程序的入口點。程序開始執行,按照代碼的邏輯執行指令,直到程序結束或者遇到異常錯誤。

2.Void*

類型為 void * 的指針代表對象的地址,而不是類型。例如,內存分配函數 void *malloc( size_t size ); 返回指向 void 的指針,可以轉換為任何數據類型。

3.C 中的變量聲明

變量聲明向編譯器保證變量以指定的類型和名稱存在,這樣編譯器在不需要知道變量完整細節的情況下也能繼續進一步的編譯。變量聲明只在編譯時有它的意義,在程序連接時編譯器需要實際的變量聲明。
變量的聲明有兩種情況:
? 1、一種是需要建立存儲空間的。例如:int a 在聲明的時候就已經建立了存儲空間。
? 2、另一種是不需要建立存儲空間的,通過使用extern關鍵字聲明變量名而不定義它。 例如:extern int a 其中變量 a 可以在別的文件中定義的。
? 除非有extern關鍵字,否則都是變量的定義
extern int i; //聲明,不是定義
int i; //聲明,也是定義

不帶初始化的定義:帶有靜態存儲持續時間的變量會被隱式初始化為 NULL(所有字節的值都是 0),其他所有變量的初始值是未定義的,最好初始化

4.C 中的左值(Lvalues)和右值(Rvalues)

C 中有兩種類型的表達式:

  1. 左值(lvalue):指向內存位置的表達式被稱為左值(lvalue)表達式。左值可以出現在賦值號的左邊或右邊。
  2. 右值(rvalue):術語右值(rvalue)指的是存儲在內存中某些地址的數值。右值是不能對其進行賦值的表達式,也就是說,右值可以出現在賦值號的右邊,但不能出現在賦值號的左邊。

4.常量

4.1 整數常量

  1. 整數常量可以是十進制、八進制或十六進制的常量。前綴指定基數:0x 或 0X 表示十六進制,0 表示八進制,不帶前綴則默認表示十進制。
  2. 整數常量也可以帶一個后綴,后綴是 U 和 L 的組合,U 表示無符號整數(unsigned),L 表示長整數(long)。后綴可以是大寫,也可以是小寫,U 和 L 的順序任意。
  3. 下面列舉幾個整數常量的實例:
  4. 212 /* 合法的 */
  5. 215u /* 合法的 */
  6. 0xFeeL /* 合法的 */
  7. 078 /* 非法的:8 不是八進制的數字 */
  8. 032UU /* 非法的:不能重復后綴 */

4.2浮點數常量

可以帶有一個后綴表示數據類型,例如:
11. float myFloat = 3.14f;
double myDouble = 3.14159;

5. C存儲類

5.1 auto

auto 存儲類是所有局部變量默認的存儲類。

定義在函數中的變量默認為 auto 存儲類,這意味著它們在函數開始時被創建,在函數結束時被銷毀

int mount;
auto int month;

上面的實例定義了兩個帶有相同存儲類的變量,auto 只能用在函數內,即 auto 只能修飾局部變量。

5.2 register 存儲類

register 存儲類用于定義存儲在寄存器中而不是 RAM 中的局部變量。這意味著變量的最大尺寸等于寄存器的大小(通常是一個字),且不能對它應用一元的 ‘&’ 運算符(因為它沒有內存位置)。

register 存儲類定義存儲在寄存器,所以變量的訪問速度更快,但是它不能直接取地址,因為它不是存儲在 RAM 中的。在需要頻繁訪問的變量上使用 register 存儲類可以提高程序的運行速度。

register int miles;
寄存器只用于需要快速訪問的變量,比如計數器。還應注意的是,定義 ‘register’ 并不意味著變量將被存儲在寄存器中,它意味著變量可能存儲在寄存器中,這取決于硬件和實現的限制

5.3 static 存儲類

static 存儲類指示編譯器在程序的生命周期內保持局部變量的存在,,而不需要在每次它進入和離開作用域時進行創建和銷毀。若在函數內部定義,外部不可訪問
靜態變量在程序中只被初始化一次,即使函數被調用多次,該變量的值也不會重置
void func1(void)
{
/* ‘thingy’ 是 ‘func1’ 的局部變量 - 只初始化一次

  • 每次調用函數 ‘func1’ ‘thingy’ 值不會被重置。
    */
    static int thingy=5;
    thingy++;
    printf(" thingy 為 %d , count 為 %d\n", thingy, count);
    }
    輸出:thingy 6 7 8 9

5.4 extern 存儲類

extern 存儲類用于定義在其他文件中聲明的全局變量或函數。當使用 extern 關鍵字時,不會為變量分配任何存儲空間,而只是指示編譯器該變量在其他文件中定義。

6.運算符

a++: 先賦值后運算 ++a:先運算后賦值

7.判斷語句switch 與無限循環

1.switch:

當遇到 break 語句時,switch 終止,控制流將跳轉到 switch 語句后的下一行。
不是每一個 case 都需要包含 break。如果 case 語句不包含 break,控制流將會 繼續 后續的 case,直到遇到 break 為止。‘

2.無限循環

C 程序員偏向于使用 for( ; ; ) 結構來表示一個無限循環。

8.枚舉

義一個枚舉類型,需要使用 enum 關鍵字,后面跟著枚舉類型的名稱,以及用大括號 {} 括起來的一組枚舉常量。每個枚舉常量可以用一個標識符來表示,也可以為它們指定一個整數值,如果沒有指定,那么默認從 0 開始遞增。

8.1枚舉變量的定義

  1. enum DAY
    {
    MON=1, TUE, WED, THU, FRI, SAT, SUN
    };
    enum DAY day;
  2. enum DAY
    {
    MON=1, TUE, WED, THU, FRI, SAT, SUN
    } day;

例子:

#include <stdio.h>enum DAY
{MON=1, TUE, WED, THU, FRI, SAT, SUN
};int main()
{enum DAY day;day = WED;printf("%d",day);return 0;
}
輸出3  里面的元素如果不賦值初始化,默認從前面一個遞增

9. 函數指針與回調函數

1.函數指針

#include <stdio.h>int max(int x, int y)
{return x > y ? x : y;
}int main(void)
{/* p 是函數指針 */int (* p)(int, int) = & max; // &可以省略int a, b, c, d;printf("請輸入三個數字:");scanf("%d %d %d", & a, & b, & c);/* 與直接調用函數等價,d = max(max(a, b), c) */d = p(p(a, b), c); printf("最大的數字是: %d\n", d);return 0;
}

2.回調函數
函數指針作為某個函數的參數
函數指針變量可以作為某個函數的參數來使用的,回調函數就是一個通過函數指針調用的函數。
簡單講:回調函數是由別人的函數執行時調用你實現的函數。

實例:實例中 populate_array() 函數定義了三個參數,其中第三個參數是函數的指針,通過該函數來設置數組的值。
實例中我們定義了回調函數 getNextRandomValue(),它返回一個隨機值,它作為一個函數指針傳遞給 populate_array() 函數。
populate_array() 將調用 10 次回調函數,并將回調函數的返回值賦值給數組

#include <stdlib.h>  
#include <stdio.h>void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{for (size_t i=0; i<arraySize; i++)array[i] = getNextValue();
}// 獲取隨機值
int getNextRandomValue(void)
{return rand();
}int main(void)
{int myarray[10];/* getNextRandomValue 不能加括號,否則無法編譯,因為加上括號之后相當于傳入此參數時傳入了 int , 而不是函數指針*/populate_array(myarray, 10, getNextRandomValue);for(int i = 0; i < 10; i++) {printf("%d ", myarray[i]);}printf("\n");return 0;
}

10.字符串相關函數

在這里插入圖片描述

11. 結構體與結構體指針

在這里插入圖片描述
在這里插入圖片描述

12.union共用體

同一時間只能使用一個變量

  1. 定義共用體
    為了定義共用體,您必須使用 union 語句,方式與定義結構類似。union 語句定義了一個新的數據類型,帶有多個成員。union 語句的格式如下
    在這里插入圖片描述
  2. 訪問
    為了訪問共用體的成員,我們使用成員訪問運算符(.)。成員訪問運算符是共用體變量名稱和我們要訪問的共用體成員之間的一個句號。您可以使用 union 關鍵字來定義共用體類型的變量。下面的實例演示了共用體的用法:
    在這里插入圖片描述

13.位域

C語言中的位域是一種用來定義數據結構成員(即結構體成員)的特殊方式,其中這些成員被定義為占用指定數量的二進制位,而不是完整的字節。

  1. 位域的定義和位域變量的說明
    在這里插入圖片描述
    在下面例子中,定義Age結構體中的age變量值只占用三位,也就是數值不能大于7
    在這里插入圖片描述
  2. 位域使用
    下面示例中,定義了位域結構圖變量和位域結構體指針
    在這里插入圖片描述

14.typedef關鍵字

C 語言提供了 typedef 關鍵字,您可以使用它來為類型取一個新的名字

  1. 別名
    typedef unsigned char BYTE;
    在這個類型定義之后,標識符 BYTE 可作為類型 unsigned char 的縮寫,例如:
    BYTE b1, b2;
    按照慣例,定義時會大寫字母,以便提醒用戶類型名稱是一個象征性的縮寫。
  2. typedef定義結構體
    在這里插入圖片描述
  3. typedef vs #define
    #define 是 C 指令,用于為各種數據類型定義別名,與 typedef 類似,但是它們有以下幾點不同:
  • typedef 僅限于為類型定義符號名稱,#define 不僅可以為類型定義別名,也能為數值定義別名,比如您可以定義 1 為 ONE。
  • typedef 是由編譯器執行解釋的,#define 語句是由預編譯器進行處理的。

15 C 預處理器

C 預處理器不是編譯器的組成部分,但是它是編譯過程中一個單獨的步驟。簡言之==,C 預處理器只不過是一個文本替換工具而已,它們會指示編譯器在實際編譯之前完成所需的預處理==。我們將把 C 預處理器(C Preprocessor)簡寫為 CPP。

所有的預處理器命令都是以井號(#)開頭。它必須是第一個非空字符,為了增強可讀性,預處理器指令應從第一列開始。下面列出了所有重要的預處理器指令:
在這里插入圖片描述
#include <stdio.h>
#include “myheader.h”

這些指令告訴 CPP 從系統庫中獲取 stdio.h,并添加文本到當前的源文件中。下一行告訴 CPP 從本地目錄中獲取 myheader.h,并添加內容到當前的源文件中。

  • 宏延續運算符(\)
    一個宏通常寫在一個單行上。但是如果宏太長,一個單行容納不下,則使用宏延續運算符(\)。例如:
    在這里插入圖片描述

16. C錯誤處理

C 語言不提供對錯誤處理的直接支持,但是作為一種系統編程語言,它以返回值的形式允許您訪問底層數據。在發生錯誤時,大多數的 C 或 UNIX 函數調用返回 1 或 NULL,同時會設置一個錯誤代碼 errno,該錯誤代碼是全局變量,表示在函數調用期間發生了錯誤。您可以在 errno.h 頭文件中找到各種各樣的錯誤代碼。
在這里插入圖片描述

  • 程序退出狀態
    通常情況下,程序成功執行完一個操作正常退出的時候會帶有值 EXIT_SUCCESS。在這里,EXIT_SUCCESS 是宏,它被定義為 0。
    如果程序中存在一種錯誤情況,當您退出程序時,會帶有狀態值 EXIT_FAILURE,被定義為 -1。

17 C可變參數

后面的參數的個數和類型都不固定
在這里插入圖片描述

18 內存管理

C 語言為內存的分配和管理提供了幾個函數。這些函數可以在 <stdlib.h> 頭文件中找到。
在這里插入圖片描述

  • C語言中常用的內存管理函數和運算符
  1. malloc() 函數:用于動態分配內存。它接受一個參數,即需要分配的內存大小(以字節為單位),并返回一個指向分配內存的指針。

  2. free() 函數:用于釋放先前分配的內存。它接受一個指向要釋放內存的指針作為參數,并將該內存標記為未使用狀態。

  3. calloc() 函數:用于動態分配內存,并將其初始化為零。它接受兩個參數,即需要分配的內存塊數和每個內存塊的大小(以字節為單位),并返回一個指向分配內存的指針。

  4. realloc() 函數:用于重新分配內存。它接受兩個參數,即一個先前分配的指針和一個新的內存大小,然后嘗試重新調整先前分配的內存塊的大小。如果調整成功,它將返回一個指向重新分配內存的指針,否則返回一個空指針。

  5. sizeof 運算符:用于獲取數據類型或變量的大小(以字節為單位)。

  6. 指針運算符:用于獲取指針所指向的內存地址或變量的值。

  7. & 運算符:用于獲取變量的內存地址。

  8. *運算符:用于獲取指針所指向的變量的值。

  9. -> 運算符:用于指針訪問結構體成員,語法為 pointer->member,等價于 (*pointer).member。

  10. memcpy() 函數:用于從源內存區域復制數據到目標內存區域。它接受三個參數,即目標內存區域的指針、源內存區域的指針和要復制的數據大小(以字節為單位)。

  11. memmove() 函數:類似于 memcpy() 函數,但它可以處理重疊的內存區域。它接受三個參數,即目標內存區域的指針、源內存區域的指針和要復制的數據大小(以字節為單位)。

19. C命令行參數

執行程序時,可以從命令行傳值給 C 程序。這些值被稱為命令行參數,它們對程序很重要,特別是當您想從外部控制程序,而不是在代碼內對這些值進行硬編碼時,就顯得尤為重要了。
命令行參數是使用 main() 函數參數來處理的,其中,argc 是指傳入參數的個數,argv[] 是一個指針數組,指向傳遞給程序的每個參數。

  • 執行的程序名為數組第一個值 argv[0], argc是int類型的,它表示的是命令行參數的個數。不許要用戶傳遞,它會根據用戶從命令行輸入的參數個數,自動確定。argv是char**類型的,它的作用是存儲用戶從命令行傳遞進來的參數。它的第一個成員是用戶運行的程序名字。
  • 多個命令行參數之間用空格分隔,但是如果參數本身帶有空格,那么傳遞參數的時候應把參數放置在雙引號 “” 或單引號 ‘’ 內部
  • ./test hello world hello world 5個參數,test為執行程序名,后面以空格劃分
  • ./test "hello world" "hello world" 3個參數

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11152.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11152.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11152.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一般社保測試

SI 分析和 PI 分析主要有以下區別&#xff1a; SI 分析&#xff1a; 主要關注信號在傳輸過程中的質量&#xff0c;如信號的失真、反射、串擾等問題。 側重于確保信號的準確傳輸和接收&#xff0c;以實現可靠的數字或模擬信號通信。 PI 分析&#xff1a; 著重于電源分配網絡…

STM32快速入門(定時器之輸出PWM波形)

STM32快速入門&#xff08;定時器之輸出PWM波形&#xff09; 前言 本節主要講解STM32利用通用定時器&#xff0c;利用CCR和CNT寄存器&#xff0c;輸出指定占空比和頻率的PWM波形。其功能的應用有&#xff1a;實現LED呼吸燈的效果、控制步進電機、控制直流電機轉速等。 導航 …

Java 類加載過程

什么是類加載 Java 類加載是指將 Java 字節碼文件加載到 Java 虛擬機&#xff08;JVM&#xff09;中&#xff0c;并將其轉化為可以執行的可執行代碼的過程。當 Java 程序在運行時引用某個類時&#xff0c;JVM 會首先檢查是否已經加載該類&#xff0c;如果沒有加載&#xff0c;則…

ue5地編模塊學習記錄

ue5網站功能3d溜溜網下載模型https://anyconv.com/max-to-fbx-converter/3dmax轉換fbx模型解決問題記錄 一、光源 搜索光源搜索不到的時候可以點擊 窗口> 對場景內的光照進行處理

【Java】數組訓練案例

訓練案例1 需求描述&#xff1a; 定義一個含有五個元素的數組&#xff0c;并為每個元素賦值&#xff0c;求數組中所有元素的最小值。 操作步驟描述&#xff1a; 1&#xff09; 定義5個元素數組。 2&#xff09; 可以使用初始化數組的兩種方式之一為數組元素賦值。 3&#xff09…

最佳解決Maven同一依賴多版本共存問題,重復依賴(同一個jar包,多個版本)-maven-shade-plugin

先看鏈接:原文鏈接 參照原文鏈接生成的文件(下面是我放的位置) mvn指令 mvn install:install-file -DfileD:\mavenrepository/maven-shade.jar -DgroupIdcom.wj -DartifactIdmaven-shade -Dversion1.1 -Dpackagingjar如果配置了maven_home 和java_home可以任意打開cmd執行(…

Google: 在新知識上微調大語言模型是否會鼓勵產生幻覺?

摘要 當大型語言模型通過監督式微調進行對齊時,它們可能會遇到在預訓練期間沒有獲得的新事實信息。人們經常推測,這可能會教導模型產生事實上不正確的回應的行為,因為模型被訓練成生成沒有基于其預先存在的知識的事實。在這項工作中,Google研究了這種暴露在新知識下對微調后模…

基于springboot實現高校教師電子名片系統項目【項目源碼+論文說明】計算機畢業設計

基于springboot實現高校教師電子名片系統演示 摘要 傳統信息的管理大部分依賴于管理人員的手工登記與管理&#xff0c;然而&#xff0c;隨著近些年信息技術的迅猛發展&#xff0c;讓許多比較老套的信息管理模式進行了更新迭代&#xff0c;名片信息因為其管理內容繁雜&#xff…

C++的數據結構(五):樹和存儲結構及示例

在計算機科學中&#xff0c;樹是一種抽象數據類型&#xff08;ADT&#xff09;或是實現這種抽象數據類型的數據結構&#xff0c;用來模擬具有樹狀結構性質的數據集合。這種數據結構以一系列連接的節點來形成樹形結構。在C中&#xff0c;樹的概念和存儲結構是實現各種復雜算法和…

Java--初識類和對象

前言 本篇講解Java類和對象的入門版本。 學習目的&#xff1a; 1.理解什么是類和對象。 2.引入面向對象程序設計的概念 3.學會如何定義類和創建對象。 4.理解this引用。 5.了解構造方法的概念并學會使用 考慮到篇幅過長問題&#xff0c;作者決定分多次發布。 面向對象的引入 J…

Docker之grep: (standard input): binary file matches

使用 docker compose logs -f | grep 命令時遇到了 grep: (standard input): binary file matches 錯誤。 這個錯誤通常發生在 grep 嘗試搜索包含二進制內容的文件時。docker compose logs 命令會輸出容器的日志&#xff0c;而這些日志可能包含二進制數據&#xff0c;導致 gre…

MySQL查詢篇-集合運算

文章目錄 union &#xff08;并集&#xff09;union distinctunion all intersect(交集)intersect allintersect distinct except 差集except distinctexcept distinctexcept all union &#xff08;并集&#xff09; union distinct 使用前提&#xff1a;a和c數據類型一致&a…

互聯網摸魚日報(2024-05-13)

互聯網摸魚日報(2024-05-13) 36氪新聞 當綠色飛行成為潮流&#xff0c;這家航空公司定下了新目標 | 最前線 回收雨水澆花&#xff0c;廚余垃圾變肥料&#xff0c;我們打卡了阿里北京新園區 | 最前線 本周雙碳大事&#xff1a;中美就氣候問題進行會談&#xff1b;鋰電池行業迎…

GIAT: 蛋白質結構預測的新利器

瑞典Karolinska研究院在瑞典政府贊助下由Ben Murrell等研究團隊在AlphaFold 3最新報告后提出這篇論文提出了一種非常有趣和創新的方法來生成蛋白質骨架結構,稱為生成式不變角度轉換器(GIAT)。與現有的主要基于擴散模型和流匹配的方法不同,GIAT采用了類似于大型語言模型(如GPT)中…

【C語言|數據結構】雙向鏈表

文章目錄 前言1、初步認識雙向鏈表1.1 定義&#xff1a;1.2 結構1.3 節點的存儲 2、雙向鏈表的接口函數2.1 鏈表的節點的動態申請2.2 鏈表的初始化2.3 尾插2.4 頭插2.5 頭刪2.5 尾刪2.6 在pos節點后面添加數據2.6 刪除pos節點 3、雙向鏈表的實現&#xff1a; 前言 各位小伙伴大…

C控制語句:分支和跳轉

1.1if語句 //colddays.c --找出0攝氏度以下的天數占總天數的百分比 #include <stdio.h>int main(void) {const int FREEZING 0;float temperature;int cold_days 0;int all_days 0;printf("Enter the list of daily low temperature.\n");printf("Use…

電子學會C/C++編程等級考試2024年03月(八級)真題解析

C/C編程&#xff08;1~8級&#xff09;全部真題?點這里 第1題&#xff1a;道路 N個以 1 … N 標號的城市通過單向的道路相連:。每條道路包含兩個參數&#xff1a;道路的長度和需要為該路付的通行費&#xff08;以金幣的數目來表示&#xff09; Bob and Alice 過去住在城市 1.在…

藍海創業商機小吃配方項目,日入200+ ,小白可上手,圖文創作轉現快

小吃技術銷售&#xff0c;一單價格從幾元到幾百元不等&#xff0c;行業競爭相對較小&#xff0c;是一個相對冷門的領域。只需一部手機&#xff0c;就可以發布圖文并茂的內容&#xff0c;配上背景音樂&#xff08;BGM&#xff09;&#xff0c;即使是對視頻剪輯不熟悉的新手&…

面試中算法(金礦)

有一位國王擁有5座金礦&#xff0c;每座金礦的黃金儲量不同&#xff0c;需要參與挖掘的工人人數也不同。 例如&#xff0c;有的金礦儲量是5ookg黃金&#xff0c;需要5個工人來挖掘;有的金礦儲量是2ookg黃金&#xff0c;需要3個工人來挖掘...... 如果參與挖礦的工人的總數是10。…

【Oracle impdp導入dmp文件(windows)】

Oracle impdp導入dmp文件&#xff08;windows&#xff09; 1、連接數據庫2、創建與導出的模式相同名稱的用戶WIRELESS2&#xff0c;并賦予權限3、創建directory 的物理目錄f:\radio\dmp&#xff0c;并把.dmp文件放進去4、連接新用戶WIRELESS25、創建表空間的物理目錄F:\radio\t…