[C語言]指針進階-創(chuàng)新互聯(lián)

[C語言]指針進階

創(chuàng)新互聯(lián)公司是一家專業(yè)從事做網(wǎng)站、成都網(wǎng)站設(shè)計的網(wǎng)絡(luò)公司。作為專業(yè)網(wǎng)站制作公司,創(chuàng)新互聯(lián)公司依托的技術(shù)實力、以及多年的網(wǎng)站運營經(jīng)驗,為您提供專業(yè)的成都網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷推廣及網(wǎng)站設(shè)計開發(fā)服務(wù)!文章目錄
  • [C語言]指針進階
    • 1.字符指針:
    • 2.指針數(shù)組:
    • 3.數(shù)組指針:
    • 4.&數(shù)組名VS數(shù)組名:
    • 5.數(shù)組指針的使用:
    • 6.數(shù)組參數(shù)、指針參數(shù):
      • 6.1一維數(shù)組傳參:
      • 6.2二維數(shù)組傳參:
      • 6.3一級指針傳參:
      • 6.4二級指針傳參:
    • 7.函數(shù)指針:
      • 7.1如何保存函數(shù)的地址:
    • 8.函數(shù)指針數(shù)組:
      • 8.1應(yīng)用:
    • 9.指向函數(shù)指針數(shù)組的指針:
    • 10.回調(diào)函數(shù):

📟作者主頁:慢熱的陜西人

🌴專欄鏈接:C語言

📣歡迎各位大佬👍點贊🔥關(guān)注🚓收藏,🍉留言

介紹了指針的一些進階使用,函數(shù)指針,函數(shù)指針數(shù)組,轉(zhuǎn)移表,內(nèi)容難度上升。

1.字符指針:

📣在指針的類型中我們知道有一種指針類型為字符指針 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.";//這里是把一個字符串放到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]; //一級字符指針的數(shù)組
char **arr3[5];//二級字符指針的數(shù)組
3.數(shù)組指針:

數(shù)組指針的定義:指向數(shù)組的指針

下面代碼哪個是數(shù)組指針?

int *p1[10];
int (*p2)[10];
//p1, p2分別是什么?
  • p1則是int型的指針數(shù)組
  • p2則是int型的數(shù)組指針
  • 原理是[]的優(yōu)先級比*高所以不帶括號的情況下就會被識別成數(shù)組
  • 帶上括號就會和解引用操作符結(jié)合所以就是數(shù)組指針了
4.&數(shù)組名VS數(shù)組名:

結(jié)論:打印地址的話數(shù)值上是相同的,實際上是兩種不同的類型所以在進行加一時步長不一樣;

(1)相同的點:

打印地址的代碼:

#includeint main()
{int arr[10] = {0};
		printf("%p\n", arr);
		printf("%p\n", &arr);
return 0;
}

不同的點:

📣原因是:

  • &arr和arr數(shù)值上相同,但是意義卻不同 &arr表示的是數(shù)組的地址(對應(yīng)之前的兩種特殊情況)。
  • arr表示的是數(shù)組首元素地址。
  • 所以&arr + 1 跳過的是整個數(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; jprintf("%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; jprintf("%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ù)組的地址
			//可以數(shù)組指針來接收
			print_arr2(arr, 3, 5);
		return 0;
}

幾個例子:

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è)計只能省略第一個[]的數(shù)字。
//因為對一個二維數(shù)組,可以不知道有多少行,但是必須知道一行多少元素。
//這樣才方便運算。
void test(int *arr)//no     是一級指針,無法接收數(shù)組的指針
{}
void test(int* arr[5])//no   是數(shù)組,無法接收指針
{}
void test(int (*arr)[5])//ok   數(shù)組指針可以接收
{}
void test(int **arr)//no   二級指針用于接收一級指針的地址與arr不匹配所以不行
{}
int main()
{int arr[3][5] = {0};
test(arr);//因為arr是二維數(shù)組,所以arr表示的是第一行的地址
}
6.3一級指針傳參:
#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]);
		//一級指針p,傳給函數(shù)
		print(p, sz);
	return 0;
}

函數(shù)的形參是一級指針我們可以傳什么參數(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ù)?
//類似上面
//char型變量的地址
//char型數(shù)組名或地址
6.4二級指針傳參:

例如:

#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;
}

當函數(shù)的參數(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  因為指針數(shù)組的數(shù)組名就是首元素地址也就是二級指針
	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)建一個函數(shù)指針類型:

形式 :返回類型 (指針變量名)(函數(shù)參數(shù));*

兩段考基礎(chǔ)的代碼:

//代碼1
(*(void (*)())0)();
//代碼2
void (*signal(int , void(*)(int)))(int);

解釋:

//代碼1
0 - int
( void (*)() )0 - 把0當做一個函數(shù)的地址

( *( void (*)() )0 )();

//把0直接轉(zhuǎn)換成一個void (*)()的函數(shù)指針,然后去調(diào)用0地址處的函數(shù)


//代碼2
//上述代碼是一次函數(shù)聲明
//	//聲明的函數(shù)叫:signal
//	//signal函數(shù)的第一個參數(shù)是int類型的
//	//signal函數(shù)的第二個參數(shù)是一個函數(shù)指針類型,該函數(shù)指針指向的函數(shù)參數(shù)是int,返回類型是void
//	//signal函數(shù)的返回類型也是一個函數(shù)指針類型,該函數(shù)指針指向的函數(shù)參數(shù)是int,返回類型是void

對代碼2的化簡:

typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
8.函數(shù)指針數(shù)組:

即存放函數(shù)指針的數(shù)組

如何定義:

返回類型 ( * 變量名[x] )(形參); // 其中x表示的是數(shù)組的大小

例如 返回值為int 無形參的函數(shù)的函數(shù)指針數(shù)組:

int (*parr1[10])();
8.1應(yīng)用:

用途是:轉(zhuǎn)移表:

應(yīng)用示例(計算機):

#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( "請選擇:" );
		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ì)上還是一個指針:

如何定義:

返回值類型 (*(*變量名)[數(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ù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個

函數(shù),當這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)

的實現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外的一方調(diào)用的,用于對該事件或條件進

行響應(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é)束了。
如果覺得本篇博客內(nèi)容對你有所幫助的話,可以點贊,收藏,順便關(guān)注一下!
如果文章內(nèi)容有錯誤,歡迎在評論區(qū)指正

在這里插入圖片描述

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:[C語言]指針進階-創(chuàng)新互聯(lián)
鏈接地址:http://bm7419.com/article10/igido.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、微信公眾號定制網(wǎng)站、微信小程序動態(tài)網(wǎng)站、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)