【C語言】深入解開指針(四)

  🌈write in front :

🔍個人主頁 : @啊森要自信的主頁

??真正相信奇跡的家伙,本身和奇跡一樣了不起啊!

歡迎大家關注🔍點贊👍收藏??留言📝>希望看完我的文章對你有小小的幫助,如有錯誤,可以指出,讓我們一起探討學習交流,一起加油鴨。 請添加圖片描述

文章目錄

  • 前言
  • 一、🚣 字符指針變量
  • 二、?? 數組指針變量
    • 2.1 數組指針變量是什么?
    • 2.2 數組指針變量怎么初始化
  • 三、???維數組傳參的本質
  • 四、🚤函數指針變量
    • 4.1 函數指針變量的創建
    • 4.2 函數指針變量的使?
    • 4.3 兩段有趣的代碼
      • 4.3.1 typedef關鍵字
  • 五、🚢函數指針數組
  • ??總結


前言

通過對前面指針的學習,你可能對指針有了一些理解,比如,數字名的理解,然后怎么使用指針來訪問數組,二級指針,指針數組 …

有了這些的理解,本小節我們繼續深入理解指針,啊森將會帶你理解字符指針變量,數組指針變量,二維數組傳參的本質,函數指針變量和函數指針數組,通過這些學習,我們最后來通過這些知識來實現轉移表,話不多說,讓我們啟航!


一、🚣 字符指針變量

在C語言中,字符指針變量是一種指向字符型數據的指針變量。它可以用來指向一個字符數組的首地址,也可以用來指向一個字符型變量的地址。
指針類型為字符指針 char*

字符指針變量的聲明和初始化如下所示:

char str[] = "Hello"; // 聲明一個字符數組
char *ptr; // 聲明一個字符指針變量
ptr = str; // 將字符數組的首地址賦給字符指針變量

通過字符指針變量可以訪問和操作字符數組中的元素,也可以通過指針運算來訪問字符串中的字符。例如:

int main()
{char str[] = "Hello";char* ptr;ptr = str;printf("%c\n", *ptr); // 輸出字符數組的第一個字符printf("%c\n", *(ptr + 1)); // 輸出字符數組的第二個字符return 0;
}

當然,以上是把字符串放在字符數組里面,不過我們可不可以把字符串直接放在指針里面呢?當然可以!

int main()
{const char* pa = "hello,world";//這?是把?個字符串放到pa指針變量?了嗎?printf("%s\n", pa);return 0;
}

思考:這?是把?個字符串放到pa指針變量?了嗎?

當然不是!
–>代碼 const char* pa = "hello,world"; 特別容易讓同學以為是把字符串 hello,world
到字符指針 pa ?了,但是本質是把字符串 hello,world. ?字符的地址放到了pa中。

在這里插入圖片描述

這個是內存布局,"hello,world"是一個字符串常量,它的值存儲在內存中,而pa是一個指向這個字符串常量的指針,它的值是字符串常量的地址。所以pa存儲的值是104,也就是"hello,world"的第一個字符的ASCII碼值,以此我們就可以通過第一個字符串常量的地址遍歷后面的字符,順藤摸瓜的找到字符"\0"才停止。

總結:代碼的意思是把?個常量字符串的?字符 h 的地址存放到指針變量 pa 中。
在這里插入圖片描述

《劍指Offer》中收錄了一道和字符串相關的筆試題,讓我們一起來學習一下:

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

在這里插入圖片描述
這個代碼打印結果不一樣的原因是:

  1. str1str2 是字符數組,它們分別用"hello bit."初始化了兩個不同的數組。雖然內容相同,但它們占用的內存地址是不同的,所以str1 == str2 判斷為不相等,打印"str1 and str2 are not same"。

  2. str3str4 是字符指針,它們都指向同一個字符串常量"hello bit."字符串常量存儲在只讀內存區域,無論如何定義,它們的地址是相同的。所以str3 == str4 判斷為相等,打印"str3 and str4 are same"。

換句話說:

- 字符數組比較地址,地址不同就不相等。

- 字符串常量比較內容,內容相同就相等。

所以結果不同的原因是str1、str2是數組,str3、str4是指針,它們的比較規則不同。

如果將str3和str4也定義為字符數組,則它們的比較結果也會是不相等,打印"str3 and str4 are not same"。

二、?? 數組指針變量

2.1 數組指針變量是什么?

之前我們學習了指針數組,指針數組是?種數組,數組中存放的是地址(指針)。
數組指針變量是指針變量?還是數組?

答案是:指針變量。
我們已經熟悉:
? 整形指針變量int * pa; 存放的是整形變量的地址,能夠指向整形數據的指針。
? 浮點型指針變量float * pf; 存放浮點型變量的地址,能夠指向浮點型數據的指針。

那數組指針變量應該是:存放的應該是數組的地址,能夠指向數組的指針變量。
下?代碼哪個是數組指針變量?

在這里插入圖片描述
那數組指針變量應該是:存放的應該是數組的地址,能夠指向數組的指針變量。
下?代碼哪個是數組指針變量?

 1. int *p1[10];2. int (*p2)[10];

思考?下:p1, p2分別是什么?
在這里插入圖片描述
數組指針變量
數組指針變量

1 int (*p)[10];

解釋:p先和*結合,說明p是?個指針變量變量,然后指著指向的是?個??為10個整型的數組。所以
p是?個指針,指向?個數組,叫 數組指針
這?要注意:[]的優先級要?于 * 號的,所以必須加上 () 來保證p先和 * 結合。

2.2 數組指針變量怎么初始化

數組指針變量是?來存放數組地址的,那怎么獲得數組的地址呢?就是我們之前學習的 &數組名

int arr[10] = {0};
&arr;//得到的就是數組的地址

如果要存放個數組的地址,就得存放在數組指針變量中,如下:

1 int(*p)[10] = &arr;

在這里插入圖片描述
我們調試也能看到 &arrp 的類型是完全?致的。
數組指針類型解析:

1. int    (*p)    [10] = &arr;2.  |       |       |3.  |       |       |4.  |       |       p指向數組的元素個數5.  |       p是數組指針變量名6.  p指向的數組的元素類型

三、???維數組傳參的本質

有了數組指針的理解,我們就能夠講?下?維數組傳參的本質了。
過去我們有?個?維數組的需要傳參給?個函數的時候,我們是這樣寫的:

#include <stdio.h>
void test(int a[3][5], int r, int c)
{int i = 0;int j = 0;for (i = 0; i < r; i++){for (j = 0; j < c; j++){printf("%d ", a[i][j]);}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}

在這里插入圖片描述
C語言二維數組傳參的本質是:

二維數組在傳參時會自動退化為一維數組指針。

具體來說:

  • 二維數組名代表整個二維數組,它其實就是一維數組指針,指向該數組的首行地址。

  • 當二維數組作為參數傳遞給函數時,它會自動退化為一維數組指針。

  • 函數內部無法得知傳入的參數原本是二維數組,它只能看到一個一維數組指針。

舉個例子:

void func(int arr[][3]) 
{// arr在這里實際類型是int (*arr)[3]  
}int main() 
{int a[4][3] = {0};func(a); // a傳參時自動退化為一維數組指針return 0;
}

這里a是二維數組,但傳給func函數時,func內部的arr參數實際上是一個指向int[3]類型一維數組的指針。

所以二維數組傳參的本質,就是自動退化為一維數組指針。

數組指針變量,它也可以指向二維數組首行地址,從而實現對二維數組的操作。

例如:

int (*ptr)[3] = a; // ptr指向a二維數組的首行

所以二維數組傳參本質是退化為一維數組指針,而數組指針變量也可以指向二維數組,兩者聯系在一起,都可以看作是一維數組指針來操作二維數組。

那我們就來試試數組指針變量來遍歷數組吧---------->

?先我們再次理解?下?維數組,?維數組起始可以看做是每個元素是?維數組的數組,也就是?維數組的每個元素是?個?維數組。那么?維數組的?元素就是第??,是個?維數組。
如下圖:
在這里插入圖片描述

根據數組名是數組首元素的地址這個規則,二維數組的數組名表示的就是第一行的地址,是一維數組的地址。
根據上面的例子,第一行的一維數組的類型就是 int [5] ,所以第一行的地址的類型就是數組指針類型 int(*)[5] 。那就意味著二維數組傳參本質上也是傳遞了地址傳遞的是第一行這個一維數組的地址,那么形參也是可以寫成指針形式的。如下:

#include <stdio.h>
void test(int(*p)[5], int r, int c)
{int i = 0;int j = 0;for (i = 0; i < r; i++){for (j = 0; j < c; j++){printf("%d ", *(*(p + i) + j));}printf("\n");}
}
int main()
{int arr[3][5] = { {1,2,3,4,5}, {2,3,4,5,6},{3,4,5,6,7} };test(arr, 3, 5);return 0;
}

在這里插入圖片描述

總結:?維數組傳參,形參的部分可以寫成數組,也可以寫成指針形式。

四、🚤函數指針變量

4.1 函數指針變量的創建

類比一下:
數組指針變量應該是:存放的應該是數組的地址,能夠指向數組的指針變量。
C語言中的函數指針變量是指向函數的指針變量。

函數指針變量的定義格式是:

返回類型 (*變量名)(參數類型列表);

例如:

int (*ptr)(int, char); // ptr是一個指向返回類型為int,參數為int和char的函數的指針

函數指針變量和普通指針變量一樣,它也需要指向具體的函數地址才能調用該函數。

例如:

int func(int a, char b) 
{return a + b;
}int main() 
{int (*ptr)(int, char); // 函數指針變量聲明ptr = func; // 指向func函數ptr(10, 'a'); // 通過函數指針調用func函數return 0;
}

函數指針變量的主要特點:

  • 可以指向不同類型的函數
  • 通過它可以調用被指向的函數
  • 可以作為函數參數或返回值進行傳遞
  • 常用在回調函數機制中

函數指針變量是用來存放函數地址的,通過這個地址可以調用函數。函數確實有地址!

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

輸出:
在這里插入圖片描述
確實打印出來了地址,所以函數是有地址的,函數名就是函數的地址,當然也可以通過 &函數名 的?式獲得函數的地址。
如果我們要將函數的地址存放起來,就得創建函數指針變量咯,函數指針變量的寫法其實和數組指針?常類似。如下:

void print()
{printf("lalala\n");
}
void (*pf1)() = &print;
void (*pf2)() = print;int Add(int x, int y)
{return x + y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add;//x和y寫上或者省略都是可以的
1. int      (*pf3)       (int x, int y)2.  |          |              ------------3.  |          |                      |4.  |          |                     pf3指向函數的參數類型和個數的交代5.  |         函數指針變量名6.  pf3指向函數的返回類型7. 8.  int (*) (int x, int y) //pf3函數指針變量的類型

看到這里,你可能會發現數組指針變量和函數指針變量其實好像也是差別不大呀!

4.2 函數指針變量的使?

通過函數指針調?指針指向的函數。

#include <stdio.h>
int Add(int x, int y)
{return x + y;
}
int main()
{int(*pf3)(int, int) = Add;printf("%d\n", (*pf3)(1, 2));printf("%d\n", pf3(3, 4));return 0;
}

在這里插入圖片描述
代碼輸出的結果是一樣的,為什么這兩種方式都可以呢?
解釋:
首先, pf3是一個函數指針變量,它指向Add函數。

在C語言中,函數指針與一般指針運算方式是一致的。

也就是說,對函數指針進行解引用(*pf3)后的結果,就是被指向的函數本身。

所以:

- (*pf3)(1, 2)
- 等價于 解引用pf3,得到Add函數,然后調用Add(1, 2)

- pf3(3, 4)
- 等價于 調用函數指針pf3,它指向的函數Add(3, 4)

兩者調用的函數都是Add,參數也一致,所以結果是相同的。

函數指針與一般指針在語法上表現形式不同,但本質上都是指向函數地址的指針。所以對函數指針進行解引用或直接調用效果是一致的。

因此上述代碼兩種打印方式結果相同,原因就是函數指針與普通指針在語法和語義上是一致的。

4.3 兩段有趣的代碼

注:兩段代碼均出?:《C陷阱和缺陷》這本書
在這里插入圖片描述

代碼1

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

讓我們分析一下:

  1. (void (*)())0 意思是把0這個整數值,強制類型轉換成一個地址,這個函數沒有參數,返回類型是void。

  2. *操作符對它進行解引用,得到void ()類型的匿名函數。

  3. 對這個匿名函數進行調用(),也就是調用0地址處的地址

所以整個表達式:

(void (*)())0 - 獲取函數指針,指向0地址

    • 解引用函數指針,得到匿名函數
      () - 調用匿名函數

換句話說,這個代碼是:

獲取一個指向0地址的函數指針,然后解引用它得到一個匿名函數,并對這個匿名函數進行調用。

由于指針指向0地址,實際調用的是內核NULL地址下的代碼。這通常會觸發異常或者崩潰。

所以這個代碼展示了一個通過函數指針調用匿名函數的語法,它實際上是在嘗試訪問空指針下的代碼從而觸發錯誤。

代碼2

1 void (*signal(int , void(*)(int)))(int);

精簡理解:

  1. 首先上述代碼是函數聲明
  2. signal是一個函數
  3. signal函數的參數有2個,第一個是int類型
  4. 第二個是函數指針類型,該指針指向的函數參數是int,返回類型是void
  5. signal函數的返回類型是這種類型的void(*)(int)函數指針
  6. 該指針指向的函數參數是int,返回類型是void

細節分析拓展如下:
此時注意signal并沒有與前面的*用括號結合 這個代碼定義了一個signal函數,它的功能是設置信號處理函數。

  1. void(*)(int) 定義了一個函數指針,該函數指針指向一個返回void,接受一個int參數的函數。

  2. signal是函數名,它有兩個參數:

    • int: 表示信號編號

    • void(*)(int): 函數指針,表示要設置的信號處理函數

  3. signal函數的返回值是一個函數指針:void (*)(int)

  4. 這個返回值函數指針也指向一個返回void,接受一個int參數的函數。

所以整個函數聲明可以解釋為:

signal函數用于設置信號處理函數。它接收兩個參數:

  • 信號編號
  • 要設置的信號處理函數

signal函數返回原來的信號處理函數。

所以這個函數聲明定義了一個典型的設置信號處理函數的接口 - signal(),它可以用來設置和獲取信號的處理回調函數。
**總結來說:**這個函數聲明使用了嵌套的函數指針定義了signal函數的接口格式,目的是為了設置和獲取信號處理回調函數。

4.3.1 typedef關鍵字

當你看到了這里,你可能在想,這么長void (*signal(int , void(*)(int)))(int);的代碼,寫出來真麻煩,有沒有辦法可以簡化他的長度呢,看起來可觀,容易理解呢?可不能自己寫著寫著把自己轉忽悠了哈哈哈。
當然!
typedef 是?來類型重命名的,可以將復雜的類型,簡單化。
C語言中的typedef主要用于定義類型別名。

typedef語法:

typedef 舊類型名 新類型名;

例如:

typedef int Int; 

這行代碼定義Intint類型的別名。

typedef的主要用途:

  1. 為復雜類型定義簡短的名稱
    比如定義指針、函數指針等:
typedef int (*FuncPtr)(int);
  1. 隱藏實現細節

比如用結構體指針替換結構體:

typedef struct {int x;int y;
} Point;typedef Point* PointPtr;
  1. 向下兼容

如果需要修改類型定義,可以使用typedef避免修改大量代碼。

  1. 提高代碼可讀性

給類型起個有意義的名稱,比如用Person替換struct Person。

  1. 標準庫也廣泛使用typedef

size_tptrdiff_t等標準類型都是通過typedef定義的。

所以總體來說,typedef主要用于為類型起別名,簡化和隱藏類型,提高代碼可讀性和兼容性。它廣泛應用于C標準庫和程序開發中。
本小節由于篇幅有限,我們先講第一點:

?如我們有數組指針類型 int(*)[5] ,需要重命名為 parr_t ,那可以這樣寫:

1 typedef int(*parr_t)[5]; //新的類型名必須在*的右邊

函數指針類型的重命名也是?樣的,?如,將 void(*)(int) 類型重命名為 pf_t ,就可以這樣寫:

1 typedef void(*pfun_t)(int);//新的類型名必須在*的右邊

那么要簡化代碼2,可以這樣寫:

typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

五、🚢函數指針數組

在這里插入圖片描述

數組是?個存放相同類型數據的存儲空間,我們已經學習了指針數組,
?如:

int *arr[10];
//數組的每個元素是int*

那要把函數的地址存到?個數組中,那這個數組就叫函數指針數組,那函數指針的數組如何定義呢?

這三個捏個才是正確的呢?int (*parr1[3])();
int *parr2[3]();
int (*)() parr3[3];

答案是:parr1
parr1 先和 [] 結合,說明 parr1是數組,數組的內容是什么呢?
是 int (*)() 類型的函數指針。
這個定義相當于:

  • 定義一個函數指針數組parr1
  • 數組長度為3
  • 每個元素都是一個函數指針
  • 指向一個返回int,無參數的函數

這里給出一個C語言函數指針數組的簡單實現示例:

// 定義函數原型
int func1(void);
int func2(void);int func1(void)
{printf("func1 called\n");return 0;
}int func2(void)
{printf("func2 called\n");return 0;
}int main()
{// 定義函數指針數組,可以存儲2個函數指針int (*funcPtrArr[2])(void);// 初始化函數指針數組元素funcPtrArr[0] = func1;funcPtrArr[1] = func2;// 通過索引調用函數指針數組元素指向的函數funcPtrArr[0]();funcPtrArr[1]();return 0;
}

輸出結果為:
在這里插入圖片描述
主要實現步驟

  1. 定義函數原型
  2. 定義函數指針數組
  3. 初始化數組元素,使每個元素指向對應的函數
  4. 通過數組索引,調用函數指針指向的函數

這個示例演示了如何定義和使用函數指針數組來管理和調用多個函數。

實際應用中,可以通過函數指針數組實現回調函數、插件等機制。函數也可以作為參數傳遞給其他函數。

總之,函數指針數組提供了一種靈活高效的方式來管理和調用多個函數在C語言中。怎么高效?下一屆我們做一個計算器,轉移表就可以清楚理解他的巧妙之處!

??總結

一、字符指針變量
字符指針變量用來存儲字符串,可以通過字符指針訪問字符串中的每個字符。

二、數組指針變量
2.1 數組指針變量實際指向數組第一個元素的地址。
2.2 可以通過數組名直接初始化數組指針,也可以通過地址運算符&初始化。

三、二維數組傳參的本質
二維數組傳參實際上是傳一級指針,等同于傳數組指針。

四、函數指針變量
4.1 通過函數原型聲明函數指針變量類型,并使用地址運算符&初始化。
4.2 通過函數指針調用函數,等同于使用普通函數名調用。
4.3 typedef可以簡化函數指針變量類型定義。

五、函數指針數組
函數指針數組可以存儲和管理多個函數指針,通過數組索引調用不同函數。

總之,C語言指針變量提供了一種靈活的方式來操作和管理數據,如字符串、數組、函數等。指針變量的概念和使用需要熟練掌握,它是C語言的重要知識點。感謝你的收看,如果文章有錯誤,可以指出,我不勝感激,讓我們一起學習交流,如果文章可以給你一個幫助,可以給博主點一個小小的贊😘

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/163101.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/163101.shtml
英文地址,請注明出處:http://en.pswp.cn/news/163101.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

centos7上用docker部署mysql 5.7,并解決中文亂碼問題

1. 安裝docker 查看這篇文章的前半部分即可&#xff1a; 虛擬機上安裝docker&#xff0c;并安裝flink鏡像 2. 安裝mysql 5.7 2.1 下載mysql鏡像 可以使用docker search mysql命令查看遠程鏡像倉庫中的鏡像信息&#xff0c;或者訪問dockerhub去找需要的鏡像 這里直接拉取鏡像…

ubuntu借助overlay方案實現重啟自動還原

配置重啟還原OS 首先&#xff1a;sudo apt install overlayroot 安裝一下軟件 然后編輯配置文件&#xff1a;/etc/overlayroot.conf * overlayroottmpfs or overlayroottmpfs:PARAMETERS write all changes to a temporary (ram only) backing device A tmpfs mount will …

ubuntu22.04安裝wvp-gb28181-pro 2023-11-23最新版本(一鍵安裝)

下載程序 輸入下面命令&#xff0c;輸入普通用戶密碼&#xff0c;切換到 root用戶 sudo su git clone -b ubuntu_wvp_online_install_2023_0425 https://gitcode.net/zenglg/ubuntu_wvp_online_install.git 等待下載完成 安裝 進入到克隆下來的路徑中 cd /home/tuners/ub…

萬界星空科技低代碼云MES系統

所謂“云MES”&#xff0c;它是基于MES管理云平臺儲存大數據運算而來&#xff0c;區別于一般管理系統&#xff0c;云MES操作運行不需要獨立的服務器去儲存和運行&#xff0c;而是通過云端進行數據、儲存、運行&#xff0c;最后將計算完的數據在MES系統上呈現&#xff0c;呈現端…

讓國內AI模型解題:滑動窗口中找出最大值,文心一言,通義千問錯誤率100%,訊飛星火略勝一籌

最近&#xff0c;一些大廠陸續放出了自己的AI模型&#xff0c;處于日常的使用和準確度&#xff0c;我通過一道試題來看一下文心一言、訊飛星火和通義千萬的回答結果 本道題是一道很經典的算法題&#xff0c;請在滑動窗口中找出最大值 文心一言 第一次給出答案 package main…

vue中v-if與v-for的優先級?

?&#x1f308;個人主頁&#xff1a;前端青山 &#x1f525;系列專欄&#xff1a;Vue篇 &#x1f516;人終將被年少不可得之物困其一生 依舊青山,本期給大家帶來vue篇專欄內容:vue中v-if與v-for的優先級? 目錄 v-if和v-for的優先級是什么&#xff1f; 一、作用 二、優先級…

移動機器人,開啟智能柔性制造新篇章

智能制造是當今工業發展的必然趨勢&#xff0c;而柔性制造則是智能制造的重要組成部分。在這個快速變革的時代&#xff0c;如何提高生產效率、降低成本、增強靈活性成為了制造業的關鍵挑戰。富唯智能移動機器人應運而生&#xff0c;為柔性制造注入了新的活力。 基于富唯智能AI-…

凸問題與非凸問題

凸函數&#xff1a;曲線上任意兩點連線上的點對應的函數值不大于該兩點對應的函數值得連線上的值&#xff0c;例如yx^2&#xff1b; 非凸函數&#xff1a;曲線上任意兩點連線上的點對應的函數值既有大于該兩點對應的函數值得連線上的值的部分也有小于的部分&#xff0c;例如&am…

Re51:讀論文 Language Models as Knowledge Bases?

諸神緘默不語-個人CSDN博文目錄 諸神緘默不語的論文閱讀筆記和分類 論文名稱&#xff1a;Language Models as Knowledge Bases? ArXiv網址&#xff1a;https://arxiv.org/abs/1909.01066 官方GitHub項目&#xff1a;https://github.com/facebookresearch/LAMA 本文是2019年…

軟件測試個人求職簡歷該怎么寫,模板在這里

1、個人資料 姓名&#xff1a;xxx性別&#xff1a;x 手機號碼&#xff1a;138888888xx郵箱&#xff1a;xxx 學歷&#xff1a;本科專業&#xff1a;電子商務 英語&#xff1a;四級當前工作&#xff1a;測試工程師 從業時間&#xff1a;4年期望薪資&#xff1a;面議 求職意向軟件…

FIB表與快速轉發表實驗

實驗名稱&#xff1a;FIB表與快速轉發表實驗 網絡拓撲圖&#xff1a; 實驗步驟&#xff1a; 1、配置接口的IP地址 R1&#xff1a; R2&#xff1a; 2、配置OSPF路由協議 在R1宣告網段 在R2宣告網段 3、查看鄰居狀態&#xff0c;一直處于2-way狀態&#xff0c;要等待30秒&…

SAP 權限設置維護

權限設置維護 su21 點擊創建自己的 對象類&#xff08;OBJECT CLASS &#xff09; Z... 在點擊創建授權對象 輸入對象名 z... 對象名文本 字段名&#xff1a;ACTVT 點擊允的許活 按鈕 里面增刪改查等權限.... 保存 .權限對象 保存后需要 pfcg 配置權限對象 分…

a標簽超鏈接 —— 實現點擊前中后變色

淺淺記錄下 <style type"text/css"> a:link {color: yellow; /*未訪問鏈接顏色*/ }a:visited {color: red; /*已訪問鏈接顏色*/ }a:hover {color: blue; /*鼠標移動到鏈接顏色*/text-decoration: underline; }a:active {color: orange; /*鼠標點擊時顏色*/ }a…

二叉樹:C++實現

引言&#xff1a; 二叉樹是一種常見的數據結構&#xff0c;它具有良好的適用性和靈活性&#xff0c;能夠應用于各種領域。在C中實現二叉樹可以通過使用模板類和結構體來實現。下面我們將介紹如何在C中實現二叉樹&#xff0c;并提供一些基本的操作方法。 技術實現&#xff1a; …

如何將音頻添加到視頻并替換視頻中的音軌

隨著視頻流媒體網站的流行和便攜式設備的發展&#xff0c;你可能越來越傾向于自己制作視頻并在互聯網上分享。有時&#xff0c;你可能還需要編輯視頻并為其添加背景音樂&#xff0c;因為音樂總是對視頻的感知起著神奇的作用。 那如何給視頻添加音頻呢&#xff1f;或者如何用新…

阿里云跨賬號建立局域網

最近有活動&#xff0c;和好友一并薅了下阿里云的羊毛。琢磨著兩臺機器組一個局域網&#xff0c;于是有了這個需求&#xff0c;把步驟記錄一下&#xff1a; 假設兩臺機器叫A和B&#xff0c;我們開始進行建立和組網 1. 建立ECS 把A機器公共環境裝好&#xff0c;然后使用《實例與…

深入解析Java 8中HashMap的底層原理

引言 HashMap是Java中常用的集合類&#xff0c;用于存儲鍵值對。其底層實現經過多次優化&#xff0c;包括哈希算法、數組擴容、鏈表轉紅黑樹等。本文將深入研究HashMap的底層原理&#xff0c;并詳細探討如何解決哈希碰撞的技術。 1. 哈希算法 HashMap的核心是哈希算法&#…

Day38:518.零錢兌換II、377. 組合總和 Ⅳ

文章目錄 518.零錢兌換II思路代碼實現 377. 組合總和 Ⅳ思路代碼實現 518.零錢兌換II 題目鏈接 思路 確定dp數組&#xff08;dp table&#xff09;以及下標的含義 dp[j]&#xff1a;組合元素和為j的組合方式確定遞推公式 題目不是選取最優解&#xff0c;而是求路徑總和&…

【運動規劃】191 自適應跟蹤kinodynamicrrt的路徑

分層法&#xff1a; two layer approach 自適應控制&#xff0c;跟隨軌跡。運動規劃&#xff1a;擴展自由空間&#xff08;基于速度約束縮小自由空間&#xff09;為控制部分留余量&#xff0c;確保安全。 控制設計&#xff1a; 考慮平移和旋轉&#xff0c;速度環控制&#xff…

銀河麒麟安裝Docker

# 配置阿里云 Centos8 鏡像源&#xff0c;需要額外的一些依賴&#xff0c;而這些依賴在麒麟官方的源里面是沒有的 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo# 配置阿里云 docker 鏡像源 sudo yum-config-manager --add-r…