国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

青浦手機網(wǎng)站建設(shè)網(wǎng)站推廣排名公司

青浦手機網(wǎng)站建設(shè),網(wǎng)站推廣排名公司,個人網(wǎng)站設(shè)計html,如何和網(wǎng)站建設(shè)者聯(lián)系1、字符指針 (1)字符指針的普通用法 char a A; char* pa &a;但是一般來說字符指針很少這么用……更多是拿來存儲一個字符串 (2)字符串的兩種存儲以及區(qū)別 現(xiàn)在有了兩種存儲數(shù)組的方法 ①一個是使用char類型數(shù)組存儲②另外…

1、字符指針

(1)字符指針的普通用法

char a = 'A';
char* pa = &a;

但是一般來說字符指針很少這么用……更多是拿來存儲一個字符串

(2)字符串的兩種存儲以及區(qū)別

  • 現(xiàn)在有了兩種存儲數(shù)組的方法
    • ①一個是使用char類型數(shù)組存儲
    • ②另外一個是使用指向char類型的指針存儲數(shù)組的首元素地址,將其當(dāng)成字符串的“標(biāo)記”
#include <stdio.h>
int main()
{char str1[] = "hello word.";char str2[] = "hello word.";const char *str3 = "hello word.";//將字符串的首字母h的地址存儲在str3里面const char *str4 = "hello word.";if(str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if(str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}
  • 兩個數(shù)組存儲不同的字符串,盡管他們的內(nèi)容是相同的
  • 兩個字符指針都指向內(nèi)容相同的字符串

這意味著str3和str4指向的是同一個常量字符串,C/C++會把常量字符串存儲到一個單獨的內(nèi)存區(qū)域,當(dāng)幾個指針指向同一串字符串時,他們實際是指向同一塊內(nèi)存。但是用相同的常量字符串去初始化不同數(shù)組時,數(shù)組會對常量字符串進行拷貝,開辟出不同的內(nèi)存塊,所以str1!=str2,但是str3==str4

(3)存儲多個字符串----字符指針數(shù)組

int main()
{char* arr[3] = { "abcd", "cdf", "jiuh" };int i = 0;for(i = 0; i < 3; i++){printf("%s\n", arr[i]);}return 0;
}

2、指針數(shù)組

比較簡單,直接寫下code就可以

char* arr[4];//存儲了4個char*指針
char** arr[10];//存儲了10個char**指針

3、數(shù)組指針

(1)數(shù)組的基礎(chǔ)概念

  • 數(shù)組名字有兩種情況如下code
//復(fù)習(xí)數(shù)組的名字含義
#include <stdio.h>
int main()
{int arr[10] = { 0 };printf("%p\n", arr);//數(shù)組名字就是首元素地址printf("%p\n", &arr[0]);//取出了首元素地址printf("%p\n, &arr);//1、取出來整個數(shù)組的地址,盡管&arr和&arr[0]的值一樣,但是意義不一樣(類型不一樣),前者是數(shù)組類型int[10],后者是整型類型intprintf("%zd\n", sizeof(arr));//2、這里的arr依舊是整個數(shù)組return 0;
}

①sizeof(數(shù)組名),這里的數(shù)組名表示整個數(shù)組,計算的是整個數(shù)組的大小
②&數(shù)組名,這里取出來的是整個數(shù)組地址,盡管它的值和數(shù)組的首元素地址相同,兩者是有區(qū)別的

最大的區(qū)別就在于int arr[10]聲明后,arr是首元素地址,指針類型是int*,這是個數(shù)組指針。而能存放&arr這個地址的指針類型是int(*)[10]。這點在對兩種指針進行+/-整數(shù)的時候會更加明顯,因為指針會根據(jù)指向的類型對地址值進行增加 (數(shù)組指針后面會講)

(2)數(shù)組指針的定義

數(shù)組指針也是指針

int (*p)[10];//p是一個指向一維整型數(shù)組的指針,該數(shù)組內(nèi)含10個int類型

注意[]和()具有相同的優(yōu)先級,結(jié)合性是從左向右結(jié)合。并且優(yōu)先級都比*高。

(3)數(shù)組指針的使用

//第一種使用方法
int main()
{int arr[10] = {1, 2, 3, 4, 5};int (*p)[10] = &arr;return 0;
}語法邏輯沒毛病,可以,但是一般不會這么使用
//第二種使用方法
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{int i = 0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}
}void print_arr2(int (*arr)[5], int row, int col)
{int i = 0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}
}int main()
{int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};//數(shù)組名arr,表示首元素的地址//但是二維數(shù)組的首元素是二維數(shù)組的第一行,指向這一行的指針類型可以寫成int [][5]或者int (*)[5]//所以這里傳遞的arr,其實相當(dāng)于第一行的地址,是一維數(shù)組的地址print_arr1(arr, 3, 5);print_arr2(arr, 3, 5);return 0;
}

(4)更多數(shù)組指針的解讀

int arr[5];//單純是個整型數(shù)組int* parr1[10];//單純是一個指針數(shù)組,每一個指針都指向一個intint (*parr2)[10];//數(shù)組指針,該指針指向一個包含10個int元素的數(shù)組int (*parr3[10])[5];//指針數(shù)組,可以思考成“int(*)[5] parr3[10]”(與int arr[5]是類似的)很明顯,這是一個包含10個元素的數(shù)組,每個元素都int(*)[5]這種類型的指針,這種指針指向一包含5個元素的數(shù)組

4、數(shù)組傳參和指針傳參

(1)一維數(shù)組傳參

#include <stdio.h>
void test1(int arr[])//可以這么寫
{//code
}
void test1(int arr[10])//10寫與不寫都行,無所謂,C會將它忽略
{//code
}
void test1(int *arr)//可以的,傳過來的arr1的拷貝是一個int元素地址
{//code
}void test2(int *arr[20])//20寫與不寫都行,C依舊會將它忽略
{//code
}
void test2(int **arr)//也可以,傳過來的arr2的拷貝是一個int*元素的地址
{//code
}int main()
{int arr[10] = {0};int *arr2[20] = {0};test(arr1);test2(arr2);
}

(2)二維數(shù)組傳參

void test(int arr[3][5])//可以使用,不過3會被忽略
{//code
}
void test(int arr[][])//不可以使用,5必須留下來
{//code
}
void test(int arr[][5])//可以使用
{//code
}
//二維數(shù)組傳參,函數(shù)形參的設(shè)計只能省略第一個[]的數(shù)字。
//對一個二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素。void test(int *arr)//不行,類型不匹配,拷貝過來的參數(shù)是一個指向一維數(shù)組的指針,而這個參數(shù)僅僅是一個一維指針
{//code
}
void test(int* arr[5])//不行,這是一個指針數(shù)組,根本沒有關(guān)系 
{//code
}
void test(int (*arr)[5])//可以這么寫,指針類型匹配了
{//code
}
void test(int **arr)//不行,指針類型不匹配
{//code
}int main()
{int arr[3][5] = {0};test(arr);
}
//使用二維數(shù)組指針(深刻理解)
void print(int(*p)[20], int x, int y)
{//二維數(shù)組的名字就是首元素的地址,其地址就是第一行數(shù)組的地址,也就是指向一維數(shù)組類型的指針,因此不能寫形參為int**//又因為一維數(shù)組的整體地址&arr和其首元素地址&arr[0]起始位置相同,故從值來看是一樣的,但是兩者的指針類型完全不同for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d", *(* (p + i) + j));//得到數(shù)組名,利用i得到每一行的數(shù)組名,利用j得到某一行的每一列的元素地址}}
}
int main()
{int arr[10][20] = { {1, 2, 3}, {2, 3, 4} };print(arr, 10, 20);return 0;
}

(3)一級指針傳參

#include <stdio.h>
void print(int *p, int sz)
{int i = 0;for(i=0; i<sz; 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]);//一級指針p,傳給函數(shù)print(p, sz);return 0;
}

(4)二級指針傳參

#include <stdio.h>
void 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;
}

(5)總結(jié)

指針的類型一定要匹配好,盡管類型不匹配的時候依舊可以進行傳參(因為所有地址在同一個平臺都是一樣大小的,只是存儲一個地址,理論上用什么類型的指針都可以存儲),但是在后續(xù)使用指針的時候(解引用指針)就會發(fā)生錯誤,指針會根據(jù)指針類型訪問不同大小的內(nèi)存

5. 函數(shù)指針

  • 整型指針int*
  • 字符指針char*
  • 指向數(shù)組int arr[10]的數(shù)組指針int (*p)[10]
  • 指向函數(shù)function()的函數(shù)指針int (*pf)(int, int) = function(或者int (*pf)(int, int) = &function)其中函數(shù)function()是一個有兩個int參數(shù),返回值為int的函數(shù)

(1)函數(shù)指針

  • 對于函數(shù)function(),其函數(shù)指針類型為【返回值 (*指針名) (參數(shù)類型的列表)】

  • 若想使用這個函數(shù)就要進行解引用,使用【(* pf)(參數(shù)列表)】或者【pf(參數(shù)列表)】都可以。編譯器在處理的時候,沒有 * 也行,但是要用 * 就一定要加括號

    • 盡管這樣很矛盾,但是調(diào)用函數(shù)指針時,使用*pf和pf是一樣的,即:函數(shù)名==函數(shù)的地址,而(&函數(shù)名)==函數(shù)的地址
    • 若是理解pf為指針,則*pf變成函數(shù)名字,*pf()就相當(dāng)于function()
    • 若是理解pf為函數(shù)名,則pf本身就是函數(shù)的名字,pf()就相當(dāng)于function()
    • C允許這兩種寫法,認(rèn)為兩種都合理
//例子
char* test(int c, float* pf)
{//某些代碼
}
int main()
{char* (*pt)(int, float*)pf = test;test(參數(shù)列表)return 0;
}

(2)有關(guān)函數(shù)指針的一些有趣的代碼

//代碼1
(*(  void (*)()  )0)();//從最里面開始理解void(*)()是一個指向“返回值為空,參數(shù)列表為空”函數(shù)的函數(shù)指針
//然后將0的int類型強制轉(zhuǎn)化為函數(shù)指針類型,于是0成了一個函數(shù)指針類型的地址
//再解引用0這個地址,得到0地址處的函數(shù),然后使用這個函數(shù)
//代碼2
void (*  signal(int , void(*)(int))  )(int);//等價代碼如下
//typedef void(*pfun_t)(int);//注意pfun_t是一個和void(*)(int)同類型名,將pfun_t放在*旁邊是為了指明pfun_t是一個指針而已,這只是語法形式要求
//pfun_t signal(int, pfun_t);//因此有一個簡化代碼的技巧就是使用typedef

這兩段代碼來自于《C陷阱與缺陷》,是本出名的C語言書籍

6. 函數(shù)指針數(shù)組

(1)使用例子

#include <stdio.h>
int 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;do{printf("*************************\n");printf(" 1:add             2:sub \n");printf(" 3:mul             4:div \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);switch (input){case 1:printf("輸入操作數(shù):");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("輸入操作數(shù):");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("輸入操作數(shù):");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("輸入操作數(shù):");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");breark;default:printf("選擇錯誤\n");break;}} while (input);return 0
}

(2)改良后

#include <stdio.h>
int 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)移表,即函數(shù)指針數(shù)組,這里的0(或者寫NULL)起到占位的作用,理論上放什么都行,只要后續(xù)處理好就行…while (input){printf("*************************\n");printf(" 1:add           2:sub \n");printf(" 3:mul           4:div \n");printf("*************************\n");printf("請選擇:");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;
}
//當(dāng)計算器后續(xù)需要加入更多的運算函數(shù)時,那么使用開關(guān)語句就會顯得冗長,但是使用函數(shù)指針數(shù)組就不會有這個問題,這將會大大縮減代碼。但是使用函數(shù)指針也具有有缺點,它只能存放同樣函數(shù)簽名(函數(shù)簽名定義了函數(shù)的輸入和輸出,即:函數(shù)簽名==參數(shù)+返回值)的函數(shù)

