[源碼下載]
作者:webabcd
介紹
不可或缺 Windows Native 之 C 語言
示例
cPointer.h
#ifndef _MYHEAD_POINTER_ #define _MYHEAD_POINTER_ #ifdef __cplusplus extern "C" #endif char *demo_cPointer(); #endif
cPointer.c
/*
* 指針
*/
#include "pch.h"
#include "cPointer.h"
#include "cHelper.h"
void pointer_demo1();
void pointer_demo2();
void pointer_demo3();
void pointer_demo4();
void pointer_demo5();
void pointer_demo6();
void pointer_demo7();
void pointer_demo8();
void pointer_demo9();
void pointer_demo10();
char *demo_cPointer()
{
// 指針的基本概念
pointer_demo1();
// 字符串指針
pointer_demo2();
// 把指針做為參數傳遞
pointer_demo3();
// 數組指針的運算
pointer_demo4();
// 二維數組的指針
pointer_demo5();
// 函數指針(指向函數的指針)
pointer_demo6();
// 指針型函數(函數返回值可以是一個指針)
pointer_demo7();
// 指針數組
pointer_demo8();
// 指針的指針
pointer_demo9();
// void 類型的指針
pointer_demo10();
return "看代碼及注釋吧";
}
// 指針的基本概念
void pointer_demo1()
{
/*
* 注:
* 1、未經賦值的指針變量不能使用
* 2、一個指針變量只能指向相同類型的變量,比如指針 p 如果指向了整形變量,就不能再指向字符變量或其他非整型類型的變量了
*/
// 定義一個指針,並將其賦值為一個空指針(對應的宏定義 #define NULL 0)。所謂空指針就是不指向任何內容的指針
int *p_empty = NULL; // 相當於 int *p = 0;
// 定義一個整型變量,並初始化
int i = 100;
// *p - 代表定義一個名為 p 的指針。此處的“*”是類型說明符,表示 p 是一個指針
// &i - 代表取變量 i 的地址。此處的“&”是取地址運算符,表示取變量 i 的地址
int *p = &i;
// *p - 代表取指針 p 所指向的內容。此處的“*”是取內容運算符,表示取指針 p 所指向的內容
int j = *p;
}
// 字符串指針
void pointer_demo2()
{
// 定義一個字符串指針(字符串是以'\0'結尾的)
char *p = "i am webabcd";
// p 就是字符串指針,p + 5 所指向的結果就是 webabcd
char *name = p + 5;
// 字符串長度
int length = strlen(name); // 7,不包括 '\0'
// 指針占用的內存空間
int memory = sizeof(name); // 我這裡是 4 字節
char *p_address = (char *)malloc(32);
sprintf(p_address, "%p", name); // 指針 name 的地址值,我這裡是 32 位的,類似 6416C99D
free(p_address);
}
// 把指針做為參數傳遞
void pointer_demo3()
{
int m = 1;
int n = 2;
int *x = &m;
int *y = &n;
// 調用 swap 後: *x = m = 2, *y = n = 1
void swap(int *i, int *j);
swap(x, y);
}
void swap(int *i, int *j) // 交換兩個指針指向的整型值
{
// 形參是實參的副本,被調用期間分配內存單元,調用結束立即釋放
// 對於指針來說也是這樣的,只不過是 copy 了地址做為副本
int temp;
temp = *i;
*i = *j;
*j = temp;
}
// 數組指針的運算
void pointer_demo4()
{
int ary[] = { 11, 22, 33, 44, 55, 66 };
// 因為 ary 是數組的首地址,所以 ary == &ary[0]
if (ary == &ary[0])
{
// ary 是數組的首地址,即數組第一個元素的地址,對其取內容後就是數組第一個元素的內容,結果為 11
int x1 = *ary;
// 數組指針是可運算的,運算的是元素在數組中的位置索引,拿 ary + 2 舉例,ary 數組第 1 個元素的指針,加 2 後就是數組第 3 個元素的指針,取其內容後結果為 33
int x2 = *(ary + 2);
char *p0_address = (char *)malloc(32);
sprintf(p0_address, "%p", ary); // 假定此處指針本身的值為:0535DC30 的話
free(p0_address);
char *p1_address = (char *)malloc(32);
sprintf(p1_address, "%p", ary + 1); // 那麼如果整型是 4 字節的話,則此處指針本身的值為 0535DC34
free(p1_address);
}
// 再來一個指針運算的例子(將字符串 str1 復制到字符串 str2)
char str1[] = "i am webabcd", str2[20], *p1, *p2;
p1 = str1; p2 = str2;
for (; *p1 != '\0'; p1++, p2++)
*p2 = *p1;
*p2 = '\0';
p1 = str1; p2 = str2; // 指回數組首地址
}
// 二維數組的指針
void pointer_demo5()
{
int ary[2][6] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
// 定義一個二維數組的指針:類型說明符(*指針變量名)[列數,即二維長度]
int(*p)[6] = ary;
// p 就是 ary
if (p == ary)
{
// 這裡要好好理解(拿指針的指針去理解,ary 相當於二級指針,ary[i] 相當於一級指針)
// ary[1] 是二維數組第 2 行的一維數組的首地址,也就是說其相當於 &ary[1][0]
// ary + 1 指向的是 ary[1],對其取內容 *(ary + 1) 就是 ary[1] 了
// ary[1] = &ary[1][0] = *(ary + 1)
// 再加深理解一下:ary 是二維數組的首地址,*ary 是二維數組第 1 行的一維數組的首地址,*(ary + 1) 是二維數組第 2 行的一維數組的首地址
// 取第 2 行,第 6 列的數據,結果為 11
int x = p[1][5];
// 再加深理解一遍
// p 是指向二維數組的指針
// p + 1 指向的是 ary[1],所以 *(p + 1) 就是 ary[1]
// *(p + 1) + 5 指向的是 p[1][5],所以 *(*(p + 1) + 5) 就是 p[1][5],結果為 11
int y = *(*(p + 1) + 5);
// ary[i] = *(ary+i), ary[i]+j = *(ary+i)+j, ary[i][j] = *(*(ary+i)+j)
}
}
// 函數指針(指向函數的指針)
void pointer_demo6()
{
// 定義一個函數指針:類型說明符(*指針變量名)();
int(*pmax)(int a, int b);
// 讓函數指針指向函數 my_max
int my_max(int a, int b);
pmax = my_max;
int x = 10, y = 100;
// (*pmax) 就是函數 my_max,結果為 100
int z = (*pmax)(x, y);
// 函數指針當然也是指針,可以取其地址
char *p_address = (char *)malloc(32);
sprintf(p_address, "%p", &pmax);
free(p_address);
}
int my_max(int a, int b) // 取兩個整型的最大值
{
if (a > b)
return a;
return b;
}
// 指針型函數(函數返回值可以是一個指針)
void pointer_demo7()
{
// 函數名之前加“*”號表明這是一個指針型函數,即返回值是一個指針。類型說明符表示了返回的指針值所指向的數據類型
char *day_name(int n);
// 結果:星期五
char *result = day_name(5);
}
char *day_name(int n)
{
static char *name[] =
{
"星期日",
"星期一",
"星期二",
"星期三",
"星期四",
"星期五",
"星期六"
};
return ((n < 0 || n > 6) ? "unknown" : name[n]);
}
// 指針數組
void pointer_demo8()
{
char *str1 = "webabcd";
char *str2 = "wanglei";
// 定義一個指針數組,即數組中的每一個元素都是一個指針
char *p[2] = { str1, str2 }; // str1 和 str2 都是指針
// 結果為 wanglei
char *x = p[1]; // p[1] - 指針數組中的第 2 個指針
}
// 指針的指針
void pointer_demo9()
{
// 指針數組其實就是指針的指針
char *name[] = { "webabcd", "wanglei" };
// 通過“**”定義一個指針的指針
char **p = name;
p++;
// 結果為 wanglei
char *myName = *p; // p 是指針的指針(二級指針),*p 是指針(一級指針)
}
// void 類型的指針
void pointer_demo10()
{
void *void_pointer();
// void 類型的指針 - 內存中的數據的類型要由用戶來指定
char *name = (char *)void_pointer();
}
void *void_pointer() // 返回 void 類型的指針
{
return "wanglei";
}
OK
[源碼下載]