公告版位
1. 發現有錯誤, 請留言告知. (或者你 '覺得' 不對也行)
2. 用字措辭不當, 請留言告知.
3. 有看沒有懂? 幫到忙也好, 幫倒忙也罷, 總之留個言吧.
目前分類:C Language (15)
- Oct 02 Tue 2018 14:34
C 語言:使用 enum 作為陣列元素的索引
- May 29 Tue 2018 09:17
C 語言:關於 sizeof 及結構及同位的記憶體對齊
C 語言的編譯器有一個內建的巨集 sizeof() 可以用來取得配置給變數的記憶體大小. 例如:
uint32_t varX = 1234;
int size;
size = sizeof(varX);
這樣變數 size 所存儲的數值就會是變數 varX 到底在電腦裡佔用了多大的記憶體. uint32_t 型態的變數 (沒有意外的話) 應該都會佔用 4 bytes.
- Nov 11 Wed 2015 18:13
C 語言:消除 C Compiler 對未使用之函數參數之告警
寫 C 程式時偶而會遇到函數的原型宣告多設了一些暫時沒有用到的參數, 一般狀況下只要修改一下標頭檔中的宣告以及實際 C 函數的定義就好了. 不過偶而也會遇到不能改的情形, 例如:
- 套用某些框架系統時, 函數的原型宣告是框架系統提供的. (一改大概框架系統就不用升版了)
- 使用函數庫中某個函數的 call back, 而函數庫改不動, 或者沒原始程式, 沒得改.
- 在開發 embedded system 時, 我們需要實作或者改寫一些函數以取代 C 編譯器的一些預設行為, 例如: Keil ARM/MDK 中要把 printf() 改輸出到 SoC 的 UART.
下面一些方法可以在無法修改函數的原型宣告時, 把 C 編譯器對未使用的函數參數之告警消除.
- 方法一: 大部份的 C 編譯器應該都可以適用.
#define UNUSED(x) ( (void)(x) )
void f(int x, int y) {
UNUSED(x);
...
}
- Jul 23 Thu 2015 03:05
C 語言:關於變數的二三事
- Jul 20 Mon 2015 19:15
C 語言:運算子優先次序和運算次序
運算子優先權 (C 語言)
Percedence Table
運算子 Operator |
說 明 |
---|
- Jul 15 Wed 2015 10:36
C 語言:typedef 和 #define 大不同
以前以為 typedef 的功能可以用 #define 來完成, 用起來感覺功能也差不多, 例如:
typedef unsigned char bool; // 用這一行或者是下一行 二選一 //#define bool unsigned char bool flag1, flag2;
- Jul 08 Wed 2015 23:06
C 語言:typedef 的用法
C 語言中 typedef 可以用來擴充 C 原有的資料型態. 通常我們會將某個資料型態或者將常用的資料型態組合給予一個比較直觀而易懂的別名. 定義別名之後我們就可以像使用原有的資料型態來宣告或定義變數一樣, 直接拿它來宣告或定義(註一, 註二)變數.
註一: 宣告和定義有所不同. 定義變數會實際佔據記憶體空間, 而宣告變數則只產生參考的連結, 稍後連結程式時再連結到在其他模組定義的變數. 我們一般把宣告變數擺放在 header file (.h 檔) 中, 有需要的模組或程式只要 include 即可. 而定義變數則視情況放在主程式或者相關的模組中, 當然它通常也會 include 該 header file.
註二: ANSI C 標準文件說: 會實際佔據記憶體空間的宣告稱為定義. 所以 ANSI C 說的宣告包含了定義及純宣告. 而註一及以下本文中所指的宣告則是指沒有佔據記憶體空間的純宣告, 而不是 ANSI C 原先所指的宣告, 特此說明. 請參考維基網站 Declaration (computer programming) 段落二 'Declaration vs. definition' 及段落三 'Declarations and Definitions')
- Jul 07 Tue 2015 16:17
C 語言:型別轉換 (Type Casting) 技巧之四 (結構運算子 "->" 和 "." 互換)
程式在移植或者整合時, 有時會遇到使用結構來的定義程式所用到的資料的情形, 有時原作者是用一指向結構的指標來處理, 但是有時也會有直接用結構變數的情形.
這些程式我們在使用的時候按理應該盡量不要更動以免日後改版時造成問題, 不過要是遇到下面二種狀況那就...
- 原始程式是用指標來指向要處理的結構變數, 而現在我們想把規模縮小, 只會有一份結構變數, 同時也希望最佳化目的碼, 讓系統小一點, 快一點.
- 或者原始程式中把結構變數寫死了, 所有的函數都是針對那一個結構變數寫的, 結構變數生不出第二個 instance 來. 而我們卻是需要擴充一下, 讓它能處理多個結構變數.
- Jul 06 Mon 2015 13:40
C 語言:型別轉換 (Type Casting) 技巧之三 指定位址 (資料結構, 函數)
外部資料結構
在寫 CPU 或介面晶片的驅動程式時, 經常會使用到某些固定位址, 如: ARM Cortex-M 把系統設定及狀態對應到記憶體的特定位址, 某些周邊 IC, 例如 PCI, USB... 也是使用一小段記憶體空間. (註: 常見的周邊 IC 暫存器定址有二種: 一種是只有二個位址空間, 一個是 '指令/地址暫存器', 一個是 '資料暫存器'; 另一種則是直接使用 CPU 的記憶體空間來對應)
軟體功力較佳的 SoC 晶片製造廠所提供的驅動程式, 通常會將這一小段記憶體空間以結構 (struct) 的方式定義好, 再使用 define 將特定的位址值 (常數), 定義成一虛擬變數. 當然如果晶片功能比較簡單就不見得是用這種方法.
- Jun 30 Tue 2015 18:42
C 語言中常見的對等寫法
個人覺得 C 語言最神奇的地方是有好些個對等寫法
類型 | 相關運算子 | 寫法一 | 寫法二 | 說明/宣告 | |
---|---|---|---|---|---|
1. | (變數)取址 | "&" | p | &x | p 為指標, 並指向變數 x |
2. | (指標)取值 | "*" | *p | x | 同上 |
3. | 陣列與指標 | "[]" and "*" | p[n] | *(p+n) | p 為陣列變數或者指標變數 |
4. | 結構成員 | "->" and "." | p->x | (*p).x | p 為指標, 並指向一結構x 為該結構成員 |
- Jun 29 Mon 2015 13:15
C 語言:型別轉換 (Type Casting) 技巧之二 (不同型別資料之轉換)
C 語言預設會幫我們作一些型別轉換的動作, 一般的型別轉換不只會更換資料型別, 更會使資料內容有所變動, 例如:
float fVar = 1.2;
int32_t iVar;
iVar = fVar; // iVar 值為整數 1
但是萬一我們不想要這個預設的換轉, 只是想要把 fVar 的數值 (以 float 格式) 存放在變數 iVar 所佔用的記憶體中, 而又不想動用 union 設定呢? (因為使用 union 程式或多或少都需要修改, 萬一 compiler 不支援 Unnamed Structure and Union Fields (或者 Anonymous unions, C11 的功能), 則需要更動的幅度就會更大.)
- Jun 28 Sun 2015 12:59
C 語言:型別轉換 (Type Casting) 技巧之一
'型別轉換': 基本上就只是在變數/函數前面加一對小括號, 中間填入要轉成什麼型別, 像這個樣子 "(型別)", 例如:
(unsigned char *)ptr
看不出哪一點難, 對吧
- Jun 26 Fri 2015 11:09
C 語言:輕鬆讀懂複雜的宣告式 (Define and Read the complex declarations)
本文來自網站 ieng9.ucsd.edu (http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html) 加以重新排版.
呃… 它搬家了, 新網址如後: cseweb.ucsd.edu (http://cseweb.ucsd.edu/~ricko/rt_lt.rule.html)
- Jun 25 Thu 2015 09:25
C 語言:用巨集定義置換 function (關於有 ... 的巨集置換)
在系統在整合或移值時最常用的就是以巨集來置換一些底層 function. 這類的技巧叫 wrapper (意思是包裝紙)
但是在面對像 printf() 或者 scanf() 之類參數個數可變 (或稱不具名參數) 的函數, 就出現只能更換函數名稱, 而無法增減參數個數的冏境, 例如:
// 下例 OK, 但是無法處理參數的異動
#define printf my_printf
// 下例 OK, 但是只能處理剛好二個參數的異動 (增加, 交換)
#define printf(a, b) my_printf(x, b, a)
// 下例 ERR, C 編譯器的 preprocessor 不認識 ...
#define printf(a, b, ...) my_printf(x, a, b, ...)
- Jun 24 Wed 2015 09:23
C 語言:讓自己寫的 function 也能使用 ... (不具名參數, 參數個數不確定)
#include <stdarg.h>
int my_function(int cnt, char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
...
x = va_arg(ap, int); // 取得一個整數變數
...
*va_arg(ap, long *) = y; // 把一個長整數指標變數塞回去
...
va_end(ap);
...
return ret_value;
}
int main(void)
{
...
my_function(12, "abc", 6, 7, 8);
...
}
說明: