歡迎訪問我的新博客:http://www.milkcu.com/blog/
原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation.html
原創:C語言指針操作
作者:MilkCu
摘要:指針是C語言的核心,也是一個普通變量,存儲的是內存中的地址。在存儲空間的分配中,一種常遵循的理念是,由用戶管理存儲空間以及與存儲空間相關的實際的數據結構,而數據結構自身只用於維護數據內部變量的存儲空間的分配。C語言使用基於堆的內存分配,通常也稱作動態存儲分配。
指針基礎
一個指針其實只是一個變量,它存儲數據在內存中的地址,而不是存儲數據本身。
可能產生懸空指針的一些編程錯誤事例包括:
-
將任意的整型變量強制轉換爲指針變量;
-
操作超出數組邊界的指針;
-
釋放一個或多個仍被引用的指針。
存儲空間分配
通常情況下,指針會佔用一個機器字長的存儲空間,但有些時候它們的大小也有所不同。
用malloc分配的存儲空間會一直有效,知道調用函數free來釋放它。
內存泄露問題的產生是由於動態分配了內存空間,但從未釋放它造成的。特別是在重複執行代碼時,這種泄露問題會表現得尤爲重要。
一種統一的內存管理方法所遵循的理念是,由用戶管理存儲空間以及與存儲空間相關的實際的數據結構,而數據結構自身只用於維護數據內部變量的存儲空間的分配。所以,在數據結構中,只使用指針指向數據變量,而不是此數據的私有副本。
數據集合與指針的算術運算
指針在C語言中最長見的用途就是用來引用數據集合。C語言支持兩種數據集合:結構和數組。
結構不允許包含自身的實例,但可以包含指向自身實例的指針。
當一個數組標識符在表達式中出現時,C語言會把數組轉換爲一個指向數組第一個元素的指針。
在C語言中,多爲數組其實是以行主序的方式存儲的,這也就說明多維數組右邊下表變化速度要比左邊下標變化來的更快。
二維數組第i行第j列的元素,用a[i][j]表示,等價於((a + i) + j)。
作爲函數參數的指針
當把一個多維數組傳遞給函數時,除了第一維以外其他維的長度必須指定。
泛型指針與類型轉換
泛型指針不指定具體的數據類型。可以使用泛型指針實現交換任何類型數據的通用交換函數。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int swap2(void *x, void *y, int size)
{
void * tmp;
if((tmp = malloc(size)) == NULL) {
return -1;
}
memcpy(tmp, x, size);
memcpy(x, y, size);
memcpy(y, tmp, size);
free(tmp);
return 0;
}
int main(void)
{
int a = 2;
int b = 3;
swap2(&a, &b, sizeof(int));
printf("a = %d\nb = %d\n", a, b);
return 0;
}
地址取到什麼類型的值是由我們用什麼類型的指針訪問它所決定的。
函數指針
聲明函數指針看起來與聲明一個函數非常相似,只是在函數名前有一個表示指針的星號,並且函數名和星號會用圓括號括起來。
函數指針的一個重要用途是將函數封裝到數據結構中,它可以使數據結構或函數變得更具通用性。
基於堆的內存分配
C語言使用基於堆的內存分配,通常也稱作動態存儲分配。它允許一個程序在運行時請求更多所需要的內存,而不是在編譯時就分配固定數額的內存。
(全文完)
本文地址:http://www.milkcu.com/blog/archives/pointer-manipulation.html