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

C語言進階核心:雙重指針、多文件編程、文件操作全解析

     編輯:C 語言入門

一、雙重指針:修改指針本身的鑰匙

單級指針傳遞的是地址副本,函數內修改指針指向不影響外部。若需在函數內修改指針變數本身(如分配內存並回傳地址),必須傳遞指針的指針。

void modify_ptr(int **pp) {  // 接收指針地址
    *pp = malloc(sizeof(int)); // 修改一級指針指向
    **pp = 42;
}

int main(void) {
    int *p = NULL;
    modify_ptr(&p);  // 傳遞 p 的地址
    printf("%d\n", *p); // 42
    free(p);
}

口訣:函數要改誰,就傳誰的地址。改變量傳 &var,改一級指針傳 &ptr(即二級指針)。

二、多文件編程:模塊化開發基石

標準三件套

  • math_bmd.h:介面,僅含函數宣告、類型定義、宏常量。
  • math_bmd.c:實作,包含頭文件,定義函數體。
  • main.c:使用者,包含頭文件,調用介面。
/* math_bmd.h */
#ifndef MATH_BMD_H
#define MATH_BMD_H
float sum(float a, float b);
#endif

/* math_bmd.c */
#include "math_bmd.h"
float sum(float a, float b) { return a + b; }

/* main.c */
#include <stdio.h>
#include "math_bmd.h"
int main(void) {
    printf("%.2f\n", sum(10.1f, 20.1f));
    return 0;
}

編譯鏈接

gcc -c math_bmd.c -o math_bmd.o
gcc -c main.c -o main.o
gcc main.o math_bmd.o -o app

或一步到位:gcc main.c math_bmd.c -o app。未來可將 .c 編譯為靜態庫 .a/動態庫 .so,僅發布 .h 實現二進制分發。

三、文件操作:從鍵盤/螢幕到磁盤的統一抽象

核心概念

  • FILE*:文件流指針,指向內部 FILE 結構(含緩衝區、文件描述符、位置指針等)。
  • fopen/fclose:打開/關閉文件,務必成對使用,否則緩衝區數據可能丟失。
  • 模式字串:r 讀、w 寫(截斷)、a 追加、+ 讀寫雙向。

文本文件讀寫示例

struct Student { int number; char *name; };

/* 寫入 */
FILE *fp = fopen("a.txt", "w");
for (int i = 0; i < 3; ++i)
    fprintf(fp, "%d %s ", stu[i].number, stu[i].name);
fclose(fp);

/* 讀取 */
fp = fopen("a.txt", "r");
for (int i = 0; i < 3; ++i) {
    char buf[20];
    fscanf(fp, "%d %s ", &stu[i].number, buf);
    stu[i].name = strdup(buf);  // 需手動釋放
}
fclose(fp);

二進制塊讀寫

fwrite(&stu, sizeof(struct Student), 3, fp);  // 整結構體寫入
fread(&stu, sizeof(struct Student), 3, fp);   // 整結構體讀出

二進制模式("wb"/"rb")無格式轉換,速度快、精確還原內存佈局,但可移植性受字節序、對齊影響。

關鍵工具函數

函數用途
fseek(fp, offset, SEEK_SET/CUR/END)移動位置指針
ftell(fp)獲取當前位置(字節偏移)
rewind(fp)回到文件開頭(等價 fseek(fp,0,SEEK_SET))
feof(fp)判斷是否讀到末尾
ferror(fp)判斷是否發生錯誤

常見錯誤與最佳實踐

  1. 檢查 fopen 返回值,失敗時 errno 指示原因。
  2. 同一文件流不可重複 fopen,需先 fclose。
  3. 讀寫切換前調用 fflush/fseek/rewind 刷新緩衝區,否則數據混亂。
  4. 動態分配的字符串成員讀取後必須 free,防止內存洩漏。
  5. 判斷文件為空:fseek(fp,0,SEEK_END); if(ftell(fp)==0) empty;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved