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

C 語言存儲類別與動態內存分配完全指南

     編輯:關於C語言

一、存儲類別與內存佈局

核心概念表

術語解釋示例
作用域標識符可訪問的程序區域塊、函數、函數原型、文件
鏈接變量跨文件可見性外部、內部、無
存儲期對象生命週期靜態、線程、自動、動態分配
翻譯單元編譯單元:源文件+頭文件—.

作用域與鏈接詳解

  • 塊作用域:{ } 內,C99 允許循環語句形成塊。無鏈接。
  • 函數作用域:僅用於 goto 標簽。無鏈接。
  • 函數原型作用域:形參名僅在原型中可見。無鏈接。變長數組聲明需在原型中指定維度。
  • 文件作用域:函數外定義,至文件末尾可見。具內部/外部鏈接。
  • 外部鏈接:全程序可見。定義處無關鍵字,引用處用 extern。
  • 內部鏈接:僅本翻譯單元可見。static 修飾文件級變量。
  • 無鏈接:塊內變量、函數參數等。

存儲期分類

  • 靜態存儲期:程序啟動到結束。全局/靜態變量。
  • 線程存儲期:線程生命週期(C11)。
  • 自動存儲期:塊執行期間。局部非靜態變量。
  • 動態分配存儲期:程序員手動管理(malloc/free)。

存儲類別總結表

存儲類別存儲期作用域鏈接聲明方式
自動自動塊無塊內
靜態外部鏈接靜態文件外部函數外,引用需 extern
靜態內部鏈接靜態文件內部函數外,static
靜態無鏈接靜態塊無塊內,static

內存佈局:靜態區(含常量)、棧區(自動)、堆區(動態)。

二、動態內存分配:malloc() / free()

基本用法

int *ptr, n = 10;
ptr = (int *)malloc((size_t)n * sizeof(int));
if (ptr == NULL) exit(EXIT_FAILURE);  // 必須檢查

// 使用 ptr ...

free(ptr);  // 及時釋放,防內存洩漏

或合寫:if (!(ptr = malloc(...))) exit(EXIT_FAILURE);

注意:若指針丟失未 free,造成內存洩漏,嚴重時耗盡系統內存導致崩潰。

三、動態數組排序實例

實例代碼圖示

#include <stdio.h>, <stdlib.h>, <conio.h>

int main() {
    int *ptr, size, i, j, key;
    printf("請輸入動態數組大小:");
    while (!(scanf("%d", &size)) || size < 0) { /* 重輸 */ }

    if (!(ptr = malloc((size_t)size * sizeof(int)))) { /* 失敗退出 */ }

    printf("請依次輸入元素:\n");
    for (i = 0; i < size; i++) scanf("%d", &ptr[i]);

    /* 插入排序 */
    for (i = 1; i < size; i++) {
        key = ptr[i]; j = i - 1;
        while (j >= 0 && ptr[j] > key) { ptr[j+1] = ptr[j]; j--; }
        ptr[j+1] = key;
    }

    printf("排序後:");
    for (i = 0; i < size; i++) printf("%d ", ptr[i]);
    free(ptr); _getch(); return 0;
}

運行結果

四、補充:realloc()

void *realloc(void *ptr, size_t size);
  • 調整 ptr 指向塊大小為 size,內容保留(截斷或擴展)。
  • 返回新地址(可能移動),失敗返回 NULL 且原塊不釋放。
  • ptr == NULL 等價 malloc(size);size == 0 等價 free(ptr)。

風險:失敗時原地址丟失導致洩漏。使用前務必備份原指針。不建議大量依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved