📟作者主頁(yè):慢熱的陜西人
🌴專(zhuān)欄鏈接:C語(yǔ)言
📣歡迎各位大佬👍點(diǎn)贊🔥關(guān)注🚓收藏,🍉留言
1.字符指針:介紹了指針的一些進(jìn)階使用,函數(shù)指針,函數(shù)指針數(shù)組,轉(zhuǎn)移表,內(nèi)容難度上升。
📣在指針的類(lèi)型中我們知道有一種指針類(lèi)型為字符指針 char*
一般用法:
int main()
{char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
另一種使用方法:
📣代碼 const char* pstr = “hello bit.”; 這里只是將首字符的地址放到了pstr中
int main()
{const char* pstr = "hello bit.";//這里是把一個(gè)字符串放到pstr指針變量里了嗎?
printf("%s\n", pstr);
return 0;
}
所以有如下的面試題:
int main()
{char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
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é)果:
str1 and str2 are not same
str3 and str4 are same
2.指針數(shù)組:📣顧名思義存放指針的數(shù)組
例如:
int* arr1[10]; //整形指針的數(shù)組
char *arr2[4]; //一級(jí)字符指針的數(shù)組
char **arr3[5];//二級(jí)字符指針的數(shù)組
3.數(shù)組指針:數(shù)組指針的定義:指向數(shù)組的指針
下面代碼哪個(gè)是數(shù)組指針?
int *p1[10];
int (*p2)[10];
//p1, p2分別是什么?
4.&數(shù)組名VS數(shù)組名:
- p1則是int型的指針數(shù)組
- p2則是int型的數(shù)組指針
- 原理是[]的優(yōu)先級(jí)比*高所以不帶括號(hào)的情況下就會(huì)被識(shí)別成數(shù)組
- 帶上括號(hào)就會(huì)和解引用操作符結(jié)合所以就是數(shù)組指針了
結(jié)論:打印地址的話(huà)數(shù)值上是相同的,實(shí)際上是兩種不同的類(lèi)型所以在進(jìn)行加一時(shí)步長(zhǎng)不一樣;
(1)相同的點(diǎn):
打印地址的代碼:
#includeint main()
{int arr[10] = {0};
printf("%p\n", arr);
printf("%p\n", &arr);
return 0;
}
不同的點(diǎn):
📣原因是:
- &arr和arr數(shù)值上相同,但是意義卻不同 &arr表示的是數(shù)組的地址(對(duì)應(yīng)之前的兩種特殊情況)。
- arr表示的是數(shù)組首元素地址。
- 所以&arr + 1 跳過(guò)的是整個(gè)數(shù)組&arr + 1 和 &arr 的差值是40
#includeint main()
{int arr[10] = {0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);
return 0;
}
5.數(shù)組指針的使用:數(shù)組指針指向的是數(shù)組,那數(shù)組指針中存放的應(yīng)該是數(shù)組的地址
#includevoid print_arr1(int arr[3][5], int row, int col)
{ int i = 0;
for(i=0; ifor(j=0; j printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void print_arr2(int (*arr)[5], int row, int col)
{ int i = 0;
for(i=0; ifor(j=0; j printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{ int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};
print_arr1(arr, 3, 5);
//數(shù)組名arr,表示首元素的地址
//但是二維數(shù)組的首元素是二維數(shù)組的第一行
//所以這里傳遞的arr,其實(shí)相當(dāng)于第一行的地址,是一維數(shù)組的地址
//可以數(shù)組指針來(lái)接收
print_arr2(arr, 3, 5);
return 0;
}
幾個(gè)例子:
int arr[5]; //整型數(shù)組
int *parr1[10]; //指針數(shù)組
int (*parr2)[10]; //數(shù)組指針
int (*parr3[10])[5];//數(shù)組指針的數(shù)組
6.數(shù)組參數(shù)、指針參數(shù):
6.1一維數(shù)組傳參:#includevoid test(int arr[])//ok
{}
void test(int arr[10])//ok
{}
void test(int *arr)//ok
{}
void test2(int *arr[20])//ok
{}
void test2(int **arr)//ok
{}
int main()
{int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}
數(shù)組傳參:形參可以是數(shù)組,也可以是指針
6.2二維數(shù)組傳參:void test(int arr[3][5])//ok
{}
void test(int arr[][])//no
{}
void test(int arr[][5])//ok
{}
//總結(jié):二維數(shù)組傳參,函數(shù)形參的設(shè)計(jì)只能省略第一個(gè)[]的數(shù)字。
//因?yàn)閷?duì)一個(gè)二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素。
//這樣才方便運(yùn)算。
void test(int *arr)//no 是一級(jí)指針,無(wú)法接收數(shù)組的指針
{}
void test(int* arr[5])//no 是數(shù)組,無(wú)法接收指針
{}
void test(int (*arr)[5])//ok 數(shù)組指針可以接收
{}
void test(int **arr)//no 二級(jí)指針用于接收一級(jí)指針的地址與arr不匹配所以不行
{}
int main()
{int arr[3][5] = {0};
test(arr);//因?yàn)閍rr是二維數(shù)組,所以arr表示的是第一行的地址
}
6.3一級(jí)指針傳參:#includevoid print(int *p, int sz)
{int i = 0;
for(i=0; i printf("%d\n", *(p+i));
}
}
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一級(jí)指針p,傳給函數(shù)
print(p, sz);
return 0;
}
函數(shù)的形參是一級(jí)指針我們可以傳什么參數(shù):
void test1(int *p)
{}
//test1函數(shù)能接收什么參數(shù)?
int a = 0;
test(&a);//ok
int * ptr = &a;
test(ptr);//ok
int arr[10];
test(arr);//ok
void test2(char* p)
{}
//test2函數(shù)能接收什么參數(shù)?
//類(lèi)似上面
//char型變量的地址
//char型數(shù)組名或地址
6.4二級(jí)指針傳參:例如:
#includevoid test(int** ptr)
{printf("num = %d\n", **ptr);
}
int main()
{int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
當(dāng)函數(shù)的參數(shù)為二級(jí)指針的時(shí)候,可以接收什么參數(shù)?
void test(char **p)
{}
int main()
{char c = 'b';
char*pc = &c;
char**ppc = &pc;
char* arr[10];
test(&pc);
test(ppc);
test(arr);//Ok 因?yàn)橹羔様?shù)組的數(shù)組名就是首元素地址也就是二級(jí)指針
return 0;
}
7.函數(shù)指針:首先看一段代碼:
#includevoid test()
{printf("hehe\n");
}
int main()
{printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
7.1如何保存函數(shù)的地址:創(chuàng)建一個(gè)函數(shù)指針類(lèi)型:
形式 :返回類(lèi)型 (指針變量名)(函數(shù)參數(shù));*
兩段考基礎(chǔ)的代碼:
//代碼1
(*(void (*)())0)();
//代碼2
void (*signal(int , void(*)(int)))(int);
解釋?zhuān)?/p>
//代碼1
0 - int
( void (*)() )0 - 把0當(dāng)做一個(gè)函數(shù)的地址
( *( void (*)() )0 )();
//把0直接轉(zhuǎn)換成一個(gè)void (*)()的函數(shù)指針,然后去調(diào)用0地址處的函數(shù)
//代碼2
//上述代碼是一次函數(shù)聲明
// //聲明的函數(shù)叫:signal
// //signal函數(shù)的第一個(gè)參數(shù)是int類(lèi)型的
// //signal函數(shù)的第二個(gè)參數(shù)是一個(gè)函數(shù)指針類(lèi)型,該函數(shù)指針指向的函數(shù)參數(shù)是int,返回類(lèi)型是void
// //signal函數(shù)的返回類(lèi)型也是一個(gè)函數(shù)指針類(lèi)型,該函數(shù)指針指向的函數(shù)參數(shù)是int,返回類(lèi)型是void
對(duì)代碼2的化簡(jiǎn):
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
8.函數(shù)指針數(shù)組:8.1應(yīng)用:即存放函數(shù)指針的數(shù)組
如何定義:
返回類(lèi)型 ( * 變量名[x] )(形參); // 其中x表示的是數(shù)組的大小
例如 返回值為int 無(wú)形參的函數(shù)的函數(shù)指針數(shù)組:
int (*parr1[10])();
用途是:轉(zhuǎn)移表:
應(yīng)用示例(計(jì)算機(jī)):
#includeint add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a*b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = {0, add, sub, mul, div }; //轉(zhuǎn)移表
while (input)
{printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "請(qǐng)選擇:" );
scanf( "%d", &input);
if ((input<= 4 && input >= 1))
{printf( "輸入操作數(shù):" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "輸入有誤\n" );
printf( "ret = %d\n", ret);
}
return 0;
}
9.指向函數(shù)指針數(shù)組的指針:本質(zhì)上還是一個(gè)指針:
如何定義:
返回值類(lèi)型 (*(*變量名)[數(shù)組大小])(形參);
例如:
void test(const char* str)
{printf("%s\n", str);
}
int main()
{//函數(shù)指針pfun
void (*pfun)(const char*) = test;
//函數(shù)指針的數(shù)組pfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
//指向函數(shù)指針數(shù)組pfunArr的指針ppfunArr
void (*(*ppfunArr)[5])(const char*) = &pfunArr;
return 0;
}
10.回調(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)
示例(快排):
int swap_int(const void* a, const void* b)
{return (*(int*)a) - (*(int*)b);
}
qsort(arr, sizeof(int), sizeof(arr) / sizeof(int), swap_int);
到這本篇博客的內(nèi)容就到此結(jié)束了。
如果覺(jué)得本篇博客內(nèi)容對(duì)你有所幫助的話(huà),可以點(diǎn)贊,收藏,順便關(guān)注一下!
如果文章內(nèi)容有錯(cuò)誤,歡迎在評(píng)論區(qū)指正
你是否還在尋找穩(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)查看詳情吧
網(wǎng)頁(yè)名稱(chēng):[C語(yǔ)言]指針進(jìn)階-創(chuàng)新互聯(lián)
鏈接地址:http://www.rwnh.cn/article10/igido.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、微信公眾號(hào)、定制網(wǎng)站、微信小程序、動(dòng)態(tài)網(wǎng)站、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容