目錄
指針:
學(xué)習(xí)目標(biāo):
指針可以理解為:
字符指針:
? ? ? ? 定義:字符指針 char*。
字符指針的使用:
練習(xí):
指針數(shù)組:
? ? ? ? 概念:指針數(shù)組是一個(gè)存放指針的數(shù)組。
實(shí)現(xiàn)模擬二維數(shù)組:
?數(shù)組指針:
? ? ? ? 概念:能夠指向數(shù)組的指針。(可以理解為先與指針結(jié)合再與數(shù)組結(jié)合)
值得注意的是:
數(shù)組指針一般用于二維數(shù)組:數(shù)組的傳參:?
一維數(shù)組傳參:
二維數(shù)組的傳參:?
總結(jié):二維數(shù)組傳參,函數(shù)形參的設(shè)計(jì)只能省略第一個(gè)[ ]的數(shù)字因?yàn)閷?duì)一個(gè)二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素這樣才方便運(yùn)算。
指針的傳參:
一級(jí)指針傳參:
?二級(jí)指針的傳參:
函數(shù)指針:
? ? ? ? 概念:指向函數(shù)的指針。
閱讀兩段有趣的代碼:
類(lèi)型重定義:typedef?
函數(shù)指針數(shù)組:
????????定義:int (*parr1[10])();? 每個(gè)元素都是函數(shù)指針類(lèi)型。
????????用途:轉(zhuǎn)移表。
函數(shù)指針數(shù)組的使用:
指向函數(shù)指針數(shù)組的指針:
定義:
????????指向函數(shù)指針數(shù)組的指針是一個(gè) 指針 指針指向一個(gè) 數(shù)組 ,數(shù)組的元素都是 函數(shù)指針 ; (一般不直接寫(xiě),通過(guò)函數(shù)指針一步一步變化得到,可以減少失誤操作)
回調(diào)函數(shù):
概念:
使用回調(diào)函數(shù)模擬實(shí)現(xiàn)qsort()函數(shù):
qsort()運(yùn)用:
排序int類(lèi)型:
排序結(jié)構(gòu)體類(lèi)型:
學(xué)習(xí)目標(biāo):
1. 字符指針2. 指針數(shù)組3. 數(shù)組指針4. 數(shù)組傳參和指針傳參5. 函數(shù)指針6. 函數(shù)指針數(shù)組7. 指向函數(shù)指針數(shù)組的指針8. 回調(diào)函數(shù)
指針:
指針可以理解為:
字符指針:
? ? ? ? 定義:字符指針 char*。
字符指針的使用:
//使用1int main (){char ch = 'w' ;char * pc = & ch ;* pc = 'w' ;return 0 ;}//使用2int main (){const char* pstr = "hello bit." ;//把一個(gè)常量字符串的 首字符 h 的地址 存放到指針變量 pstr 中printf ( "%s\n" , pstr );return 0 ;}
練習(xí):
指針數(shù)組:
? ? ? ? 概念:指針數(shù)組是一個(gè)存放指針的數(shù)組。
int* arr1 [ 10 ];? ? // 整形指針的數(shù)組char * arr2 [ 4 ];?? // 一級(jí)字符指針的數(shù)組char ** arr3 [ 5 ]; // 二級(jí)字符指針的數(shù)組
實(shí)現(xiàn)模擬二維數(shù)組:
?數(shù)組指針:
? ? ? ? 概念:能夠指向數(shù)組的指針。(可以理解為先與指針結(jié)合再與數(shù)組結(jié)合)
??????int (*p)[10];// 解釋?zhuān)?/span> p先和*結(jié)合,說(shuō)明p是一個(gè)指針變量 ,然后指著指向的是一個(gè)大小為 10 個(gè)整型的數(shù)組。所以 p 是一個(gè)指針,指 向一個(gè)數(shù)組,叫數(shù)組指針。// 這里要注意: [ ] 的優(yōu)先級(jí)要高于 * 號(hào)的,所以必須加上()來(lái)保證 p 先和 * 結(jié)合。
值得注意的是:
數(shù)組名的理解:數(shù)組名是數(shù)組首元素的地址
有2個(gè)例外:
1. sizeof(數(shù)組名),這里的數(shù)組名不是數(shù)組首元素的地址,數(shù)組名表示整個(gè)數(shù)組,sizeof(數(shù)組名)計(jì)算的是整個(gè)數(shù)組的大小,單位是字節(jié)
2. &數(shù)組名,這里的數(shù)組名表示整個(gè)數(shù)組, &數(shù)組名取出的是整個(gè)數(shù)組的地址
?除此之外,所有的地方的數(shù)組名都是數(shù)組首元素的地址
數(shù)組指針一般用于二維數(shù)組:
數(shù)組的傳參:?
????????二維數(shù)組的每一行可以理解為二維數(shù)組的一個(gè)元素,每一行又是一個(gè)一維數(shù)組,所以二維數(shù)組其實(shí)是一維數(shù)組的數(shù)組。
????????二維數(shù)組的數(shù)組名,也是數(shù)組名,數(shù)組名就是數(shù)組首元素的地址。
arr----首元素的地址;
arr----第一行的地址;
arr----一維數(shù)組的地址即數(shù)組的地址。
一維數(shù)組傳參:
二維數(shù)組的傳參:?
?
總結(jié):二維數(shù)組傳參,函數(shù)形參的設(shè)計(jì)只能省略第一個(gè)[ ]的數(shù)字因?yàn)閷?duì)一個(gè)二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素這樣才方便運(yùn)算。
指針的傳參:
一級(jí)指針傳參:
?二級(jí)指針的傳參:
函數(shù)指針:
? ? ? ? 概念:指向函數(shù)的指針。
?? ?int (*pf)(int, int) = &Add;
????//pf是函數(shù)指針變量
?? ?//int (*)(int, int) 是函數(shù)指針類(lèi)型
void test(char* pc, int arr[10])
{
}
int main()
{
void (*pf)(char *, int [10]) = test;
return 0;
}
由上圖可知:??
????????函數(shù)名是函數(shù)的地址;
????????&函數(shù)名也是函數(shù)的地址。
閱讀兩段有趣的代碼:
//代碼1( * ( void ( * )()) 0 )();解析:調(diào)用0地址處的函數(shù)
?????????? ?1. 將0強(qiáng)制類(lèi)型轉(zhuǎn)換為void (*)() ?類(lèi)型的函數(shù)指針
?????????? ?2. 調(diào)用0地址處的這個(gè)函數(shù)//代碼2void ( * signal ( int , void ( * )( int )))( int );解析:? ? 1.signal 是一個(gè)函數(shù)聲明
? ? 2.signal 函數(shù)有2個(gè)參數(shù),第一個(gè)參數(shù)的類(lèi)型是int,第二個(gè)參數(shù)的類(lèi)型是 void(*)(int) 函數(shù)指針類(lèi)型
? ? 3.該函數(shù)指針指向的函數(shù)有一個(gè)int類(lèi)型的參數(shù),返回類(lèi)型是void
? ? 4.signal 函數(shù)的返回類(lèi)型也是void(*)(int) 函數(shù)指針類(lèi)型,該函數(shù)指針指向的函數(shù)有一個(gè)int類(lèi)型的參數(shù),返回類(lèi)型是void
類(lèi)型重定義:typedef?
//類(lèi)型重定義1
typedef unsigned int uint;
typedef int* ptr_t;
int main()
{
uint u1;
ptr_t p1;
int* p2;
return 0;
}
//類(lèi)型重定義2
typedef int(*parr_t)[10];
typedef int (*pf_t)(int, int) ;
int main()
{
typedef void(*pf_t)(int);
pf_t signal(int, pf_t);
//上方兩句將下方的語(yǔ)句簡(jiǎn)化,效果相同
void (* signal(int, void(*)(int) ) )(int);
return 0;
}
函數(shù)指針數(shù)組:
????????定義:int (*parr1[10])();? 每個(gè)元素都是函數(shù)指針類(lèi)型。
????????用途:轉(zhuǎn)移表。
函數(shù)指針數(shù)組的使用:
#include <stdio.h>
#include <string.h>
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;
}
void menu()
{
printf("***************************\n");
printf("***** 1.add 2.sub ******\n");
printf("***** 3.mul 4.div ******\n");
printf("***** 0.exit ******\n");
printf("***************************\n");
}
//實(shí)現(xiàn)int類(lèi)型的加減乘除
int main()
{
int input = 0;
int x = 0;
int y = 0;
int ret = 0;
//函數(shù)指針數(shù)組的使用 - 轉(zhuǎn)移表
int (* pfArr[5])(int, int) = {NULL, Add, Sub, Mul, Div};
0 1 2 3 4
do
{
menu();
printf("請(qǐng)選擇:>");
scanf("%d", &input);
if (input >= 1 && input <= 4)
{
printf("請(qǐng)輸入兩個(gè)操作數(shù):");
scanf("%d %d", &x, &y);
ret = pfArr[input](x, y);
printf("ret = %d\n", ret);
}
else if(input == 0)
{
printf("退出計(jì)算器\n");
}
else
{
printf("選擇錯(cuò)誤,重新選擇\n");
}
} while (input);
return 0;
}
指向函數(shù)指針數(shù)組的指針:
定義:
????????指向函數(shù)指針數(shù)組的指針是一個(gè) 指針 指針指向一個(gè) 數(shù)組 ,數(shù)組的元素都是 函數(shù)指針 ; (一般不直接寫(xiě),通過(guò)函數(shù)指針一步一步變化得到,可以減少失誤操作)
void (*pf)(const char*) = test;? ?//pf是函數(shù)指針變量
void (*pfArr[10])(const char*);? //pfArr是存放函數(shù)指針的數(shù)組
void (* (*p) [10])(const char*) = &pfArr;//p指向函數(shù)指針數(shù)組的指針
回調(diào)函數(shù):
概念:
//回調(diào)函數(shù)的使用
void Calc(int (*pf)(int, int))
{
?? ?int x = 0;
?? ?int y = 0;
?? ?int ret = 0;
?? ?printf("請(qǐng)輸入兩個(gè)操作數(shù):");
?? ?scanf("%d %d", &x, &y);
?? ?ret = pf(x, y);
?? ?printf("ret = %d\n", ret);
}
使用回調(diào)函數(shù)模擬實(shí)現(xiàn)qsort()函數(shù):
base:指向要排序的數(shù)組的第一個(gè)對(duì)象的指針,轉(zhuǎn)換為 .void*。
num:數(shù)組中由指向的元素個(gè)數(shù)。是無(wú)符號(hào)整型。
size:數(shù)組中每個(gè)元素的大?。ㄒ宰止?jié)為單位),是無(wú)符號(hào)整型。
compar:指向比較兩個(gè)元素的函數(shù)的指針,重復(fù)調(diào)用此函數(shù)以比較兩個(gè)元素。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-668422.html
qsort()運(yùn)用:
#include <stdio.h>
//qosrt函數(shù)的使用者得實(shí)現(xiàn)一個(gè)比較函數(shù)
int int_cmp(const void * p1, const void * p2)
{
return (*( int *)p1 - *(int *) p2);
}
int main()
{
int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
int i = 0;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
{
printf( "%d ", arr[i]);
}
printf("\n");
return 0;
}
排序int類(lèi)型:
#include <stdio.h>
//比較int類(lèi)型的比較函數(shù)
int my_compare(const void* q1, const void* q2)
{
return (*(int*)q1 - *(int*)q2);
}
//交換每一個(gè)字節(jié)的元素
void Swap(char* b1, char* b2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *b1;
*b1 = *b2;
*b2 = tmp;
b1++;
b2++;
}
}
//模擬實(shí)現(xiàn)自己的qsort()函數(shù)
void my_qsort(void* base, int num, int size, int (*my_compare)(const void* q1, const void* q2))
{
int i = 0;
int j = 0;
for (i = 0; i < num - 1; i++)
{
for (j = 0; j < num - 1 - i; j++)
{
//從小到大排序
if (my_compare((char*)base+j*size,(char*)base+(j+1)*size) > 0)
{
Swap((char*)base + j*size, (char*)base + (j + 1)*size, size);
}
}
}
}
int main()
{
int arr[10] = { 2,4,6,7,8,3,1,0,9,5 };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), my_compare);
return 0;
}
排序結(jié)構(gòu)體類(lèi)型:
#include <string.h>
//創(chuàng)建學(xué)生結(jié)構(gòu)體
struct Stu
{
char name[20];
int age;
};
//比較int類(lèi)型的比較函數(shù)
int my_compare_age(const void* q1, const void* q2)
{
return ((struct Stu*)q1)->age - ((struct Stu*)q2)->age;
}
//比較int類(lèi)型的比較函數(shù)
int my_compare_name(const void* q1, const void* q2)
{
return strcmp( ( (struct Stu*)q1 )->name ,( (struct Stu*)q2 )->name);
}
//交換每一個(gè)字節(jié)的元素
void Swap(char* b1, char* b2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *b1;
*b1 = *b2;
*b2 = tmp;
b1++;
b2++;
}
}
//模擬實(shí)現(xiàn)自己的qsort()函數(shù)
void my_qsort(void* base, int num, int size, int (*my_compare)(const void* q1, const void* q2))
{
int i = 0;
int j = 0;
//趟數(shù)
for (i = 0; i < num - 1; i++)
{
//一趟內(nèi)部比較的對(duì)數(shù)
for (j = 0; j < num - 1 - i; j++)
{
//從小到大排序
if (my_compare((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
//交換
Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
int main()
{
struct Stu arr[] = { {"zhangsan",34},{"lisi",27},{"wanwu",20} };
int sz = sizeof(arr) / sizeof(arr[0]);
my_qsort(arr, sz, sizeof(arr[0]), my_compare_age);
my_qsort(arr, sz, sizeof(arr[0]), my_compare_name);
return 0;
}
以上就是個(gè)人學(xué)習(xí)指針的個(gè)人見(jiàn)解和學(xué)習(xí)的解析,歡迎各位大佬在評(píng)論區(qū)探討!
感謝大佬們的一鍵三連!?感謝大佬們的一鍵三連!?感謝大佬們的一鍵三連!
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-668422.html
到了這里,關(guān)于C語(yǔ)言:指針(超深度講解)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!