日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言——指针详解(必收藏)

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言——指针详解(必收藏) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

1.什么是指針?

1.1概念

1.2指針的大小

??1.3指針類型的作用

2.野指針?

2.1野指針產生的原因

2.2 如何規避野指針

3.指針運算?

3.1指針+-整數

3.2指針-指針

3.3 指針的關系運算?

4. 二級指針

5. 數組名

*6.指針數組和數組指針?

6.1指針數組

*6.2數組指針?

?6.3舉例區別含義

7.數組參數和指針參數

7.1數組參數

7.2指針傳參

8.函數指針?

9.函數指針數組

9.1指向函數指針數組的指針

*10.回調函數

1.什么是指針?

1.1概念

簡單的來說,指針就是地址。我們口頭上說的指針其實指的是指針變量。指針變量就是一個存放地址的變量。

1.2指針的大小

?指針在32位機器下是4個字節,在64位機器下是8個字節。注:(指針的大小與類型無關)

?

?1.3指針類型的作用

上面涉及到指針的大小與指針類型無關,那么指針類型的作用是什么呢?

指針解引用訪問,使用的訪問權限是多少? ? 話不多說,上圖!

當一個int* 的指針+1,跳過4個字節;當一個char* 的指針+1,跳過1個字節。

同理,對于(指針+-整數)類的題也是如上的原理。

2.野指針?

野指針顧名思義,指針指向的位置不可知,就像沒有主人的流浪狗。

2.1野指針產生的原因

  • 指針未被初始化

  • 指針越界訪問

  • 指針指向的空間釋放

  • 對于前兩點比較好理解,下面對第三點進行解釋:

    int* test( ) {int a = 5;return &a; } int main() {int* p = test();*p = 10;return 0; }

    變量a的地址只在test()函數內有效,當把a的地址傳給指針p時,因為出了test函數,變量a的空間地址釋放,導致p變成了野指針。

    2.2 如何規避野指針

  • 小心越界
  • 及時把指針賦成空指針
  • 避免返回局部變量的地址
  • 使用指針前檢查有效性
  • 3.指針運算?

    3.1指針+-整數

    此部分內容跟指針類型那部分一致

    3.2指針-指針

    指針-指針的絕對值指的是兩個指針之間元素的個數。

    前提:兩個指針必須指向同一空間

    例如:&arr[9]-&arr[0]?

    下面舉個例子實現my_strlen函數

    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 指針的關系運算?

    此部分內容很簡單,指針與指針之間比較大小就是指針的關系運算。

    例如:定義int* p1,數組int arr[5],p1>&arr[5]。

    但是要遵循一個標準:允許指針指向數組元素和指針指向數組最后一個元素后面的位置進行比較,不允許指針指向數組元素與指針指向數組第一個位置的前面進行比較。

    4. 二級指針

    二級指針就是存放指針地址的指針變量。就像有三個抽屜第一個抽屜的鑰匙放在第二個抽屜,第二個抽屜的鑰匙放在第三個抽屜。

    例如:int a=10;int* p1=&a;int** p2=&p1;

    對int* * 做解釋:第一個*號代表指針指向的類型是int*的,第二個*代表這個是指針。

    5. 數組名

    數組名大家都很熟悉,但要區分以下幾種情況:

  • sizeof(arr):表示的是整個數組的大小。
  • &arr: 表示整個數組,取出的是整個數組的大小。
  • 其他情況數組名都表示數組首元素地址。

    *6.指針數組和數組指針?

    6.1指針數組

  • 定義:存放指針的數組(int* arr[])。我們知道有整型類型的數組int arr[],還有字符類型的數組char arr[],指針數組就是指針類型的數組。

  • 以下舉個例:

  • int main() {int a = 0;int b = 1;int* p1 = &a;int* p2 = &b;int* arr[] = { p1,p2 };//指針數組int* arr[] = { &a,&b };//指針數組return 0; }

    *6.2數組指針?

  • 定義: 指向數組的指針int (*)[]。
  • 應用:遍歷整個二維數組
  • 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]);相似的寫法}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舉例區別含義

    • int arr[5]? ? ? ? ? ? ? ?//名為arr的數組,數組里有5個元素,每個元素是int
    • int* p1[5]? ? ? ? ? ? ? //指針數組,數組里有5個元素,每個元素是int*
    • int (*p2)[5]? ? ? ? ? ? //數組指針,一個指向數組(里面有五個元素,每個元素是int)的指? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 針
    • int (*p3[5])[5]? ? ? ? //p3[5]是一個有5個元素的數組,數組里每個元素是int(*)[5]

    7.數組參數和指針參數

    7.1數組參數

    • 一維數組傳參:?int arr[10](形參部分數組大小可以不寫)、int* arr
    • 二維數組傳參: int arr[3][5]、int arr[][5](行可以省略,列不能)、int (*arr)[5]? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 不能直接傳數組名,二維數組的首地址是第一行元素的首地址

    7.2指針傳參

    • 一級指針傳參:int* p
    • 二級指針傳參:int** p

    8.函數指針?

  • 定義:指向函數的指針int (*pf) (int,int),pf函數返回的類型是int (*)(int,int)
  • 對于函數來說如:Add和&Add,意義和值都一樣。這一定要區別于數組。
  • 特別的,當要調用函數時,定義一個pf的函數指針指向函數。那么int ret=(*pf)(2,3)和int ret=pf (2,3)等價。
  • ?**對下面代碼的理解:

    (*(void(*)())0)()? ? ? ? ? ? ? ? ? ? ? ? ? ? //? ?將0處強制類型轉換為函數指針類型,再對0地址? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?進行調用

    void(*signal(int,void(*)(int)))(int)? ? ? ??//這是函數的聲明,singal是一個函數,傳進去兩個? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 參數的類型是int和void(*)(int),signal函數的返回值? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 類型是void(*)(int)。

    9.函數指針數組

  • 定義:存放函數指針類型元素的數組
  • 應用:實現計算器
  • #include<stdio.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"); }int main() {menu();int input = 0;printf("請選擇:");scanf("%d",&input);int ret = 0;//轉移表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("請輸入兩個操作數:");scanf("%d%d",&x,&y);ret = pfarr[input](x,y);printf("結果是%d\n",ret);break;}else{printf("選擇錯誤!");}} while (input);return 0; }

    9.1指向函數指針數組的指針

    1.定義:int (*(*parr)[4])(int? int)=&parr

    *10.回調函數

    • qsort()函數:?是一個庫函數,基于快速排序算法實現的一個排序的函數。優點是,任意類型的數據都能排序
    • qsort()函數的形參定義:

    void qsort(void* base(起始地址),size_t num(元素個數),size_t width(一個元素的字節長度),int (*cmp)(const void* e1,const void* e2)(自定義比較函數))

    • qsort()函數應用:模擬計算器,排序結構體
    //模擬計算器,對上面的代碼進行優化 #include<stdio.h>void 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<e2-> <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; } //排序結構體 #include<stdio.h> struct 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; }

    總結

    以上是生活随笔為你收集整理的C语言——指针详解(必收藏)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。