【簡單地過一遍C語言基礎部分】所有知識點,點到為止!(僅一萬多字)
「這是我參與2022首次更文挑戰的第1天,活動詳情檢視:2022首次更文挑戰」。
前言:
本章從如何寫主函式開始講起,對C語言基礎知識點進行蜻蜓點水地介紹。
圖示說明:
❓ 表示問題
📚 表示知識點
❕ 表示注意
🔍 表示比較
🔨 表示操作/解決方案
💬 程式碼塊
💭 思考/思考題
🚩 執行程式碼
✅ 正確
❌ 錯誤
❎ 可以但是不建議
🅰 .c檔案B
🅱 .c檔案B
📺 系統環境/編譯器/環境
🔺 表示總結
🚫 表示禁止
📜 表示建議
📌 注意事項
🔑 表示解析、答案
💡 解決方案
💀 死迴圈
🐞 BUG
💊 DEBUG
🚀 提交
📦 封裝
⚡ 程式碼優化
👆👇👈👉 方位
## 注:本圖示適用於本人所有C語言系列部落格!
一、如何寫程式碼
0x00 首先寫主函式
❓ 何為main函式?
main函式,又稱主函式,是程式執行的起點。
1. 主函式是程式的入口
2. 主函式有且只有一個
📚 一個工程中可以有多個“.c檔案”,但是多個“.c檔案”中只能有一個“main 函式”
0x01 然後寫程式碼
💬 "你好,世界!"
#include <stdio.h> //標頭檔案
int main()
{
printf("hello world!\n");
return 0;
}
0x02 最後執行程式
🔨 編譯 + 連結 + 執行程式碼
快捷鍵:
Ctrl + F5
( VS2013 )
[除錯] -> [選擇' 開始執行(不除錯)']
❓ “是不是有什麼一閃而過了?”
因為程式執行得太快,所以沒有看到結果。
為了看到結果,我們需要設定一下 VS2013 的屬性 ( VS2019不需要設定專案屬性 )
[解決方案資源管理器] -> [右鍵專案名稱] -> [屬性] -> [連結器] -> [系統]
-> [子系統] -> [選擇' 控制檯(/SUBSYSRTEM:CONSOLE) ']
🚩 執行結果如下:
二、資料型別
0x00 基本型別
📚 這裡先做些簡單的介紹:
💬 基本資料型別的使用方法:
int main()
{
char ch = 'a';
int age = 20;
float weight = 50.8;
double d = 0.0;
return 0;
}
0x01 格式說明
📚 格式說明由“%”和格式字元組成:
💬 演示:
int main()
{
printf("%d\n", 100);
printf("%c\n", 'a');
float foo = 5.0;
printf("%f\n", foo);
double pi = 3.14;
printf("%.2lf\n", pi); // .xf(x為小數點保留幾位數)
char str1[] = "hello";
printf("%s\n", str1);
int a = 10;
printf("%p\n", &a);
return 0;
}
🚩 執行結果: 100 a 5.000000 3.14 hello 0000000000061FE04
0x03 資料型別的大小
📺 32位系統下:
📚 關鍵字 sizeof :獲取資料在記憶體中所佔用的儲存空間,以位元組為單位計數
💬 使用方法演示:
int main()
{
char a = 'A';
printf("%d\n", sizeof(a))
printf("%d\n", sizeof a) //求變數時可省略括號 ✅
printf("%d\n", sizeof(char));
printf("%d\n", sizeof char); //error!但是求字元型別時不可省略 ❌
return 0;
}
🚩 執行結果:1
💬 使用 sizeof 求元素個數:
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", sizeof(arr)); //計算的是陣列的總大小,單位是位元組
printf("%d\n", sizeof(arr[0])); //計算的是陣列首字元大小
int sz = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", sz);
return 0;
}
🚩 執行結果: 40 4 10
📚 計算機中的單位: bit - 位元位
計算機中識別二進位制:1&0 8進位制:0-7 10進位制:0-9
三、變數與常量
0x00 建立變數
💬 程式碼演示:
#include <stdio.h>
int main()
{
int age = 20;
double weight = 62.5;
age = age + 1;
weight = weight - 10;
printf("%d\n", age);
printf("%lf\n", weight);
return 0;
}
0x01 全域性變數和區域性變數
💬 區域性變數和全域性變數的名字相同時,區域性變數優先,對區域性影響:
int var = 100;
int main()
{
int var = 10;
printf("%d\n", var);
return 0;
}
🚩 執行結果: 10
0x02 scanf 函式
💬 使用方法演示:
int main()
{
int a = 0;
scanf("%d", &a);
printf("%d", a);
return 0;
}
0x03 變數的使用
💬 使用方法演示:寫一個程式碼求兩個變數的和
int main()
{
int a = 0;
int b = 0;
int sum = 0;
scanf("%d %d", &a, &b);
sum = a + b;
printf("sum = %d\n", sum);
return 0;
}
❗ 如果編譯器發出了警告,說 scanf 不安全,在程式碼前面新增
define _CRT_SECURE_NO_WANRINGS 1
即可,當然還有其他方法可以解決,這裡就不細說了。
🚩 執行結果如下:(假設輸入了 1 2)
sum = 3
0x04 作用域和生命週期
📚 作用域(scope)
程式設計概念,通常來說,一段程式程式碼中所用到的名字並不總是有效/可用 的 而限定這個名字的可用性的程式碼範圍就是這個名字的作用域。
全域性變數的作用域是整個工程。
區域性變數的作用域是變數所在的區域性範圍。
📚 生命週期:
變數的生命週期:變數的建立和銷燬之間的時間段
區域性變數的生命週期:進入作用域生命週期開始,出作用域生命週期結束。
全域性變數的生命週期:整個程式的生命週期。
💬 區域性變數的生命週期:
int main()
{
{
int a = 10;
printf("%d\n", a);
}
printf("%d\n", a); //error 生命週期結束了
}
💬 全域性變數的生命週期
//宣告一下變數
extern int g_val;
int main()
{
printf("%d", g_val);
}
0x05 常量
📚 定義:C語言中常量和變數的定義的形式有所差異
C語言的常量分為以下幾種:
① 字面常量:直接寫
② const 修飾的常變數:用 const 定義
③ #define 定義的識別符號常量:巨集定義
④ 列舉常量:可以一一列舉的常量
💬 字面常量:
int main()
{
3.14;
10;
'a';
"abcdef";
}
💬 const 修飾的常量:
int main()
{
const int num = 10;
num = 20; //error, 不能修改
printf("num = %d\n", num);
}
🚩 執行結果: 10
💬 #define 定義的識別符號常量:
#define MAX 10000 // 不寫=,不加分號!
int main()
{
int n = MAX;
printf("%d\n", n);
}
🚩 執行結果:10000
💬 列舉常量:
//性別
enum Sex {
//這種列舉型別的變數的未來可能取值
//列舉常量
MALE = 3, //賦初值
FEMALE,
SECRET
};
int main()
{
enum Sex s = MALE;
printf("%d\n", MALE);
// MALE = 3 error 不可修改
printf("%d\n", FEMALE);
printf("%d\n", SECRET);
return 0;
}
📌 注意事項:
const 只是一個有常屬性的變數,本質上仍然為變數!arr[], 陣列的大小必須是常量!
int main()
{
const int n = 10; //n是變數,但是又有常屬性,所以我們說n是常變數
int arr[n] = {0}; // 仍然不可以,因為n是變數,只是有常屬性而已
return 0;
}
💬 #define 定義的可以,巨集定義用得最多的地方是在陣列中用於指定陣列的長度:
#define N 10
int main()
{
int arr[N] = {0};
return 0;
}
📌 注意事項:
列舉常量雖然是不能改變的,但是通過列舉常量創造出來的變數是可以改變的!
enum Color
{
// 列舉常量
RED,
YEELOW,
BULE
};
int main()
{
enum Color c = BULE; //我們建立一個變數c,並將BULE賦給它
c = YEELOW; //這時將YEELOW賦給它,完全沒有問題 ✅
BULE = 6; //error!列舉常量是不能改變的 ❌
return 0;
}
四、字串&轉義字元&註釋
0x00 字串
📚 定義:
"hello world."
這種由雙引號(Double Quote)引起來的一串字元稱為字串字面值(String Literal)
📚 關於斜槓零:
字串的結束標誌是一個 \0 轉義字元。
在計算字串長度的時候 \0 是結束標誌,不算字串的內容!
💬 下面程式碼,列印的結果是什麼?為什麼?
int main()
{
char arr1[] = "abc"; //陣列
// "abc" -- 'a' 'b' 'c' '\0'
// 這裡面,'\0' 字串的結束標誌
char arr2[] = {'a', 'b', 'c'};
char arr3[] = {'a', 'b', 'c', '\0'};
printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);
return 0;
}
🚩 列印結果如下:
0x01 計算字串長度
📚 strlen 函式:返回字串的長度
📜 使用時需引入標頭檔案
💬 程式碼演示:
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = "abc";
char arr2[] = {'a', 'b', 'c'};
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}
🚩 執行結果如下: 3
隨機值
0x02 ASCII 碼值
📚 ASCII (American Standard Code for Information Interchange)
“是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。它是最通用的資訊交換標準,並等同於國際標準ISO/IEC 646。ASCII第一次以規範標準的型別發表是在1967年,最後一次更新則是在1986年,到目前為止共定義了128個字元”
0x03 轉義字元
📚 轉意字元顧名思義就是轉變字元的意思。
💬 讓斜槓就是斜槓:
int main()
{
printf("c:\\test\\32\\test.c"); //再加一個斜槓,規避轉義字元檢測
return 0;
}
🚩 執行結果: c:\test\32\test.c
💬 三字母詞、輸出單引號、ddd、xdd:
int main()
{
printf("(are you ok?\?)\n"); // ??) -- ] - 三字母詞
printf("%c\n", '\''); //輸出一個單引號
printf("%s\n", "\""); //輸出一個雙引號
printf("%c\n", '\130');//8進位制的130是10進位制的多少呢?
//X - ASCII碼值是88
printf("%c\n", '\101'); // A- 65 - 8進位制是:101
printf("%c\n", '\x30'); //48 - '0'
return 0;
}
🚩 執行結果: (are you ok??) ' " X A 0
❓ 下列程式碼列印的結果是什麼?
int main()
{
printf("%d\n", strlen("c:\test\328\test.c"));
return 0;
}
💡 答案:14
0x04 註釋
📚 程式碼中有不需要的程式碼可以直接刪除,也可以註釋掉
程式碼中有些程式碼比較難懂,可以加一下注釋文字
有兩種風格:
① C語言風格的註釋 /* xxxxxx */
缺陷:不能巢狀註釋
② C++風格的註釋 //xxxxxxxxx
優點:可以註釋一行也可以註釋多行
快捷鍵:
Ctrl + /?
💬 演示:
/* C語言風格註釋
int Add(int x, int y) {
int z = 0;
z = x + y;
return z;
}
*/
int Add(int x, int y) {
return x + y;
}
int main()
{
// C++註釋風格
// int a = 10;
printf("%d\n", Add(1,2)); //呼叫Add函式
return 0;
}
五、分支和迴圈
0x00 if 語句
📚 定義:if 語句是指程式語言(包括c語言、C#、VB、java、組合語言等)中用來判定所給定的條件是否滿足,根據判定的結果(真或假)決定執行給出的兩種操作之一。
💬 選擇語句程式碼演示:
int main()
{
int a = 10;
int b = 20;
if(a>b) {
printf("a比b大\n") ;
} else {
printf("b比a大\n");
}
return 0;
}
🚩 執行結果: b比a大
❓ C語言中如何實現迴圈呢?
1. while 語句
2. for 語句
3. do ... while 語句
這裡我們著重先了解下 while 語句。
📚 while 迴圈的基本概念:while是計算機的一種基本迴圈模式。當滿足條件時進入迴圈,進入迴圈後,當條件不滿足時,跳出迴圈。
💬 演示程式碼:敲三萬行程式碼
#include <stdio.h>
int main()
{
int line = 0;
while(line < 30000) {
printf("敲程式碼: %d\n", line);
line++;
}
if(line == 30000) {
printf("恭喜你敲滿30000行程式碼!\n");
}
return 0;
}
六、函式
❓ 什麼是函式?
數學中的函式 f(x) = 2×x+5,C語言中的函式也是一樣的。
📚 函式的特點就是:簡化程式碼,程式碼複用。
💬 程式碼演示:
int Add (int x, int y) {
int z = 0;
z = x + y;
return z;
}
int main()
{
int num1 = 0;
int num2 = 0;
scanf("%d%d", &num1, &num2);
// int sum = num1 + num2;
// 函式的方式解決
int sum = Add(num1, num2);
printf("%d\n", sum);
return 0;
}
七、陣列
📚 要儲存1-10的數字,怎麼儲存?
“C語言給了陣列的定義:一組相同型別元素的集合”
定義一個整型陣列,最多放十個元素:
💬 程式碼演示:
int main()
{
int a = 0;
int b = 0;
int c = 0;
int d = 0;
//...
// 10個整型1-10存起來
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
char ch[5] = {'a', 'b', 'c'}; // 不完全初始化,剩餘的預設為0
// 用下標就可以訪問元素
printf("%d\n", arr[0]);
// 列印整個陣列
int i = 0;
while(i<10) {
printf("%d ", arr[i]);
i++;
}
return 0;
}
八、操作符簡單介紹
0x00 算數操作符
❓ 什麼是算數操作符?
📚 算術運算子即算術運算子號。是完成基本的算術運算 (arithmetic operators) 符號,就是用來處理四則運算的符號。
💬 程式碼演示:
int main()
{
int add = 1 + 1;
int sub = 2 - 1;
int mul = 2 * 3;
float div = 9 / 2.0; //只要有浮點數出現,執行的就是浮點數除法
int mod = 123 % 10;
return 0;
}
0x01 移位操作符
❓ 什麼是移位操作符?
📚 移位運算子在程式設計中,是位操作運算子的一種。移位運算子可以在二進位制的基礎上對數字進行平移。
💬 程式碼演示:
int main()
{
// 移位操作符 移動的是它的二進位制位
// << 左移
// >> 右動
int a = 1;
// 整形1佔4個位元組-32bit位
// 0000000000000000000000000000001
int b = a<<1;
// 0000000000000000000000000000010 左邊丟棄,右邊補0
printf("%d\n", b);
printf("%d\n", a);
return 0;
}
🚩 執行結果: 2 1
0x02 位操作符
❓ 什麼是位操作符?
📚 位操作是程式設計中對位模式按位或二進位制數的一元和二元操作
💬 程式碼演示:
#include <stdio.h>
int main()
{
//位操作 依然是二進位制位
// & 按位與 都為真,則返回真,只要出現假,就返回假
int a = 3; //真
int b = 5; //真
int c = a&b; //按位與
// 011
// 101
// 001
// R→ 1 //真
printf("%d\n", c);
int d = a|b;// 按位或 有真則為真,無則假,只要出現真,就返回真
// 011
// 101
// 111
// R→ 7
printf("%d\n", d);
int e = a^b;// 按位異或 相同為假,相異為真 11\ 00-> 0 10 -> 1
//異或的計算規律
//對應的二進位制位相同,則為0
//對應的二進位制位相異,則為1
// 011
// 101
// 110
// R→
printf("%d\n", e);
return 0;
}
0x03 賦值操作符
❓ 什麼是賦值操作符?
📚 賦值運算子是雙目運算子,用在賦值表示式中。賦值運算子將值儲存在運算子左邊運算元指定的變數中。
💬 程式碼演示:
#include <stdio.h>
int main()
{
int a = 10;
a = 20; // “=” 賦值 “==” 判斷相等
a = a+10; //1
a += 10; // 2
a = a-20;
a -= 20;
a = a & 2;
a &= 2;
//這些操作叫做 複合賦值符
return 0;
}
0x04 單目操作符
❓ 什麼是單目操作符?
📚 單目操作符,也就是隻接受一個運算元的操作符。
💬 邏輯反操作 !
int main()
{
//0表示假,非0就是真
int a = 5;
printf("%d\n", !a);
if(a) {
//如果a為真,做事
}
if(!a) {
//如果a為假,做事
}
while(a); //a != 0,做事
while(!a); //a=0,做事
return 0;
}
💬 按位取反 ~
int main()
{
int a = 0;
printf("%d\n", ~a);
// ~ 按(二進位制)位取法
//把所有二進位制位的數字,1變成0,0變成1
//整數a
// 0
// 00000000000000000000000000000000
// 11111111111111111111111111111111 ~a
// 資料在記憶體中儲存的是補碼
// 一個整數的二進位制表示有三種: 原碼 反碼 補碼
// 負數的計算 -1:
// 10000000000000000000000000000001 (原碼)
// 11111111111111111111111111111110 (反碼)
// 11111111111111111111111111111111 (補碼) -> 在記憶體中存的
// 正的整數: 原碼、反碼、補碼相同
return 0;
}
💬 前置++
int main()
{
int a = 10;
int b = ++a; //前置++, 先++後使用
printf("%d\n", b); //11
printf("%d\n", a); //11
return 0;
}
💬 後置++
int main()
{
int a = 10;
int b = a++; //後置++,先使用再++
printf("%d\n", b);
printf("%d\n", a);
return 0;
}
💬 強制型別轉換:
int main()
{
int a = (int)3.14; //強制型別轉換
printf("%d\n", a);
return 0;
}
0x05 邏輯操作符
📚 邏輯運算子或邏輯聯結詞把語句連線成更復雜的複雜語句
邏輯與:兩個都為真即為真(and)
邏輯或:一個為真即為真(or)
💬 邏輯與 &&
int main()
{
int a = 3;
int b = 5;
int c = a && b;
printf("%d\n", c); //1
return 0;
}
💬 邏輯或 ||
int main()
{
int a = 3;
int b = 0;
int c = a||b;
printf("%d\n", c); //1
return 0;
}
0x06 條件操作符
📚 條件操作符就是三目操作符
exp1成立,exp2計算,整個表示式的結果是:exp2的結果。
exp1不成立,exp2計算,整個表示式的結果是:exp3的結果。
💬 條件操作符的用法:
int main()
{
//exp1成立,exp2計算,整個表示式的結果是:exp2的結果
//exp1不成立,exp3計算,整個表示式的結果是exp3的結果
int a = 0;
int b = 3;
int max = 0;
/* 等價於
if(a>b) {
max = a;
} else {
max = b;
}
*/
max = a>b ? a : b;
return 0;
}
0x07 逗號表示式
📚 逗號表示式:逗號隔開的一串表示式。
逗號表示式是從左向右依次計算的。
整個表示式的結果是最後一個表示式的結果。
💬 逗號表示式的用法演示:
int main()
{
(2, 3+5, 6);
int a = 0;
int b = 3;
int c = 5;
// a=5 c=5-4 b=1+2
int d = (a=b+2, c=a-4, b=c+2);
printf("%d\n", d); // 3
return 0;
}
0x08 下標引用操作符
📚 [] 就是下標引用操作符。
💬 演示:
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", arr[5]); // 6
return 0;
}
0x09 函式引用操作符
📚 呼叫函式時,函式名後面的()就是函式呼叫操作符
💬 演示:
int main()
{
printf("hehe\n");
printf("%d", 100);
return 0;
}
九、關鍵字
0x00 常見關鍵字
📚 C語言提供的關鍵字:
1. C語言提供的,不能自己建立關鍵字
2. 關鍵字不能做變數名
這裡我們來簡單地介紹幾個:
💬 auto - 自動的
int main()
{
{
int a = 10; //自動建立,自動銷燬的 - 自動變數
// auto省略掉了
auto int a = 10;
// auto新的C語言中也有其它用法 - 暫時不考慮
}
return 0;
}
💬 register - 寄存關鍵字
int main()
{
// 大量/頻繁使用的資料,想放在暫存器中,提升效率
register int num = 100; //建議num的值存放在暫存器中
//是不是最終放到暫存器中是編譯器說的算
// 其實現在編輯器已經很聰明瞭,
// 就算你不主動加register,它也會幫你存到暫存器中。
return 0;
}
💬 typedef - 型別重新命名
// 這種羅裡吧嗦的變數我們可以把它重新命名一下
typedef unsigned int u_int;
int main()
{
unsigned int num = 100;
u_int num2 = 100; //和上面是等價的
return 0;
}
📚 static - 靜態的
1. static修飾區域性變數
2. static修飾全域性變數
3. static修飾函式
💬 static修飾區域性變數
函式中區域性變數:
宣告週期延長:該變數不隨函式結束而結束
初始化:只在第一次呼叫該函式時進行初始化
記憶性:後序呼叫時,該變數使用前一次函式呼叫完成之後儲存的值
儲存位置:不會儲存在棧上,放在資料段
void test() {
static int a = 1; //不銷燬,生命週期變長了
a++;
printf("%d ", a);
}
int main()
{
int i = 0;
while(i<10) {
test();
i++;
}
return 0;
}
🚩 執行結果: 2 3 4 5 6 7 8 9 10 11
💬 static修飾全域性變數
改變該變數的連結屬性,讓該變數具有檔案作用域,即只能在當前檔案中使用。
① Global.c:
static int g_val = 2021;
// static 修飾全域性變數,
// 使得這個全域性變數只能在自己所在的原始檔(.c)內部可以使用
// 其他的原始檔不能使用!
// 全域性變數,在其他原檔案內部可以被使用,是因為全域性變數具有外部連結屬性
// 但是被static修飾之後,就變成了內部連結屬性,
// 其他的原始檔就不能連結到這個靜態的全域性變量了!
② test.c:
extern int g_val;
int main()
{
printf("%d\n", g_val);
return 0;
}
🚩 執行結果: test.obj : error LNK2001: 無法解析的外部符號 _g_val
💬 static修飾函式
改變該函式的連結屬性,讓該函式具有檔案作用域,即只能在當前檔案中使用。
① Add.c:
//static修飾函式,
static int Add(int x, int y) {
return x + y;
}
💬 test1.c:
extern int Add(int, int); //宣告外部函式
int main()
{
int a = 10;
int b = 20;
int sum = Add(a, b);
printf("sum = %d\n", sum);
return 0;
}
🚩 執行結果:
test.obj : error LNK2019: 無法解析的外部符號 _Add,該符號在函式 _main 中被引用
0x01 define
📚 define 是一個預處理指令:
1. define 定義識別符號常量
2. define 定義巨集
💬 define 定義識別符號常量:
#define MAX 1000
int main()
{
printf("%d\n", MAX);
return 0;
}
💬 define 定義巨集:
#define ADD(X, Y) X+Y
#define ADD1(X, Y) ((X)+(Y))
int main()
{
printf("%d\n", 4*ADD(2, 3));
// 4*2+3 = 11
printf("%d\n", 4*ADD1(2, 3));
// 4*(2+3) = 20
return 0;
}
十、指標初探
0x00 指標介紹
❓ 什麼是指標?
指標就是地址,地址就是指標。
指標,是C語言中的一個重要概念及其特點,也是掌握C語言比較困難的部分。指標也就是記憶體地址,指標變數是用來存放記憶體地址的變數,不同型別的指標變數所佔用的儲存單元長度是相同的,而存放資料的變數因資料的型別不同,所佔用的儲存空間長度也不同。有了指標以後,不僅可以對資料本身,也可以對儲存資料的變數地址進行操作。
💬 變數都有地址,取出變數的地址如下:
int main()
{
int a = 10; // a在記憶體中要分配空間 - 4個位元組
&a; // 取出num的地址
printf("%p\n", &a); //%p - 以地址的形式列印
return 0;
}
🚩 打印出來的是a的地址
💬 定義指標變數,儲存地址
* 說明 pa 是指標變數
int 說明 pa 執行的物件是 int 型別的
int main()
{
int a = 10;
int* pa = &a; // pa是用來存放地址的,在C語言中叫pa的是指標變數
char ch = 'w';
char* pc = &ch;
return 0;
}
0x01 解引用操作
如果把定義指標理解為包裝成快遞,那麼“解引用操作”就可以理解為是拆包裹
拆出來的值就是那個變數的值,甚至還可以通過“解引用”來修改它的值。
💬 解引用操作用法:
int main()
{
int a = 10;
int* pa = &a;
*pa = 20; // * 解引用操作 *pa就是通過pa裡邊的地址,找到a
printf("%d\n", a); //20
return 0;
}
0x02 指標的大小
📚 指標的大小
“指標的大小是相同的”
❓ 為什麼相同?
“因為指標是用來存放地址的,指標需要多大空間,取決於地址的儲存需要多大空間”
📺 指標是一種複合資料型別,指標變數內容是一個地址,因此一個指標可以表示該系統的整個地址集合,故按照32位編譯程式碼,指標佔4個位元組,按照64位編譯程式碼,指標佔8個位元組(注意:不是64位系統一定佔8個位元組,關鍵是要按照64位方式編譯)。
32位 - 32bit - 4byte
64位 - 64bit - 8byte
💬 sizeof 計算指標的大小:
int main()
{
printf("%d\n", sizeof(char*));
printf("%d\n", sizeof(short*));
printf("%d\n", sizeof(int*));
printf("%d\n", sizeof(long*));
printf("%d\n", sizeof(long long*));
printf("%d\n", sizeof(float*));
printf("%d\n", sizeof(double*));
return 0;
}
32位下都是 4 64位下都是 8
十一、結構體
0x00 什麼是結構體
📚 結構體可以讓C語言創建出新的型別
“結構體是C語言中特別重要的知識點,結構體使得C語言有能力描述複雜的型別”
💬 使用結構體描述學生 / 描述書:
// 建立一個學生的型別
struct Stu {
char name[20]; // 姓名
int age; // 年齡
double score; // 分數
}; // ← 不要忘了加分號
// 建立一個書的型別
struct Book {
char name[20];
float price;
char id[30];
};
💬 結構體的初始化:
點操作符和箭頭操作符
. 結構體變數.成員
-> 結構體指標->成員
struct Stu {
char name[20]; // 姓名
int age; // 年齡
double score; // 分數
};
struct Book {
char name[20];
float price;
char id[30];
};
int main()
{
struct Stu s = {"張三", 20, 85.5}; // 結構體的建立和初始化
// 點操作符
printf("1: %s %d %lf\n", s.name, s.age, s.score);
struct Stu* ps = &s;
printf("2: %s %d %lf\n", (*ps).name, (*ps).age, (*ps).score); // ❎ 可以但不推薦
// 箭頭操作符
printf("3: %s %d %lf\n", ps->name, ps->age, ps->score); // ✅ 推薦
return 0;
}
參考文獻 / 資料
Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .
俞甲子 / 石凡 / 潘愛民. 《程式設計師的自我修養》[M]. 電子工業出版社, 2009-4.
百度百科[EB/OL]. []. https://baike.baidu.com/.
位元科技. C語言基礎[EB/OL]. 2021[2021.8.31]. .
本章完。