目錄
城北ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!1.字符指針
1.1字符指針定義
1.2 字符指針用法
2.指針數(shù)組
2.1 指針數(shù)組定義及使用
3.數(shù)組指針
3.1 數(shù)組指針定義
3.2 &數(shù)組名和數(shù)組名?
3.3 數(shù)組指針的基本用法
4. 數(shù)組參數(shù)、指針參數(shù)?
5. 函數(shù)指針?
5.1 函數(shù)指針定義既基本使用
5.2 有趣的代碼?
6. 函數(shù)指針數(shù)組?
6.1 函數(shù)指針數(shù)組定義
6.2 函數(shù)指針數(shù)組用法?
6.3 指向函數(shù)指針數(shù)組的指針?
7. 回調(diào)函數(shù)?
7.1 回調(diào)函數(shù)定義
7.2 回調(diào)函數(shù)使用?
在初學(xué)指針的時(shí)候你是否也常常分不清楚 ’指針數(shù)組‘ 和 ’數(shù)組指針‘ 呢?
結(jié)果是指針數(shù)組是數(shù)組,數(shù)組指針是指針,那快來(lái)學(xué)習(xí)一下這篇好文,更深刻的了解吧
前面初階指針中學(xué)習(xí)了一下指針的基本概念:
1.字符指針 1.1字符指針定義1. 指針就是個(gè)變量,用來(lái)存放地址,地址唯一標(biāo)識(shí)一塊內(nèi)存空間。
2. 指針的大小是固定的4/8個(gè)字節(jié)(32位平臺(tái)/64位平臺(tái))。
3. 指針是有類型,指針的類型決定了指針的+-整數(shù)的步長(zhǎng),指針解引用操作的時(shí)候的權(quán)限。
4. 指針的運(yùn)算
http://t.csdn.cn/wsHNl??????
在指針類型中我們知道一種指針類型為:char*
1.2 字符指針用法一般情況就是存放字符變量地址的指針
int main() { char a = 'w'; char* pc = &a; return 0; }
除去存放字符變量地址這個(gè)用法外還有其他的用法:
首先知道字符串常量:一對(duì)雙引號(hào)括起來(lái)的字符序列
int main() { const char* pc = "abcdef"; //字符串"abcdef"是常量,不可被修改所以加上const修飾 printf("%c\n", *pc); // 'a' printf("%s\n", pc); // "abcdef" return 0; }
這么一串代碼字符指針pc存放的是字符串"abcdef"的首元素地址,所以如果打印一個(gè)字符:解引用pc打印結(jié)果就是字符串的首元素‘a(chǎn)’,知道了首元素既可通過(guò)字符指針pc打印字符串
字符指針經(jīng)典面試題:題源《劍指offer》
2.指針數(shù)組 2.1 指針數(shù)組定義及使用int main() { char str1[] = "hello world."; char str2[] = "hello world."; const char* str3 = "hello world."; const char* str4 = "hello world."; if (str1 == str2) printf("str1 and str2 are same\n"); else printf("str1 and str2 are not same\n"); if (str3 == str4) printf("str3 and str4 are same\n"); else printf("str3 and str4 are not same\n"); return 0; }
輸出結(jié)果:
str3和str4指向的是一個(gè)同一個(gè)常量字符串。C/C++會(huì)把常量字符串存儲(chǔ)到單獨(dú)的一個(gè)內(nèi)存區(qū)域,當(dāng)幾個(gè)指針。指向同一個(gè)字符串的時(shí)候,他們實(shí)際會(huì)指向同一塊內(nèi)存。但是用相同的常量字符串去初始化不同的數(shù)組的時(shí)候就會(huì)開辟出不同的內(nèi)存塊。所以str1和str2不同,str3和str4不同。
指針數(shù)組是一個(gè)存放指針的數(shù)組。
3.數(shù)組指針 3.1 數(shù)組指針定義int main() { char* pch[5]; // 字符指針數(shù)組 int* parr[5];// 整形指針數(shù)組 char** ppch[5]; //二級(jí)字符指針數(shù)組 return 0; }
指針數(shù)組用法:將三個(gè)一維數(shù)組通過(guò)指針變成二維數(shù)組并輸出打印
int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 2,3,4,5,6 }; int arr3[] = { 3,4,5,6,7 }; int* arr[] = { arr1,arr2,arr3 };//定義一個(gè)指針數(shù)組存放arr1、2、3,的首元素地址 int i = 0; for (i = 0; i< 3; i++) { int j = 0; for (j = 0; j< 5; j++) { // *(arr[i]+j)=arr[i][j] 通過(guò)i分別找出arr1、2、3并通過(guò)j找出所對(duì)于的數(shù) printf("%d ", arr[i][j]); } printf("\n"); } return 0; }
數(shù)組指針是指向數(shù)組的指針?
3.2 &數(shù)組名和數(shù)組名?數(shù)組指針表示形式:
int main() { int arr[10] = { 0 }; int(*p)[10] = &arr;//取出的arr數(shù)組的地址 // 取出arr的地址,元素個(gè)數(shù)10,每個(gè)元素類型為int return 0; }
解釋:p先和*結(jié)合,說(shuō)明p是一個(gè)指針變量,然后指著指向的是一個(gè)大小為10個(gè)整型的數(shù)組。所以p是一個(gè)指針,指向一個(gè)數(shù)組,叫數(shù)組指針。
這里要注意:[]的優(yōu)先級(jí)要高于*號(hào)的,所以必須加上()來(lái)保證p先和*結(jié)合。區(qū)分:指針數(shù)組 和 數(shù)組指針
3.3 數(shù)組指針的基本用法&數(shù)組名:取出的是整個(gè)數(shù)組的地址
數(shù)組名:表示的是首元素的地址?
http://t.csdn.cn/Pm7B9
本例中 &arr 的類型是: int(*)[10] ,是一種數(shù)組指針類型
數(shù)組的地址+1,跳過(guò)整個(gè)數(shù)組的大小,所以 &arr+1 相對(duì)于 &arr 的差值是40
4. 數(shù)組參數(shù)、指針參數(shù)?例:將一個(gè)整形二維數(shù)組中的元素輸出打印
void print1(int arr[3][5],int x,int y) { int i = 0; int j = 0; for (i = 0; i< x; i++) { for (j = 0; j< y; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } void print2(int(*pa)[5], int x, int y) { //int(*pa)[5] 表示指向一個(gè)有5個(gè)int類型元素的數(shù)組,既arr首地址 int i = 0; for (i = 0; i< x; i++) { int j = 0; for (j = 0; j< y; j++) { printf("%d ", (*(pa)+i)[j]);//*(pa)+i==pa[i] } printf("\n"); } } int main() { int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} }; print1(arr,3,5);//arr首元素地址是{1,2,3,4,5} print2(arr,3,5); return 0; }
數(shù)組名arr,表示首元素的地址
但是二維數(shù)組的首元素是二維數(shù)組的第一行
所以這里傳遞的arr,其實(shí)相當(dāng)于第一行的地址,是一維數(shù)組的地址
可以數(shù)組指針來(lái)接收
5. 函數(shù)指針? 5.1 函數(shù)指針定義既基本使用一維數(shù)組傳參
void test1(int arr [])//同樣用整形數(shù)組接收 {} void test2(int* str) //用一個(gè)同類型指針接收 {} void test3(int arr[5])//同類型同大小接收(數(shù)組大小可忽略) {} void test1_1(int* parr[]) //相同整形指針數(shù)組接收 {} void test2_2(int** str) //二級(jí)指針接收 {} int main() { int arr[5] = { 0 };//一維數(shù)組 int* parr[10] = { 0 };//指針數(shù)組 test1(arr); test2(arr); test3(arr); test1_1(parr); test2_2(parr); return 0; }
二維數(shù)組傳參
void test1(int arr[3][5])//相同類型二維數(shù)組 {} void test2(int arr[][5])//二維數(shù)組傳參,函數(shù)形參的設(shè)計(jì)只能省略第一個(gè)[]的數(shù)字。 {} void test3(int(*pa)[5])//用數(shù)組指針接收 {} int main() { int arr[3][5] = { 0 }; test1(arr); test2(arr); test3(arr); return 0; }
一級(jí)指針傳參
void test(int* p)//同類型指針接收 { int i = 0; for (i = 0; i< 5; i++) { printf("%d ", *(p + i)); } } int main() { int arr[5] = { 1,2,3,4,5 }; int* pa = arr; test(pa); return 0; }
二級(jí)指針傳參
void test(int** ppa)//相同類型二級(jí)指針接收 {} int main() { int a =5; int* pa = &a; int** ppa = &pa; test(ppa); return 0; }
5.2 有趣的代碼?函數(shù)指針:存放函數(shù)地址的指針變量
兩個(gè)輸出的都是test函數(shù)的地址
void test() {} int main() { test(); void (*p)() = &test; //函數(shù)指針,存放函數(shù)地址 return 0; }
pfun1可以存放。pfun1先和*結(jié)合,說(shuō)明pfun1是指針,指針指向的是一個(gè)函數(shù),指向的函數(shù)無(wú)參數(shù),返回值類型為void。
函數(shù)指針基本使用:
int add(int x, int y) { return x + y; } int main() { int a = 0; int b = 0; int(*pa)(int, int) = &add;//存放add函數(shù)地址的函數(shù)指針 printf("%d\n", (*pa)(10, 20));//直接通過(guò)解引用pa操作函數(shù)add return 0; }
下面是兩個(gè)有趣的代碼,簡(jiǎn)述大概意思。來(lái)源:《C陷阱與缺陷》?
6. 函數(shù)指針數(shù)組? 6.1 函數(shù)指針數(shù)組定義代碼1:
首先看到這么一個(gè)復(fù)雜的代碼,我們先將其括號(hào)配對(duì),使我們能更明確的看出所代表的含義
簡(jiǎn)述:將整形0強(qiáng)制 類型轉(zhuǎn)換成一個(gè)參數(shù)為無(wú)返回類型為void的函數(shù)指針地址,既0地址
后調(diào)用地址為0的函數(shù)。
代碼2:
簡(jiǎn)述:
signal是一個(gè)函數(shù)聲明
signal函數(shù)的參數(shù)有2個(gè),第一個(gè)是int。第二個(gè)是函數(shù)指針,該函數(shù)指針指向的函數(shù)的參數(shù)是int,返回類型是void
signal函數(shù)的返回類型也是一個(gè)函數(shù)指針:該函數(shù)指針指向的函數(shù)的參數(shù)是int,返回類型是void
函數(shù)指針數(shù)組:存放函數(shù)指針的數(shù)組
6.2 函數(shù)指針數(shù)組用法?int add(int x, int y) { return x + y; } int sub(int x, int y) { return x - y; } int mul(int x, int y) { return x * y; } int div(int x, int y) { return x / y; } int main() { int (*pf[4])(int, int) = { add,sub,mul,div }; return 0; }
pf?先和 [] 結(jié)合,說(shuō)明 pf是數(shù)組,數(shù)組內(nèi)容是:int (*) (int ,int );
函數(shù)指針數(shù)組用途:轉(zhuǎn)移表?
以計(jì)算器為例,函數(shù)指針數(shù)組用法:
6.3 指向函數(shù)指針數(shù)組的指針?void mune() { printf("**********************\n"); printf("** 1.add 2.sub **\n"); printf("** 3.mul 4.div **\n"); printf("******* 0.exit *******\n"); } int add(int x, int y) { return x + y; } int sub(int x, int y) { return x - y; } int mul(int x, int y) { return x * y; } int div(int x, int y) { return x / y; } int main() { int n = 0; int x = 0; int y = 0; int(*pf[5])(int, int) = { 0,add,sub,mul,div };//定義5個(gè)下標(biāo),讓數(shù)組下標(biāo)和菜單選項(xiàng)對(duì)應(yīng) //函數(shù)指針數(shù)組:轉(zhuǎn)移表 do { mune(); printf("請(qǐng)選擇:>"); scanf("%d", &n); if (n >= 1 && n<= 4) { printf("請(qǐng)輸入兩位操作數(shù):>"); scanf("%d %d", &x, &y); printf("%d\n", pf[n](x, y)); } else if (n == 0) { printf("退出\n"); } else { printf("輸入錯(cuò)誤\n"); } } while (n); return 0; }
存放函數(shù)指針數(shù)組地址的指針變量
7. 回調(diào)函數(shù)? 7.1 回調(diào)函數(shù)定義void test(const char* str) { printf("%s\n", str); } int main() { //函數(shù)指針 void(*p)(const char*) = &test; //函數(shù)指針的數(shù)組 void(*parr[5])(const char*); //指向函數(shù)指針數(shù)組的指針 void (*(*pfarr)[5])(const char*) = &parr; return 0; }
7.2 回調(diào)函數(shù)使用?回調(diào)函數(shù)就是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
void print(char* str) { printf("%s\n", str); } void test(void) { print("hello world!"); } int main() { test(); return 0; }
設(shè)定一個(gè)通用冒泡排序函數(shù)可以排序任意類型:參考函數(shù)qsort()?
qsort ()函數(shù)詳解:? ? ? ? ? http://t.csdn.cn/xkfQ8http://t.csdn.cn/xkfQ8代碼實(shí)現(xiàn):
//置換
void permute(char* buf1, char* buf2, int width)//類型不同,一個(gè)字節(jié)一個(gè)字節(jié)進(jìn)行置換
{
int i = 0;
for (i = 0; i< width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
// base:任意類型數(shù)組地址,sz:數(shù)組長(zhǎng)度,width:數(shù)組寬度(數(shù)組類型),比較參數(shù)函數(shù)
void bubble_sort(void* base,int sz,int width,int(*cmp)(void* elem1,void*elem2))
{
//冒泡排序
int i = 0;
//趟數(shù)
for (i = 0; i< sz-1; i++)
{
//每躺比較的對(duì)數(shù)
int j = 0;
for (j = 0; j< sz - i - 1; j++)
{
//比較兩個(gè)參數(shù)
if (cmp((char*)base+width*j, (char*)base+width*(j+1)) >0)//比較該元素和后一個(gè)元素大小
//傳參任意類型,可通過(guò)一個(gè)字節(jié)+寬度就等于該數(shù)據(jù)類型,一個(gè)char類型加上一個(gè)int類型就等于跳過(guò)一個(gè)int類型
{
//置換
permute((char*)base + width * j, (char*)base + width * (j + 1),width);
}
}
}
}
int cmp_int(void* elem1, void* elem2)
{
return *(int*)elem1 - *(int*)elem2;
}
void test(void)
{
int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
for (i = 0; i< sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
test();
return 0;
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱:C語(yǔ)言—指針進(jìn)階(詳解篇)-創(chuàng)新互聯(lián)
鏈接URL:http://www.rwnh.cn/article38/ccjipp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、建站公司、App開發(fā)、標(biāo)簽優(yōu)化、網(wǎng)站改版、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容