【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/161362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/161362.shtml
英文地址,請注明出處:http://en.pswp.cn/news/161362.shtml

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

相關文章

帝國cms開發一個泛知識類的小程序的歷程記錄

#帝國cms小程序# 要開發一個泛知識類的小程序&#xff0c;要解決以下幾個問題。 1。知識內容的分類。 2。知識內容的內容展示。 3。知識內容的價格設置。 4。用戶體系&#xff0c;為簡化用戶的操作&#xff0c;在用戶進行下載的時候&#xff0c;請用戶輸入手機號&#xff…

【HarmonyOS】API6上JS實現視頻播放全屏播放時,會回到之前界面

【關鍵字】 API6 / 視頻播放 / 全屏播放異常 【問題現象】 開發者在API6上用JS實現視頻播放器點全屏播放后&#xff0c;不是全屏效果&#xff0c;實際效果是變成了橫屏并返回到首頁。 具體代碼實現是參考video媒體組件指南。 【問題分析】 JS實現視頻播放器有Codelab代碼示…

DedeBIZ 管理系統 DedeV6 v6.2.6 社區版 免費授權版

DedeBIZ 系統&#xff1a;開源、安全、高效的 DedeV6 v6.2.6 社區版 DedeBIZ 系統是基于 PHP 7 版本開發的&#xff0c;具有強大的可擴展性&#xff0c;并且完全開放源代碼。它采用現流行的 Go 語言設計開發&#xff0c;不僅擁有簡單易用、靈活擴展的特性&#xff0c;還具備更…

ElasticSearch之Health API

查看當前集群全部健康指標的信息&#xff0c;執行如下命令&#xff1a; curl -X GET "https://localhost:9200/_health_report?pretty" --cacert $ES_HOME/config/certs/http_ca.crt -u "elastic:ohCxPHQBEs5*lo7F9"執行結果輸出如下&#xff1a; {&quo…

Niushop 開源商城 v5.1.7:支持PC、手機、小程序和APP多端電商的源碼

Niushop 系統是一款基于 ThinkPHP6 開發的電商系統&#xff0c;提供了豐富的功能和完善的商品機制。該系統支持普通商品和虛擬商品&#xff0c;并且針對虛擬商品還提供了完善的核銷機制。同時&#xff0c;它也支持新時代的商業模式&#xff0c;如拼團、分銷和多門店砍價等營銷活…

Platform Issues 平臺問題

Set processing does not behave the same on every database platform. On some platforms, set processing can encounter performance breakdowns. Some platforms do not optimize update statements that include subqueries. 集處理在每個數據庫平臺上的行為并不相同。在…

Log4j

通過Log4j&#xff0c;我們可以控制日志信息輸送到目的地是控制臺、文件、GUI組件&#xff0c;甚至是套接口服務器、NT的事件記錄器。我們可以控制每一條日志的輸出格式。通過定義每一條日志信息的級別&#xff0c;能更加細致地控制日志的生成過程。 1 log4j、log4j2與SLF4J …

【Vue3從入門到項目實現】前置知識及Vue基礎

概念 理論基礎 MVC 架構&#xff08;以JavaWeb舉例&#xff09; M &#xff1a;Model&#xff0c;&#xff08;pojo、service、dao等&#xff09;V &#xff1a;View&#xff0c;&#xff08;JSP, HTML等&#xff09;C&#xff1a;Controller (servlet) MVVC 架構&#xff…

C/C++ 使用API實現數據壓縮與解壓縮

在Windows編程中&#xff0c;經常會遇到需要對數據進行壓縮和解壓縮的情況&#xff0c;數據壓縮是一種常見的優化手段&#xff0c;能夠減小數據的存儲空間并提高傳輸效率。Windows提供了這些API函數&#xff0c;本文將深入探討使用Windows API進行數據壓縮與解壓縮的過程&#…

【Rust日報】2023-11-21 如何將 Rust 的編譯效率提高 75%

這是一篇來自 https://benw.is/posts/how-i-improved-my-rust-compile-times-by-seventy-five-percent 的總結和翻譯&#xff0c;我去掉了一些不太重要的章節&#xff0c;保留了所有關鍵技術點。 Rust經常被提到的一個痛點是編譯時間較慢。為了享受借用檢查器、安全性和零成本抽…

pikachu靶場Table pikachu.member doesn’t exist:解決

背景&#xff1a; 第一次搭建pikachu靶場&#xff0c;搭建好后訪問index.php后&#xff0c;嘗試練習&#xff0c;發現界面顯示Table pikachu.member doesn t exist&#xff0c;后來找了很多教程&#xff0c;沒有解決&#xff0c;后來發現是自己沒有進行初始化&#xff0c;給大家…

VMware 系列:ESXI6.7升級7.0

ESXI6.7升級7.0 一、下載補丁二、上傳文件三 啟用Shell四、登錄Shell后臺五、刪除不兼容驅動六、正常升級最近,將一臺使用ESXI6.7的虛擬機升級到了7.0版本,下面記錄一下自己的升級過程。 升級條件 首先確保硬件是否能升級到7.0版本,物理網卡驅動為e1000e不能升級,如果是ig…

不到十個例題帶你拿下c++雙指針算法(leetcode)

移動零問題 https://leetcode.cn/problems/move-zeroes/submissions/ 1.題目解析 必須在原數組進行修改&#xff0c;不可以新建一個數組 非零元素相對順序不變 2.算法原理 【數組劃分】【數組分塊】 這一類題會給我們一個數組&#xff0c;讓我們劃分區間&#xff0c;比如…

【機器學習】Nonlinear Independent Component Analysis - Aapo Hyv?rinen

Linear independent component analysis (ICA) x i ( k ) ∑ j 1 n a i j s j ( k ) for all i 1 … n , k 1 … K ( ) x_i(k) \sum_{j1}^{n} a_{ij}s_j(k) \quad \text{for all } i 1 \ldots n, k 1 \ldots K \tag{} xi?(k)j1∑n?aij?sj?(k)for all i1…n,k1…K()…

VUE語法-$refs和ref屬性的使用

1、$refs和ref屬性的使用 1、$refs:一個包含 DOM 元素和組件實例的對象&#xff0c;通過模板引用注冊。 2、ref實際上獲取元素的DOM節點 3、如果需要在Vue中操作DOM我們可以通過ref和$refs這兩個來實現 總結:$refs可以獲取被ref屬性修飾的元素的相關信息。 1.1、$refs和re…

PS_魔幻

首先打開一個背景圖片 然后ctrl j復制一層背景 在調整中將圖片改成黑白顏色 點擊調整中的 色相/飽和度 調整明度 點擊畫筆工具&#xff0c;并且設置畫筆模板 調節畫筆大小&#xff0c;將筆記本電腦涂個概況 然后再新建色相/飽和度 勾選著色 調節背景顏色至喜歡 右鍵混合選項 …

04-React腳手架 集成Axios

初始化React腳手架 前期準備 1.腳手架: 用來幫助程序員快速創建一個基于xxx庫的模板項目 1.包含了所有需要的配置&#xff08;語法檢查、jsx編譯、devServer…&#xff09;2.下載好了所有相關的依賴3.可以直接運行一個簡單效果 2.react提供了一個用于創建react項目的腳手架庫…

【華為OD機試python】分糖果【2023 B卷|100分】

【華為OD機試】-真題 !!點這里!! 【華為OD機試】真題考點分類 !!點這里 !! 題目描述 小明從糖果盒中隨意抓一把糖果,每次小明會取出一半的糖果分給同學們。 當糖果不能平均分配時,小明可以選擇從糖果盒中(假設盒中糖果足夠) 取出一個糖果或放回一個糖果。 小明最少需要多…

【喵叔閑扯】---小談靜態類和單例模式

靜態類&#xff08;Static Class&#xff09;和單例&#xff08;Singleton&#xff09;都是在編程中用于實現特定類型的設計模式或代碼組織方式。它們在不同的情境下有不同的用途和特點。 靜態類&#xff08;Static Class&#xff09; 靜態類是一種類&#xff0c;它的方法和屬性…

一鍵去水印免費網站快速無痕處理圖片、視頻水印

水印問題往往是一個大麻煩。即使我們只想將這些照片保留在我們的個人相冊中以供懷舊&#xff0c;水印也可能像頑固的符號一樣刺激我們的眼睛。為了解決這個問題&#xff0c;我們需要不斷探索創新的解決方案&#xff0c;讓我們深入研究一款強大的一鍵去水印免費網站“水印云”。…