目錄
站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到東豐網(wǎng)站設(shè)計(jì)與東豐網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)頁(yè)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋東豐地區(qū)。1.什么是指針?
1.1概念
1.2指針的大小
??1.3指針類(lèi)型的作用
2.野指針?
2.1野指針產(chǎn)生的原因
2.2 如何規(guī)避野指針
3.指針運(yùn)算?
3.1指針+-整數(shù)
3.2指針-指針
3.3 指針的關(guān)系運(yùn)算?
4. 二級(jí)指針
5. 數(shù)組名
*6.指針數(shù)組和數(shù)組指針?
6.1指針數(shù)組
*6.2數(shù)組指針?
6.3舉例區(qū)別含義
7.數(shù)組參數(shù)和指針參數(shù)
7.1數(shù)組參數(shù)
7.2指針傳參
8.函數(shù)指針?
9.函數(shù)指針數(shù)組
9.1指向函數(shù)指針數(shù)組的指針
*10.回調(diào)函數(shù)
1.什么是指針? 1.1概念1.2指針的大小簡(jiǎn)單的來(lái)說(shuō),指針就是地址。我們口頭上說(shuō)的指針其實(shí)指的是指針變量。指針變量就是一個(gè)存放地址的變量。
1.3指針類(lèi)型的作用指針在32位機(jī)器下是4個(gè)字節(jié),在64位機(jī)器下是8個(gè)字節(jié)。注:(指針的大小與類(lèi)型無(wú)關(guān))
上面涉及到指針的大小與指針類(lèi)型無(wú)關(guān),那么指針類(lèi)型的作用是什么呢?
指針解引用訪問(wèn),使用的訪問(wèn)權(quán)限是多少? ? 話不多說(shuō),上圖!
2.野指針?當(dāng)一個(gè)int* 的指針+1,跳過(guò)4個(gè)字節(jié);當(dāng)一個(gè)char* 的指針+1,跳過(guò)1個(gè)字節(jié)。
同理,對(duì)于(指針+-整數(shù))類(lèi)的題也是如上的原理。
2.1野指針產(chǎn)生的原因野指針顧名思義,指針指向的位置不可知,就像沒(méi)有主人的流浪狗。
指針未被初始化
指針越界訪問(wèn)
指針指向的空間釋放
對(duì)于前兩點(diǎn)比較好理解,下面對(duì)第三點(diǎn)進(jìn)行解釋?zhuān)?/p>
int* test( )
{
int a = 5;
return &a;
}
int main()
{
int* p = test();
*p = 10;
return 0;
}
2.2 如何規(guī)避野指針變量a的地址只在test()函數(shù)內(nèi)有效,當(dāng)把a(bǔ)的地址傳給指針p時(shí),因?yàn)槌隽藅est函數(shù),變量a的空間地址釋放,導(dǎo)致p變成了野指針。
3.指針運(yùn)算? 3.1指針+-整數(shù)
- 小心越界
- 及時(shí)把指針賦成空指針
- 避免返回局部變量的地址
- 使用指針前檢查有效性
3.2指針-指針此部分內(nèi)容跟指針類(lèi)型那部分一致
指針-指針的絕對(duì)值指的是兩個(gè)指針之間元素的個(gè)數(shù)。
前提:兩個(gè)指針必須指向同一空間
例如:&arr[9]-&arr[0]?
下面舉個(gè)例子實(shí)現(xiàn)my_strlen函數(shù)
int my_strlen(char str[])
{
char* p = str;
int count = 0;
while (*p != '\0')
{
p++;
count++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
printf("%d\n",my_strlen(arr));
return 0;
}
3.3 指針的關(guān)系運(yùn)算?4. 二級(jí)指針此部分內(nèi)容很簡(jiǎn)單,指針與指針之間比較大小就是指針的關(guān)系運(yùn)算。
例如:定義int* p1,數(shù)組int arr[5],p1>&arr[5]。
但是要遵循一個(gè)標(biāo)準(zhǔn):允許指針指向數(shù)組元素和指針指向數(shù)組最后一個(gè)元素后面的位置進(jìn)行比較,不允許指針指向數(shù)組元素與指針指向數(shù)組第一個(gè)位置的前面進(jìn)行比較。
5. 數(shù)組名二級(jí)指針就是存放指針地址的指針變量。就像有三個(gè)抽屜第一個(gè)抽屜的鑰匙放在第二個(gè)抽屜,第二個(gè)抽屜的鑰匙放在第三個(gè)抽屜。
例如:int a=10;int* p1=&a;int** p2=&p1;
對(duì)int* * 做解釋?zhuān)旱谝粋€(gè)*號(hào)代表指針指向的類(lèi)型是int*的,第二個(gè)*代表這個(gè)是指針。
*6.指針數(shù)組和數(shù)組指針? 6.1指針數(shù)組數(shù)組名大家都很熟悉,但要區(qū)分以下幾種情況:
- sizeof(arr):表示的是整個(gè)數(shù)組的大小。
- &arr: 表示整個(gè)數(shù)組,取出的是整個(gè)數(shù)組的大小。
其他情況數(shù)組名都表示數(shù)組首元素地址。
定義:存放指針的數(shù)組(int* arr[])。我們知道有整型類(lèi)型的數(shù)組int arr[],還有字符類(lèi)型的數(shù)組char arr[],指針數(shù)組就是指針類(lèi)型的數(shù)組。
以下舉個(gè)例:
int main()
{
int a = 0;
int b = 1;
int* p1 = &a;
int* p2 = &b;
int* arr[] = { p1,p2 };//指針數(shù)組
int* arr[] = { &a,&b };//指針數(shù)組
return 0;
}
*6.2數(shù)組指針?
- 定義: 指向數(shù)組的指針int (*)[]。
- 應(yīng)用:遍歷整個(gè)二維數(shù)組
void my_print(int(*p)[5], int x, int y)
{
int i = 0;
for (i = 0; i< x; i++)
{
int j = 0;
for (j = 0; j< y; j++)
{
printf("%d ", *(*(p + i) + j));
//printf("%d ", p[i][j]);相似的寫(xiě)法
}
printf("\n");
}
}
int main()
{
int arr1[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
my_print(arr1, 3, 5);
return 0;
}
6.3舉例區(qū)別含義7.數(shù)組參數(shù)和指針參數(shù) 7.1數(shù)組參數(shù)
- int arr[5]? ? ? ? ? ? ? ?//名為arr的數(shù)組,數(shù)組里有5個(gè)元素,每個(gè)元素是int
- int* p1[5]? ? ? ? ? ? ? //指針數(shù)組,數(shù)組里有5個(gè)元素,每個(gè)元素是int*
- int (*p2)[5]? ? ? ? ? ? //數(shù)組指針,一個(gè)指向數(shù)組(里面有五個(gè)元素,每個(gè)元素是int)的指? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 針
- int (*p3[5])[5]? ? ? ? //p3[5]是一個(gè)有5個(gè)元素的數(shù)組,數(shù)組里每個(gè)元素是int(*)[5]
7.2指針傳參
- 一維數(shù)組傳參:?int arr[10](形參部分?jǐn)?shù)組大小可以不寫(xiě))、int* arr
- 二維數(shù)組傳參: int arr[3][5]、int arr[][5](行可以省略,列不能)、int (*arr)[5]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不能直接傳數(shù)組名,二維數(shù)組的首地址是第一行元素的首地址
8.函數(shù)指針?
- 一級(jí)指針傳參:int* p
- 二級(jí)指針傳參:int** p
- 定義:指向函數(shù)的指針int (*pf) (int,int),pf函數(shù)返回的類(lèi)型是int (*)(int,int)
- 對(duì)于函數(shù)來(lái)說(shuō)如:Add和&Add,意義和值都一樣。這一定要區(qū)別于數(shù)組。
- 特別的,當(dāng)要調(diào)用函數(shù)時(shí),定義一個(gè)pf的函數(shù)指針指向函數(shù)。那么int ret=(*pf)(2,3)和int ret=pf (2,3)等價(jià)。
9.函數(shù)指針數(shù)組**對(duì)下面代碼的理解:
(*(void(*)())0)()? ? ? ? ? ? ? ? ? ? ? ? ? ? //? ?將0處強(qiáng)制類(lèi)型轉(zhuǎn)換為函數(shù)指針類(lèi)型,再對(duì)0地址? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?進(jìn)行調(diào)用
void(*signal(int,void(*)(int)))(int)? ? ? ??//這是函數(shù)的聲明,singal是一個(gè)函數(shù),傳進(jìn)去兩個(gè)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數(shù)的類(lèi)型是int和void(*)(int),signal函數(shù)的返回值? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 類(lèi)型是void(*)(int)。
- 定義:存放函數(shù)指針類(lèi)型元素的數(shù)組
- 應(yīng)用:實(shí)現(xiàn)計(jì)算器
#includeint 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");
}
int main()
{
menu();
int input = 0;
printf("請(qǐng)選擇:");
scanf("%d",&input);
int ret = 0;
//轉(zhuǎn)移表
int(*pfarr[])(int, int) = { 0,Add,Sub,Mul,Div };
do
{
if (input == 0)
{
printf("退出\n");
break;
}
else if (input >= 1 && input<= 4)
{
int x = 0;
int y = 0;
printf("請(qǐng)輸入兩個(gè)操作數(shù):");
scanf("%d%d",&x,&y);
ret = pfarr[input](x,y);
printf("結(jié)果是%d\n",ret);
break;
}
else
{
printf("選擇錯(cuò)誤!");
}
} while (input);
return 0;
}
9.1指向函數(shù)指針數(shù)組的指針*10.回調(diào)函數(shù)1.定義:int (*(*parr)[4])(int? int)=&parr
- qsort()函數(shù):?是一個(gè)庫(kù)函數(shù),基于快速排序算法實(shí)現(xiàn)的一個(gè)排序的函數(shù)。優(yōu)點(diǎn)是,任意類(lèi)型的數(shù)據(jù)都能排序。
- qsort()函數(shù)的形參定義:
void qsort(void* base(起始地址),size_t num(元素個(gè)數(shù)),size_t width(一個(gè)元素的字節(jié)長(zhǎng)度),int (*cmp)(const void* e1,const void* e2)(自定義比較函數(shù)))
- qsort()函數(shù)應(yīng)用:模擬計(jì)算器,排序結(jié)構(gòu)體
//模擬計(jì)算器,對(duì)上面的代碼進(jìn)行優(yōu)化
#includevoid print(int* str, int sz)
{
int i = 0;
for (i = 0; i< sz; i++)
{
printf("%d ", str[i]);
}
printf("\n");
}
void swap(char* e1, char* e2, int width)
{
int temp = 0;
int i = 0;
for (i = 0; i< width; i++)
{
temp = *e1;
*e1 = *e2;
*e2 = temp;
e1++;
e2++;
}
}
int cmp(const void* e1, const void* e2)
{
return (*(int*)e1 - *(int*)e2);//e1>e2->>0;e1=e2->0;e1<0
}
int bubble_sort(void* base, int num, int width, int(*cmp)(const int* e1, const int* e2))
{
int i = 0;
int j = 0;
for (i = 0; i< num - 1; i++)
{
for (j = 0; j< num - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width)>0)
{
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
int main()
{
int arr[] = { 9,8,7,3,5,4,2,1,6,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp);
print(arr, sz);
return 0;
}
//排序結(jié)構(gòu)體
#includestruct Student
{
char name[20];
int age;
double score;
};
int cmp_name(const void* e1, const void* e2)
{
return strcmp(((struct Student*)e1)->name, ((struct Student*)e2)->name);
}
int main()
{
struct Student arr[] = { {"zhang",17,80.6},{"wang",20,85.2},{"li",19,92.0} };
int sz = sizeof (arr) / sizeof (arr[0]);
qsort(arr,sz,sizeof (arr[0]),cmp_name);
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)查看詳情吧