(3)轉(zhuǎn)移表的概念

像類似上面使用函數(shù)指針數(shù)組的方法就叫做轉(zhuǎn)移表,具有一種跳轉(zhuǎn)使用函數(shù)的效果。即“函數(shù)指針數(shù)組”==“轉(zhuǎn)移表”

7. 指向函數(shù)指針數(shù)組的指針

void test(const char* str)
{printf("%s\n", str);
}
int main()
{//聲明函數(shù)指針pfun,并且進行初始化void (*pfun)(const char*) = test;//聲明一個函數(shù)指針的數(shù)組pfunArrvoid (*pfunArr[5])(const char* str) = { pfun };pfunArr[0] = test;//指向函數(shù)指針數(shù)組pfunArr的指針ppfunArrvoid (*(*ppfunArr)[5])(const char*) = &pfunArr;return 0;
}
//*代表ppfunArr是指針,[]代表這個指針指向一個內(nèi)含5元素的數(shù)組,而每個元素的類型都是void (*)(const char*)
//因此按照運算符的順序來解讀是比較快的    

8. 回調(diào)函數(shù)

  • 回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。
  • 如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另外一個函數(shù),當(dāng)這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)。
  • 回調(diào)函數(shù)不是由該函數(shù)的實現(xiàn)方式直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外一方調(diào)用的,用于對該事件或條件進行響應(yīng)

(1)例子一:使用qsort

①前要:C庫函數(shù)qsort能對數(shù)組進行排序

void qsort(void *base,//指向了待排序數(shù)組的第一個元素 size_t nitems,//排序的元素個數(shù)size_t size,//每個元素的大小,單位是字節(jié)int (*compar)(const void*, const void*)//指向一個函數(shù),這個函數(shù)可以比較兩個元素的大小);//其底層是使用快速排序的方法來排序的,依靠compar指向的不同函數(shù)內(nèi)部不同的比較,可以解決不同類型的數(shù)據(jù)快速排序

②使用qsort:對數(shù)組進行排序

#include <stdio.h>
#include <stdlib.h>
//qosrt函數(shù)的使用者得實現(xiàn)一個比較函數(shù)
int int_cmp(const void * p1, const void * p2)
{return ( *(int*)p1 - *(int*)p2 );//注意不能直接解引用void指針,另外如果倒過來就是逆序輸出了
}
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;
}

(2)例子二:模擬實現(xiàn)類似qsort函數(shù)的bubble函數(shù)(底層采用冒泡函數(shù))

#include <stdio.h>
int int_cmp(const void * p1, const void * p2)//其中一個比較函數(shù),這個是整型比較,是用戶決定這個函數(shù)應(yīng)該如何編寫
{return (*(int*)p1 - *(int*)p2);//不過注意void不能直接解引用!!!
}void _swap(void *p1, void * p2, int size)//其中一個排序方法,這個是排序是冒泡排序,可以由開發(fā)者決定底層排序的方法,在qsort中使用的底層函數(shù)是快排
{int i = 0;for (i = 0; i< size; i++)//之所以這么做,是因為沒有辦法預(yù)測有多少個字節(jié),只能通過一個一個字節(jié)進行交換,最后所有字節(jié)進行交換,即兩個數(shù)據(jù)進行了交換{char tmp = *((char*)p1 + i);*((char*)p1 + i) = *((char*)p2 + i);*((char*)p2 + i) = tmp;}
}void bubble(void *base, int count, int size, int(*cmp )(void*, void*))//相當(dāng)于qsort,但是實現(xiàn)邏輯不僅僅是快速排序,內(nèi)部的_swap函數(shù)也可能是其他的排序算法,cmp函數(shù)可能比較不同類型的數(shù)據(jù)。     注意base是void*類型,寫int*會寫死的,只能限定于整型
{int i = 0;int j = 0;for (i = 0; i < count - 1; i++){int flag = 1;//①優(yōu)化代碼,若是沒有交換就說明不需要經(jīng)過排序就是有序的了for (j = 0; j < count - i - 1; j++){if (cmp ((char*) base + j * size, (char*)base + (j + 1) * size) > 0)//比較函數(shù),這里改成(char*)就可以利用size適應(yīng)不同的字節(jié){flag = 0;_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);//排序函數(shù),這里改成(char*)就可以利用size適應(yīng)不同的字節(jié)}if(flag == 1){break;}}}
}int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };//char *arr[] = {"aaaa","dddd","cccc","bbbb"};int i = 0;bubble(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;
}

