首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言高級指針、預處理器與輸入輸出函數詳解

     編輯:關於C語言

C語言高級指針、預處理器與輸入輸出函數詳解

聲明:原創作品,轉載時請注明文章來自SAP師太博客,並以超鏈接形式標明文章原始出處,否則將追究法律責任!

第十一章 高級指針話題

指向指針的指針

多級間接訪問允許修改不同層級的變量:

int i, *pi = &i, **ppi = π
**ppi = 10; // 修改 i
*ppi = &other; // 修改 pi

函數修改調用者指針時需傳遞指針地址(二級指針)。

複雜聲明解析

  • int *f, g; → f 是指針,g 是 int
  • int (*f)(); → f 是函數指針
  • int (*f())(); → f 是返回函數指針的函數

函數指針聲明:int (*comp)(void*, void*); 括號不可省。賦值時函數名隱式轉換為地址,&func 與 func 等價。調用可用 (*pf)(arg) 或 pf(arg)。

函數指針數組與回調

聲明:void (*f[3])(int) = {fn1, fn2, fn3}; 調用:(*f[i])(arg)。最大用途是回調,如 qsort 比較函數、冒泡排序動態選擇升/降序:

void bubble(int *a, int n, int (*cmp)(int,int)) {
    if ((*cmp)(a[j], a[j+1])) swap(&a[j], &a[j+1]);
}

main 命令行參數

int main(int argc, char **argv):argv[0] 為程序名,argv[argc] == NULL。遍歷參數:while (*++argv) puts(*argv);

字符串常量技巧

字符串常量在表達式中為指針常量。"xyz"[2] 取字符 'z',*"xyz" 取 'x'。十六進制輸出妙用字符串索引:

putchar("0123456789ABCDEF"[value % 16]);

第十二章 預處理器

預定義宏

__FILE__, __LINE__, __FUNCTION__, __DATE__, __TIME__, __STDC__。宏名慣用全大寫。

宏定義與參數

#define NAME stuff 替換文本可為任意符號序列。長定義用反斜槓換行。帶參宏:#define SQUARE(x) ((x)*(x)) —— 參數與整體均需括號防止優先級錯誤。

字符串化與拼接

  • #param → 將參數轉為字符串字面量:#define PRINT(x) printf(#x "=%d", x)
  • ## → 連接符號:#define VAR(n) var##n → VAR(5) 展開為 var5

區別:# 加引號,## 直接連接符號。

宏副作用

參數多次求值導致副作用:MAX(x++, y++) 可能使 x、y 各增兩次。複雜表達式首選內聯函數。

條件編譯

#if/#elif/#else/#endif 配合 defined(MACRO) 或 #ifdef/#ifndef。可嵌套。防止頭文件重複包含標準模式:

#ifndef _HEADER_H
#define _HEADER_H 1
// 內容
#endif

文件包含

#include <sys.h> 搜索系統路徑,#include "local.h" 先搜當前目錄。頭文件慣用 .h 後綴,不應定義全局變量(多次包含導致重定義)。

第十三章 輸入/輸出函數

錯誤報告

I/O 函數失敗設置 errno,perror(msg) 輸出 msg: 錯誤描述。僅在函數失敗後檢查 errno 有意義。

流與文本/二進制模式

FILE 結構體管理緩衝區與狀態。文本流自動轉換換行符(Windows: \n↔\r\n),二進制流不轉換。fopen 模式:r/w/a + 可選 b/+。freopen 實現標準流重定向。

I/O 函數分類

類型輸入輸出
字符getc/fgetc/getcharputc/fputc/putchar
文本行fgets/getsfputs/puts
格式化fscanf/scanf/sscanffprintf/printf/sprintf
二進制freadfwrite

fgets 保留 \n,gets 丟棄 \n(不安全,已棄用)。fputs 不加 \n,puts 自動加 \n。

格式化 I/O 詳解

scanf 格式:%[*][width][修飾]類型。% 抑制賦值,width 限制最大字符數。修飾符:h(short), l(long), L(long double)。

printf 格式:%[標誌][寬度][.精度][修飾]類型。標誌:-左對齊, 0零填充, +強制符號, 空格正數前加空格, #替代形式(0x前綴等)。精度對整數指最小位數,對浮點指小數位數,對字符串指最大字符數。* 可由參數動態指定寬度/精度。

二進制 I/O

fread(ptr, size, count, fp) / fwrite(ptr, size, count, fp) 直接讀寫內存位模式,高效且保持結構體佈局。返回實際項數。結構體寫入文件後可直接讀回,但涉及指針成員時需序列化處理。

fwrite(&struct_var, sizeof(struct_var), 1, fp); // 整體寫入

流定位與緩衝控制

  • fflush(fp):強制刷新輸出緩衝區
  • ftell/fseek:基於 long 偏移定位(SEEK_SET/CUR/END)
  • fgetpos/fsetpos:使用 fpos_t 支持大文件
  • rewind(fp):等價 fseek(fp,0,SEEK_SET) 並清除錯誤標誌

文本流定位受換行轉換影響,不可移植地計算偏移;二進制流無此問題。fseek 會清除 ungetc 退回的字符。

緩衝模式設置

setbuf(fp, buf) / setvbuf(fp, buf, mode, size)。mode:_IOFBF全緩衝, _IOLBF行緩衝, _IONBF無緩衝。必須在操作前調用。

臨時文件與文件操作

  • tmpfile():創建臨時二進制更新文件 (wb+),關閉自動刪除
  • tmpnam(buf):生成唯一文件名
  • remove(name) / rename(old, new):刪除/重命名
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved