主頁 > 軟體設計 > C語言的羅盤——指標!深入理解C語言指標及其應用

C語言的羅盤——指標!深入理解C語言指標及其應用

2021-08-15 08:04:15 軟體設計

??前面的話??

在前面C語言的指南針——指標!指標與結構體的介紹和C語言處理批量資料的好伙伴!陣列!C語言陣列的介紹與應用兩篇文章中已經簡要介紹了陣列指標,字串庫函式和指標等內容,在這篇文章我們將繼續深入了解有關字串庫函式和指標的探索,

📒博客主頁:https://blog.csdn.net/m0_59139260?spm=1011.2124.3001.5343
🎉歡迎關注🔎點贊👍收藏??留言📝
📌本文由未見花聞原創,CSDN首發!
??堅持和努力一定能換來詩與遠方!
🙏作者水平很有限,如果發現錯誤,一定要及時告知作者哦!感謝感謝!
博主的碼云gitee,平常博主寫的程式代碼都在里面,


內容導讀

  • 1.字符指標與字串
    • 1.1字符指標與字串的關系
    • 1.2常用的幾個字串庫函式
      • 1.2.1輸出輸入字串的函式
      • 1.2.2字串連接函式
      • 1.2.3字串復制函式
      • 1.2.4字串比較函式
      • 1.2.5測字串長度的函式
      • 1.2.6轉換為大小寫的函式
  • 2.指標陣列與陣列指標
    • 2.1指標陣列
    • 2.2陣列指標
    • 2.3陣列名與&陣列名
  • 3.陣列傳參與指標傳參
    • 3.1陣列傳參
      • 3.1.1一維陣列傳參
      • 3.1.2二維陣列傳參
    • 3.2指標傳參
      • 3.2.1一級指標傳參
      • 3.2.2二級指標傳參
  • 4.函式指標與函式指標陣列
    • 4.1函式指標
    • 4.2函式指標陣列及其在計算器的應用
  • 5.回呼函式


1.字符指標與字串

字符指標即指向字符型別的指標,

char* pch = NULLchar ch = 's';
pch = &ch;//字符指標

1.1字符指標與字串的關系

在C語言中,并沒有字串這種資料型別,但是在編程中又常常遇到字串,那在C語言中然后去表達字串呢?
有兩種方式,一是使用字符陣串列示字串,本質上就是定義一個char型別的陣列變數去儲存字串,使用字符陣串列示字串得到的是一個字串變數,它是能夠被修改的;二是使用字符指標的方式去表達字串,本質上就是使用一個char指標指向字串的第一個字符,因為在輸出字串的時候計算機是以\0為標志來列印字串的,但是要注意的是,它和使用字符陣列不同,字符陣列定義的是一個字串變數,而字符指標定義的是一個字串常量,是不能進行修改的,

#include <stdio.h>

int main()
{
	char str1[40] = "Come on, China Olympic Games!";//使用字符陣列定義字串變數

	char* str2 = "Come on, China Olympic Games!";//使用字符指標定義字串常量

	printf("str1:%s\nstr2:%s\n", str1, str2);
	return 0;
}

💡運行結果:

str1:Come on, China Olympic Games!
str2:Come on, China Olympic Games!

D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 6960)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

如果不小心對字串常量修改,會引發讀寫訪問沖突的例外,對于VS這個例外只有在除錯的時候才能看得見而在編譯的時候是不會報警告或者報錯的,萬一是在一個很大的工程中出現了這種問題,是很難察覺的,所以一般定義一個不能被修改的變數或常量的時候,一般在定義的資料型別前面加上一個const,這樣如果不小心修改了這個const修飾的變數或常量,編譯器在編譯的時候就會報錯,這樣就能更容易地發現讀寫沖突例外的情況,

💡面試題:

#include <stdio.h>
int main()
{
    char str1[] = "hello str.";
    char str2[] = "hello str.";
    char* str3 = "hello str.";
    char* str4 = "hello str.";
    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

D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 16488)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

1.2常用的幾個字串庫函式

在前面介紹字符陣列的時候簡要提到了這幾個與字串相關的庫函式,現在我將詳細介紹這些常用的庫函式,

1.2.1輸出輸入字串的函式

puts(字符陣列);//輸出
int puts(const char* string);
gets(字符陣列);//輸入
char* gets(char* buffer);

在這里插入圖片描述
🔎puts:函式所在庫為stdio.h;函式引數為const修飾的char*型別(使用const修飾是為了防止字串被修改);函式回傳值為int,如果函式執行失敗則會回傳EOF
在這里插入圖片描述

🔎gets:函式所在庫為stdio.h;函式引數為char*型別(從緩沖區讀取一行字串,buffer是緩沖區的意思);函式回傳值為char*(字串的第一個元素地址),函式不能傳入空指標,如果函式執行失敗會回傳EOF

用puts和gets函式只能輸出或輸入一個字串,

puts作用:將一個字串(以′\0′結束的字符序列)輸出到終端,
用puts函式輸出的字串中可以包含轉義字符,
在用puts輸出時將字串結束標志′\0′轉換成′\n′,即輸出完字串后換行,
gets作用:從終端輸入一個字串到字符陣列,并且得到一個函式值,該函式值是字符陣列的起始地址,

1.2.2字串連接函式

strcat(字串1, 字串2);
char *strcat( char *strDestination, const char *strSource );

在這里插入圖片描述
🔎strcat:函式所在庫為string.h;函式引數有兩個,第一個為char*型別(目的字串地址)第二個引數為const char*型別(被連接字串的地址);函式回傳值為char*(回傳strDestination的元素地址),
strcat函式將strSource追加到strDestination后面,

strcat作用:把兩個字符陣列中的字串連接起來,把字串2接到字串1的后面,結果放在字符陣列1中,函式呼叫后得到一個函式值——字符陣列1的地址,
字符陣列1必須足夠大,以便容納連接后的新字串,
連接前兩個字串的后面都有′\0′,連接時將字串1后面的′\0′取消,只在新串最后保留′\0′,

1.2.3字串復制函式

strcpy(字串1, 字串2);
char *strcpy( char *strDestination, const char *strSource );

在這里插入圖片描述

🔎strcpy:函式所在庫為string.h;函式引數有兩個,第一個為char*型別(目的字串地址)第二個引數為const char*型別(被復制字串的地址);函式回傳值為char*(回傳strDestination的元素地址),
strcpy函式將strSource復制給strDestination

strcpy作用:將字串2復制到字符陣列1中去,
字符陣列1必須定義得足夠大,以便容納被復制的字串2,字符陣列1的長度不應小于字串2的長度,
“字符陣列1”必須寫成陣列名形式,“字串2”可以是字符陣列名,也可以是一個字串常量,
若在復制前未對字符陣列1初始化或賦值,則其各位元組中的內容無法預知,復制時將字串2和其后的′\0′一起復制到字符陣列1中,取代字符陣列1中前面的字符,未被取代的字符保持原有內容,
不能用賦值陳述句將一個字串常量或字符陣列直接給一個字符陣列,字符陣列名是一個地址常量,它不能改變值,正如數值型陣列名不能被賦值一樣,
可以用strncpy函式將字串2中前面n個字符復制到字符陣列1中去,
將str2中最前面2個字符復制到str1中,取代str1中原有的最前面2個字符,但復制的字符個數n不應多于str1中原有的字符(不包括′\0′),

1.2.4字串比較函式

strcmp(字串1, 字串2);
int strcmp( const char *string1, const char *string2 );

在這里插入圖片描述
🔎strcmp:函式所在庫為string.h;函式引數有兩個,第一個為constchar*型別(第一個字串地址)第二個引數為const char*型別(第二個字串的地址);函式回傳值為int(相同則回傳0,字串1>字串2則回傳一個正整數,字串1<字串2則回傳一個負整數),

💡對兩個字串比較不能直接用str1>str2進行比較,因為str1和str2代表地址而不代表陣列中全部元素,而只能用 (strcmp(str1,str2)>0)實作,系統分別找到兩個字符陣列的第一個元素,然后順序比較陣列中各個元素的值,

strcmp作用:比較字串1和字串2,
字串比較的規則是: 將兩個字串自左至右逐個字符相比(按ASCII碼值大小比較),直到出現不同的字符或遇到′\0′為止,
(1) 如全部字符相同,則認為兩個字串相等;
(2) 若出現不相同的字符,則以第1對不相同的字符的比較結果為準,
比較的結果由函式值帶回,
(1) 如果字串1與字串2相同,則函式值為0,
(2) 如果字串1>字串2,則函式值為一個正整數,
(3) 如果字串1<字串2,則函式值為一個負整數,

1.2.5測字串長度的函式

strlen(字串);
size_t strlen( const char *string );//size_t本質上是unsigned int 型別

在這里插入圖片描述
🔎strlen:函式所在庫為string.h;函式引數為const char*型別(需要被計算字串長度的字串地址);函式回傳值為unsigned int(size_t)(回傳傳入字串長度大小),

strlen作用:測驗字串長度的函式,函式的值為字串中的實際長度(不包括′\0′在內),

1.2.6轉換為大小寫的函式

strlwr(字串);//大寫字母轉小寫字母
char *_strlwr( char *string );
strupr(字串)//小寫字母轉大寫字母

在這里插入圖片描述
🔎strlwr:函式所在庫為string.h;函式引數為char*型別(需要被轉換成小寫的字串地址);函式回傳值為char*(回傳傳入字串地址),
在這里插入圖片描述

🔎strupr:函式所在庫為string.h;函式引數為char*型別(需要被轉換成大寫的字串地址);函式回傳值為char*(回傳傳入字串地址),

作用:
srtlwr將字串中大寫字母換成小寫字母,
strupr將字串中小寫字母換成大寫字母,

2.指標陣列與陣列指標

2.1指標陣列

指標陣列就是陣列元素型別為指標的陣列,

int* arr1[10]; //整形指標的陣列
char* arr2[40]; //一級字符指標的陣列
char** arr3[50];//二級字符指標的陣列

2.2陣列指標

陣列指標就是指向一個陣列的指標,要弄清楚陣列指標是什么,首先必須知道陣列指標是指標還是陣列,我們從概念名字上進行分析,就能知道它是指標而不是陣列,
我們以類比的方式來搞清楚陣列指標究竟是什么?
我們已經學習過整型指標int*,浮點數指標float* double*,我們以型別名+變數名的方式定義一個相應型別的指標,

a = 8;
b = 2.2;
int* pa = &a;//整型指標
double* pb = &b;//雙精度浮點型指標

同理陣列指標也是如此,不過需要與指標陣列區分開來

int* arr[10];//整型指標陣列,是一個陣列,存放了10個整型指標型別元素
int (*parr)[10];//這就是一個陣列指標,是不是和指標陣列有點像呢?
//因為[]優先級高于*,如果不加括號,變數名首先會與[]結合表示成一個陣列
//如果(*變數名),那變數名首先會與*結合就表示一個指標

int (*parr)[10]表示一個指標,指向一個資料型別為int元素個數為10的一個陣列,所以parr是一個陣列指標變數,

2.3陣列名與&陣列名

陣列名一般情況下指的是陣列首元素地址,與陣列名[0]等價,但是有二般情況,使用sizeof(陣列名),這里的陣列名指的是全陣列整體;&arr并不是指陣列名存放的地址的地址,而是指一個陣列整體的首地址,陣列名+1加的是該陣列存放元素的資料型別的大小,如果為int型別的陣列,那就是加4,而&arr+1加的是陣列整體的大小,如果一個int型別的陣列有10個元素,那就是加40,

3.陣列傳參與指標傳參

3.1陣列傳參

3.1.1一維陣列傳參

對于test1 test2函式形參可以這么寫呢?

#include <stdio.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int* arr2[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		arr2[i] = &arr1[i];
	}
	test1(arr1);
	test2(arr2);
	return 0;
}
//test1
 void test1(int arr[]);//方式1
 void test1(int arr[10]);//方式2
 void test1(int* arr);//方式3
//test2
void test2(int* arr[]);//方式1
void test2(int* arr[10]);//方式2
void test2(int** arr);//方式3

3.1.2二維陣列傳參

對于test函式形參可以這么寫呢?

#include <stdio.h>
int main()
{
	int arr[4][3] = { 0 };
	test(arr);
	return 0;
}
void test(int arr[4][3]);//方式1
void test(int arr[][3]);//方式2
void test(int arr[][]);//不能省略列數,錯誤
//對于二維陣列來說,每個元素指的是每一行,首元素指的是第一行陣列,所以可以使用陣列指標傳參
void test(int (*arr)[3]);//方式3

3.2指標傳參

3.2.1一級指標傳參

一個函式test(int* p)能接受什么引數?

int arr[10] = {0};
test(arr);//1.陣列名
int a = 10;
int* pa = &a;
test(pa);//或
test(&a);//2.一級指標

3.2.2二級指標傳參

一個函式test(int** p)能接受什么引數?

int n = 10;
int* p = &n;
int** pp = &p;
int* arr[10] = {0};
test(arr);//1.整型指標陣列
test(pp);
test(&p);//2.二級指標

4.函式指標與函式指標陣列

4.1函式指標

如果在程式中定義了一個函式,在編譯時會把函式的源代碼轉換為可執行代碼并分配一段存盤空間,這段記憶體空間有一個起始地址,也稱為函式的入口地址,每次呼叫函式時都從該地址入口開始執行此段函式代碼,
函式名就是函式的指標,它代表函式的起始地址,
函式名與陣列名有點相似,對函式名取地址得到的還是函式的地址,

#include <stdio.h>
void test()
{
	printf("hehe\n");
}
int main()
{
	printf("%p\n", test);
	printf("%p\n", &test);
	return 0;
}

💡運行結果:

004713B1
004713B1

D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 20032)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

可以定義一個指向函式的指標變數,用來存放某一函式的起始地址,這就意味著此指標變數指向該函式,例如:

int (*p)(int,int);

定義p是一個指向函式的指標變數,它可以指向函式型別為整型且有兩個整型引數的函式,此時,指標變數p的型別用int (*)(int,int)表示,

??函式指標定義通式:型別名 (*指標變數名)(函式引數表列)
??對于函式指標你要注意以下幾點:

🍋:定義指向函式的指標變數,并不意味著這個指標變數可以指向任何函式,它只能指向在定義時指定的型別的函式,
🍋:如果要用指標呼叫函式,必須先使指標變數指向該函式,
🍋:在給函式指標變數賦值時,只須給出函式名而不必給出引數,
🍋:用函式指標變數呼叫函式時,只須將(*p)代替函式名即可(p為指標變數名),在(*p)之后的括號中根據需要寫上實參,
🍋:對指向函式的指標變數不能進行算術運算,如p+n,p++,p–等運算是無意義的,
🍋:用函式名呼叫函式,只能呼叫所指定的一個函式,而通過指標變數呼叫函式比較靈活,可以根據不同情況先后呼叫不同的函式,
小栗子

#include <stdio.h>

int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int a = 2;
	int b = 6;
	int (*p)(int, int) = Add;
	int c = Add(a, b);
	int d = (*p)(a, b);
	printf("%d\n%d", c, d);
	return 0;
}

💡運行結果:

8
8
D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 21292)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

💡分析兩個有趣的代碼

#include <stdio.h>
int main()
{
	//代碼1 
	(*(void (*)())0)();
	//代碼2
	void (*signal(int, void(*)(int)))(int);
	return 0;
}

🔑代碼1:
void (*)()是一個引數為慷訓傳值為空的函式指標型別,(void (*)())0意思是將0強制轉換成這種指標型別,(* (void (*)())0)()解參考被轉換過的0執行在該地址的函式,
🔑代碼2:
定義了一個名為signal的函式,其中引數為整型int和引數為int 回傳值為空的函式指標void(*)(int),回傳值為void (*)(int)型別的函式指標,
可以使用typedef將這個代碼簡化:

typedef void (*pf)(int)
void (*signal(int, void(*)(int)))(int);
//相當于
pf signal(int, pf);

4.2函式指標陣列及其在計算器的應用

//函式指標
int (*func)(int, int);
//指標陣列
int* arr[10];
//函式指標陣列
int (*funcarr[10])(int, int);
//函式指標陣列的指標
int (*(*pfuncarr)[10])(int, int);

函式指標陣列用途:轉移表

🌽栗子:整型加減乘除計算器

選單及其加減乘除函式

#include <stdio.h>
void menu()
{
	printf("**********************************\n");
	printf("**********************************\n");
	printf("*******        1.add       *******\n");
	printf("*******        2.sub       *******\n");
	printf("*******        3.mul       *******\n");
	printf("*******        4.div       *******\n");
	printf("*******        0.exit      *******\n");
	printf("**********************************\n");
	printf("**********************************\n");

	
}
int Add(int x, int y)//int (*)(int, int)
{
	return x + y;
}

int Sub(int x, int y)//int (*)(int, int)
{
	return x - y;
}

int Mul(int x, int y)//int (*)(int, int)
{
	return x * y;
}

int Div(int x, int y)//int (*)(int, int)
{
	return x / y;
}

void Calc(int(*pf)(int, int))
{
	int x = 0;
	int y = 0;
	int ret = 0;

	printf("請輸入2個運算元:>");
	scanf("%d %d", &x, &y);
	ret = pf(x, y);
	printf("ret = %d\n", ret);
}

1.使用函式指標傳參實作

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Calc(Add);
			break;
		case 2:
			Calc(Sub);
			break;
		case 3:
			Calc(Mul);
			break;
		case 4:
			Calc(Div);
			break;
		case 0:
			printf("退出計算器\n");
			break;
		default:
			printf("選擇錯誤\n");
			break;
		}
	} while (input);
	return 0;
}

💡運行結果:

**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>1
請輸入2個運算元:>2 3
ret = 5
**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>3
請輸入2個運算元:>2 3
ret = 6
**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>0
退出計算器

D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 7012)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

2.使用函式指標陣列實作

int main()
{
	int input = 0;
	do
	{
		int x = 0;
		int y = 0;
		int ret = 0;
		menu();
		printf("請選擇:>");//1
		scanf("%d", &input);

		int (*pfArr[5])(int, int) = {0, Add, Sub, Mul, Div};
		                            //0   1   2    3    4
		if (input == 0)
		{
			printf("退出計算器\n");
		}
		else if(input>=1 && input<=4)
		{
			printf("請輸入2個運算元:>");
			scanf("%d %d", &x, &y);
			ret = pfArr[input](x, y);
			printf("%d\n", ret);
		}
		else
		{
			printf("選擇錯誤\n");
		}
	} while (input);
	return 0;
}

💡運行結果:

**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>1
請輸入2個運算元:>2 3
5
**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>3
請輸入2個運算元:>2 3
6
**********************************
**********************************
*******        1.add       *******
*******        2.sub       *******
*******        3.mul       *******
*******        4.div       *******
*******        0.exit      *******
**********************************
**********************************
請選擇:>0
退出計算器

D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (行程 16872)已退出,代碼為 0,
按任意鍵關閉此視窗. . .

5.回呼函式

回呼函式就是一個通過函式指標呼叫的函式,如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回呼函式,回呼函式不是由該函式的實作方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用于對該事件或條件進行回應,
比如上述計算器中的Calc函式,這個函式通過傳入的函式指標,去找到Add Sub Mul Div中的一個函式并呼叫它,

int Add(int x, int y)//int (*)(int, int)
{
	return x + y;
}

int Sub(int x, int y)//int (*)(int, int)
{
	return x - y;
}

int Mul(int x, int y)//int (*)(int, int)
{
	return x * y;
}

int Div(int x, int y)//int (*)(int, int)
{
	return x / y;
}

void Calc(int(*pf)(int, int))
{
	int x = 0;
	int y = 0;
	int ret = 0;

	printf("請輸入2個運算元:>");
	scanf("%d %d", &x, &y);
	ret = pf(x, y);//通過函式指標回傳呼叫呼叫加減乘除函式
	printf("ret = %d\n", ret);
}
覺得文章寫得不錯的老鐵們,點贊評論關注走一波!謝謝啦!

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293773.html

標籤:其他

上一篇:每公里配速9分18秒,雙足機器人完成5公里慢跑

下一篇:標準對話框

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more