注意我們不是在模擬qsort函數(shù),而是作一個類似qsort函數(shù)的“冒泡排序通用的bubble函數(shù)”

http://m.aloenet.com.cn/news/38452.html

相關(guān)文章:

  • php網(wǎng)站后臺模板推廣app最快的方法
  • 貴陽 網(wǎng)站建設(shè)網(wǎng)絡(luò)營銷主要內(nèi)容
  • 做旅行網(wǎng)站的依據(jù)及意義國內(nèi)十大搜索引擎網(wǎng)站
  • 福州專業(yè)網(wǎng)站建設(shè)友鏈交易網(wǎng)
  • app小程序開發(fā)價格網(wǎng)站優(yōu)化方式有哪些
  • 無錫網(wǎng)站建設(shè)制作方案網(wǎng)頁設(shè)計制作網(wǎng)站html代碼大全
  • 特效網(wǎng)站大全seo秘籍優(yōu)化課程
  • 哪家做網(wǎng)站便宜營銷型網(wǎng)站建站推廣
  • 網(wǎng)站開發(fā)數(shù)據(jù)庫課程設(shè)計專注于網(wǎng)站營銷服務(wù)
  • 做模擬人生類的游戲下載網(wǎng)站廣告開戶南京seo
  • 調(diào)查問卷在哪個網(wǎng)站做子域名在線查詢
  • 志勛網(wǎng)站建設(shè)公司中國十大外貿(mào)平臺
  • 建企業(yè)網(wǎng)站怎么做網(wǎng)站自然排名工具
  • 有域名怎樣做網(wǎng)站軟文網(wǎng)站發(fā)布平臺
  • 9元包郵網(wǎng)站怎么做seo搜索引擎優(yōu)化是什么
  • 網(wǎng)站域名建設(shè)費進什么科目人工智能培訓(xùn)心得體會
  • 有域名了怎么做網(wǎng)站百度推廣優(yōu)化公司
  • 新手做網(wǎng)站視頻講解大地seo視頻
  • 騰訊 網(wǎng)站開發(fā)如何在百度推廣自己的產(chǎn)品
  • 做網(wǎng)站運營需要培訓(xùn)嗎在線搭建網(wǎng)站
  • 濰坊做網(wǎng)站的電話seo網(wǎng)站有優(yōu)化培訓(xùn)班嗎
  • 備案平臺新增網(wǎng)站優(yōu)秀的軟文廣告欣賞
  • h5互動網(wǎng)站建設(shè)今日百度小說排行榜
  • 易語言可以建設(shè)網(wǎng)站嗎新站seo優(yōu)化快速上排名
  • 網(wǎng)站開發(fā)實踐研究報告溫州seo排名公司
  • 給公眾號做頭像的網(wǎng)站北京百度關(guān)鍵詞優(yōu)化
  • 智能建站cms管理系統(tǒng)百度推廣關(guān)鍵詞優(yōu)化
  • 重慶網(wǎng)站租賃空間國內(nèi)新聞最新消息今天
  • asp網(wǎng)站仿制公司官網(wǎng)開發(fā)制作
  • 同程網(wǎng) 網(wǎng)站模板國外網(wǎng)絡(luò)推廣