欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

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

[C語言]指針進階

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

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

🌴專欄鏈接:C語言

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

介紹了指針的一些進階使用,函數指針,函數指針數組,轉移表,內容難度上升。

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

輸出的結果:

str1 and str2 are not same
str3 and str4 are same
2.指針數組:

📣顧名思義存放指針的數組

例如:

int* arr1[10]; //整形指針的數組
char *arr2[4]; //一級字符指針的數組
char **arr3[5];//二級字符指針的數組
3.數組指針:

數組指針的定義:指向數組的指針

下面代碼哪個是數組指針?

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

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

(1)相同的點:

打印地址的代碼:

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

不同的點:

📣原因是:

  • &arr和arr數值上相同,但是意義卻不同 &arr表示的是數組的地址(對應之前的兩種特殊情況)。
  • arr表示的是數組首元素地址。
  • 所以&arr + 1 跳過的是整個數組&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.數組指針的使用:

數組指針指向的是數組,那數組指針中存放的應該是數組的地址

#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);
			//數組名arr,表示首元素的地址
			//但是二維數組的首元素是二維數組的第一行
			//所以這里傳遞的arr,其實相當于第一行的地址,是一維數組的地址
			//可以數組指針來接收
			print_arr2(arr, 3, 5);
		return 0;
}

幾個例子:

int arr[5];         //整型數組
int *parr1[10];     //指針數組
int (*parr2)[10];   //數組指針
int (*parr3[10])[5];//數組指針的數組
6.數組參數、指針參數: 6.1一維數組傳參:
#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);
}

數組傳參:形參可以是數組,也可以是指針

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

函數的形參是一級指針我們可以傳什么參數:

void test1(int *p)
{}
//test1函數能接收什么參數?

int a = 0;
test(&a);//ok

int * ptr = &a;
test(ptr);//ok

int arr[10];
test(arr);//ok

void test2(char* p)
{}
//test2函數能接收什么參數?
//類似上面
//char型變量的地址
//char型數組名或地址
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;
}

當函數的參數為二級指針的時候,可以接收什么參數?

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  因為指針數組的數組名就是首元素地址也就是二級指針
	return 0;
}
7.函數指針:

首先看一段代碼:

#includevoid test()
{printf("hehe\n");
}
int main()
{printf("%p\n", test);
printf("%p\n", &test);
return 0;
}

在這里插入圖片描述

7.1如何保存函數的地址:

創(chuàng)建一個函數指針類型:

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

兩段考基礎的代碼:

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

解釋:

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

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

//把0直接轉換成一個void (*)()的函數指針,然后去調用0地址處的函數


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

對代碼2的化簡:

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

即存放函數指針的數組

如何定義:

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

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

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

用途是:轉移表:

應用示例(計算機):

#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 }; //轉移表
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( "輸入操作數:" );
					scanf( "%d %d", &x, &y);
					ret = (*p[input])(x, y);
			}
			else
					printf( "輸入有誤\n" );
					printf( "ret = %d\n", ret);
}
return 0;
}
9.指向函數指針數組的指針:

本質上還是一個指針:

如何定義:

返回值類型 (*(*變量名)[數組大小])(形參);

例如:

void test(const char* str)
{printf("%s\n", str);
}
int main()
{//函數指針pfun
		void (*pfun)(const char*) = test;
		//函數指針的數組pfunArr
		void (*pfunArr[5])(const char* str);
		pfunArr[0] = test;
		//指向函數指針數組pfunArr的指針ppfunArr
		void (*(*ppfunArr)[5])(const char*) = &pfunArr;
	return 0;
}
10.回調函數:

回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個

函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數

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

行響應

示例(快排):

int swap_int(const void* a, const void* b)
{return (*(int*)a) - (*(int*)b);
}
qsort(arr, sizeof(int), sizeof(arr) / sizeof(int), swap_int);

到這本篇博客的內容就到此結束了。
如果覺得本篇博客內容對你有所幫助的話,可以點贊,收藏,順便關注一下!
如果文章內容有錯誤,歡迎在評論區(qū)指正

在這里插入圖片描述

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

網頁名稱:[C語言]指針進階-創(chuàng)新互聯
鏈接地址:http://www.chinadenli.net/article10/igido.html

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

廣告

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

微信小程序開發(fā)