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