C語言深度剖析書籍學習記錄 第四章 指針和數組

  • ?p 稱為指針變量,p 里存儲的內存地址處的內存稱為 p 所指向的內存。 指針變量 p 里存儲的任何數據都將被當作地址來處理
  • 一個基本的數據類型(包括結構體等自定義類型)加上“*” 號就構成了一個指針類型的模子。這個模子的大小是一定的,與“*”號前面的數據類型無 關。
  • “*”號前面的數據類型只是說明指針所指向的內存里存儲的數據類型。所以,在 32 位 系統下,不管什么樣的指針類型,其大小都為 4byte。可以測試一下 sizeof(void *)。
  • int *p = NULL;? 這時候通過編譯器查看 p 的值為 0x00000000。這句代碼的意思是:定義一個指針 變量 p,其指向的內存里面保存的是 int 類型的數據;
  • 在定義變量 p 的同時把 p 的值設置為 0x00000000,而不是把*p 的值設置為 0x00000000。
  • 這個過程叫做初始化,是在編譯的時候 進行的。避免野指針,指向一段關鍵數據的地址造成數據的損毀
  • int *p;? *p = NULL; 同樣,我們可以在編譯器上調試這兩行代碼。第一行代碼,定義了一個指針變量 p,其指向 的內存里面保存的是 int 類型的數據;但是這時候變量 p 本身的值是多少不得而知,也就是 說現在變量 p 保存的有可能是一個非法的地址。第二行代碼,給*p 賦值為 NULL,即給 p 指向的內存賦值為 NULL;但是由于 p 指向的內存可能是非法的,所以調試的時候編譯器可 能會報告一個內存訪問錯誤。這樣的話,我們可以把上面的代碼改寫改寫,使 p 指向一塊合 法的內存:
  • int i = 10; int *p = &i; *p = NULL;? 在編譯器上調試一下,我們發現 p 指向的內存由原來的 10 變為 0 了;而 p 本身的值, 即內存地址并沒有改變。經過上面的分析,相信你已經明白它們之間的區別了。不過這里還有一個問題需要注 意,也就是這個 NULL。初學者往往在這里犯錯誤。注意 NULL 就是 NULL,它被宏定義為 0:
    #define NULL 0
  • 很多系統下除了有 NULL 外,還有 NUL(Visual C++ 6.0 上提示說不認識 NUL)。NUL 是 ASCII 碼表的第一個字符,表示的是空字符,其 ASCII 碼值為 0。其值雖然都為 0,但表示的意思 完全不一樣。同樣,NULL 和 0 表示的意思也完全不一樣。一定不要混淆。
  • 另外還有初學者在使用 NULL 的時候誤寫成 null 或 Null 等。這些都是不正確的,C 語 言對大小寫十分敏感啊。當然,也確實有系統也定義了 null,其意思也與 NULL 沒有區別, 但是你千萬不用使用 null,這會影響你代碼的移植性。

將數值存儲到指定的內存地址

  • 假設現在需要往內存 0x12ff7c 地址上存入一個整型數 0x100。我們怎么才能做到呢?我 們知道可以通過一個指針向其指向的內存地址寫入數據,那么這里的內存地址 0x12ff7c 其 本質不就是一個指針嘛。所以我們可以用下面的方法:? ?int *p = (int *)0x12ff7c;? ?*p = 0x100;
  • 需要注意的是將地址 0x12ff7c 賦值給指針變量 p 的時候必須強制轉換。至于這里為什么選擇內存地址 0x12ff7c,而不選擇別的地址,比如 0xff00 等。這僅僅是為了方便在 Visual C++ 6.0 上測試而已。如果你選擇 0xff00,也許在執行*p = 0x100;這條語句的時候,編譯器 會報告一個內存訪問的錯誤,因為地址 0xff00 處的內存你可能并沒有權力去訪問。
  • 既然這 樣,我們怎么知道一個內存地址是可以合法的被訪問呢?也就是說你怎么知道地址 0x12ff7c 處的內存是可以被訪問的呢?其實這很簡單,我們可以先定義一個變量 i,比如:int i = 0;? 變量 i 所處的內存肯定是可以被訪問的。然后在編譯器的 watch 窗口上觀察&i 的值不就 知道其內存地址了么?這里我得到的地址是 0x12ff7c,僅此而已(不同的編譯器可能每次給 變量 i 分配的內存地址不一樣,而剛好 Visual C++ 6.0 每次都一樣)。你完全可以給任意一個 可以被合法訪問的地址賦值。得到這個地址后再把“int i = 0;”這句代碼刪除。
  • *(int *)0x12ff7c = 0x100;? 這行代碼其實和上面的兩行代碼沒有本質的區別。先將地址 0x12ff7c 強制轉換,告訴編譯 器這個地址上將存儲一個 int 類型的數據;然后通過鑰匙“*”向這塊內存寫入一個數據。

  • 如上圖所示,當我們定義一個數組 a 時,編譯器根據指定的元素個數和元素的類型分配確定 大小(元素類型大小*元素個數)的一塊內存,并把這塊內存的名字命名為 a。名字 a 一旦 與這塊內存匹配就不能被改變。a[0],a[1]等為 a 的元素,但并非元素的名字。數組的每一個 元素都是沒有名字的。那現在再來回答第一章講解 sizeof 關鍵字時的幾個問題:
  • sizeof(a)的值為 sizeof(int)*5,32 位系統下為 20。
  • sizeof(a[0])的值為 sizeof(int),32 位系統下為 4。
  • sizeof(a[5])的值在 32 位系統下為 4。并沒有出錯,為什么呢?我們講過 sizeof 是關鍵字 不是函數。函數求值是在運行的時候,而關鍵字 sizeof 求值是在編譯的時候。雖然并不存在 a[5]這個元素,但是這里也并沒有去真正訪問 a[5],而是僅僅根據數組元素的類型來確定其 值。所以這里使用 a[5]并不會出錯。
  • sizeof(&a[0])的值在 32 位系下為 4,這很好理解。取元素 a[0]的首地址。 sizeof(&a)的值在 32 位系統下也為 4,這也很好理解。取數組 a 的首地址
  • &a[0]和&a 的區別? ?a[0]是一個元素,a 是整個數組,雖然&a[0]和&a 的值一樣,但其意義不一樣。前者是數組首元素的首地址,而后者是數組的首地址。舉個 例子:湖南的省政府在長沙,而長沙的市政府也在長沙。兩個政府都在長沙,但其代表的 意義完全不同。這里也是同一個意思。?

數組名 a 作為左值和右值的區別

  • 簡單而言,出現在賦值符“=”右邊的就是右值,出現在賦值符“=”左邊的就是左值。? 比如,x=y。
  • 左值:在這個上下文環境中,編譯器認為 x 的含義是 x 所代表的地址。這個地址只有 編譯器知道,在編譯的時候確定,編譯器在一個特定的區域保存這個地址,我們完全不必考慮這個地址保存在哪里。
  • 右值:在這個上下文環境中,編譯器認為 y 的含義是 y 所代表的地址里面的內容。這 個內容是什么,只有到運行時才知道。
  • C 語言引入一個術語-----“可修改的左值”。意思就是,出現在賦值符左邊的符號所代 表的地址上的內容一定是可以被修改的。換句話說,就是我們只能給非只讀變量賦值。
  • 當 a 作為右值的時候代表的是什么意思呢?很多書認為是數組的首地址,其實這是非常 錯誤的。a 作為右值時其意義與&a[0]是一樣,代表的是數組首元素的首地址,而不是數組 的首地址。這是兩碼事。但是注意,這僅僅是代表,并沒有一個地方(這只是簡單的這么 認為,其具體實現細節不作過多討論)來存儲這個地址,也就是說編譯器并沒有為數組 a 分配一塊內存來存其地址,這一點就與指針有很大的差別。
  • a 不能作為左值!編譯器會認為數組名作為左值代表 的意思是 a 的首元素的首地址,但是這個地址開始的一塊內存是一個總體,我們只能訪問數組的某個元素而無法把數組當一個總體進行訪問。所以我們可以把 a[i]當左值,而無法把 a 當左值。其實我們完全可以把 a 當一個普通的變量來看,只不過這個變量內部分為很多小塊, 我們只能通過分別訪問這些小塊來達到訪問整個變量 a 的目的。
  • A),char *p = “abcdef”;
  • B),char a[] = “123456”;

以指針的形式訪問和以下標的形式訪問指針

  • 例子 A)定義了一個指針變量 p,p 本身在棧上占 4 個 byte,p 里存儲的是一塊內存的首地址。這塊內存在靜態區,其空間大小為 7 個 byte,這塊內存也沒有名字。對這塊內存的訪 問完全是匿名的訪問。比如現在需要讀取字符‘e’,我們有兩種方式:
  • 1),以指針的形式:*(p+4)。先取出 p 里存儲的地址值,假設為 0x0000FF00,然后加 上 4 個字符的偏移量,得到新的地址 0x0000FF04。然后取出 0x0000FF04 地址上的值。
  • 2),以下標的形式:p[4]。編譯器總是把以下標的形式的操作解析為以指針的形式的操作。p[4]這個操作會被解析成:先取出 p 里存儲的地址值,然后加上中括號中 4 個元素的偏 移量,計算出新的地址,然后從新的地址中取出值。也就是說以下標的形式訪問在本質上 與以指針的形式訪問沒有區別,只是寫法上不同罷了。
  • 偏移量的單位是元 素的個數而不是 byte 數

#include <iostream>int main(){int a[] = {1,2,3,4,5,6,7,8,9,10};int *ptr = (int*)(&a + 1);printf("%d,%d",*(a+1),*(ptr-1));
}
  • 對指針進行加 1 操作,得到的是下一個元素的地址,而不是原有地址值直接加 1。所以,一個類型為 T 的指針的移動,以 sizeof(T) 為移動單位。 因此,對上題來說,a 是一個一 維數組,數組中有 5 個元素; ptr 是一個 int 型的指針。?

  • 這就是為什么 extern char a[]與 extern char a[100]等價的原因。因為這只是聲明,不分配 空間,所以編譯器無需知道這個數組有多少個元素。這兩個聲明都告訴編譯器 a 是在別的文 件中被定義的一個數組,a 同時代表著數組 a 的首元素的首地址,也就是這塊內存的起始地 址。數組內地任何元素的的地址都只需要知道這個地址就可以計算出來。
  • 但是,當你聲明為 extern char *a 時,編譯器理所當然的認為 a 是一個指針變量,在 32 位系 統下,占 4 個 byte。這 4 個 byte 里保存了一個地址,這個地址上存的是字符類型數據。雖 然在文件 1 中,編譯器知道 a 是一個數組,但是在文件 2 中,編譯器并不知道這點。大多數 編譯器是按文件分別編譯的,編譯器只按照本文件中聲明的類型來處理。所以,雖然 a 實際 大小為 100 個 byte,但是在文件 2 中,編譯器認為 a 只占 4 個 byte。
  • 編譯器會把存在指針變量中的任何數據當作地址來處理。所以,如果需要 訪問這些字符類型數據,我們必須先從指針變量 a 中取出其保存的地址。如下圖:?

?

  • 在文件 1 中,編譯器分配 4 個 byte 空間,并命名為 p。同時 p 里保存了字符串常量“abcdefg” 的首字符的首地址。這個字符串常量本身保存在內存的靜態區,其內容不可更改。
  • 在文件 2 中,編譯器認為 p 是一個數組,其大小為 4 個 byte,數組內保存的是 char 類型的數據。
  • 在 文件 2 中使用 p 的過程如下圖:?

?

?指針數組和數組指針

  • 初學者總是分不出指針數組與數組指針的區別。其實很好理解:
  • 指針數組:首先它是一個數組,數組的元素都是指針,數組占多少個字節由數組本身 決定。它是“儲存指針的數組”的簡稱。
  • 數組指針:首先它是一個指針,它指向一個數組。在 32 位系統下永遠是占 4 個字節, 至于它指向的數組占多少字節,不知道。它是“指向數組的指針”的簡稱。
  • 下面到底哪個是數組指針,哪個是指針數組呢:
    • A),int *p1[10];? ? ? ? ?指針數組
    • B),int (*p2)[10];? ? ? ?數組指針
  • 這里需要明白一個符號之間的優先級問題。 “[]”的優先級比“*”要高。p1 先與“[]”結合,構成一個數組的定義,數組名為 p1,int * 修飾的是數組的內容,即數組的每個元素。那現在我們清楚,這是一個數組,其包含 10 個 指向 int 類型數據的指針,即指針數組。
  • 至于 p2 就更好理解了,在這里“()”的優先級比 “[]”高,“*”號和 p2 構成一個指針的定義,指針變量名為 p2,int 修飾的是數組的內容, 即數組的每個元素。數組在這里并沒有名字,是個匿名數組。那現在我們清楚 p2 是一個指 針,它指向一個包含 10 個 int 類型數據的數組,即數組指針。
  • 我們可以借助下面的圖加深 理解:

  • char a[5]={'A','B','C','D'};
  • char (*p3)[5] = &a;? ? ?正確
  • char (*p4)[5] = a;? ? ? ?需要類型轉換
  • &a 是整個數組的首地址,a 是數組首元素的首地址,其值相同但意義不同

?

  • ?根據上面的講解,&a+1 與 a+1 的區別已經清楚。
  • ptr1:將&a+1 的值強制轉換成 int*類型,賦值給 int* 類型的變量 ptr,ptr1 肯定指到數 組 a 的下一個 int 類型數據了。ptr1[-1]被解析成*(ptr1-1),即 ptr1 往后退 4 個 byte。所以其 值為 0x4。
  • ptr2:按照上面的講解,(int)a+1 的值是元素 a[0]的第二個字節的地址。然后把這個地址 強制轉換成 int*類型的值賦給 ptr2,也就是說*ptr2 的值應該為元素 a[0]的第二個字節開始的 連續4個byte的內容。
  • 其內存布局如下圖:

?

?

  • ?使用一個指針分配內存空間,復制數據
  • 在運行 strcpy(str,”hello”)語句的時候發生錯誤。這時候觀察 str 的值,發現仍然為 NULL。 也就是說 str 本身并沒有改變,我們 malloc 的內存的地址并沒有賦給 str,而是賦給了_str。 而這個_str 是編譯器自動分配和回收的,我們根本就無法使用。所以想這樣獲取一塊內存是 不行的。那怎么辦?
  • 兩個辦法: 使用return返回內存空間?
  • 使用二級指針

?

  • 注意,這里的參數是&str 而非 str。這樣的話傳遞過去的是 str 的地址,是一個值。在函 數內部,用鑰匙(“*”)來開鎖:*(&str),其值就是 str。所以 malloc 分配的內存地址是真正 賦值給了 str 本身。?

函數指針

  • char * (*fun1)(char * p1,char * p2);? ?fun1 指針變量指向的是一個函數

?

  • ?給函數指針賦值時,可以用&fun 或直接用函數名 fun。這是因為函數名被 編譯之后其實就是一個地址,所以這里兩種用法沒有本質的差別

*(int*)&p ----這是什么?

  • void (*p)();? ? 這行代碼定義了一個指針變量 p,p 指向一個函數,這個函數的參數和返回值都是 void。
  • &p 是求指針變量 p 本身的地址,這是一個 32 位的二進制常數(32 位系統)。
  • (int*)&p 表示將地址強制轉換成指向 int 類型數據的指針。
  • (int)Function 表示將函數的入口地址強制轉換成 int 類型的數據。
  • *(int*)&p=(int)Function;表示將函數的入口地址賦值給指針變量 p。
  • 那么(*p) ();就是表示對函數的調用。
  • 其實函數指針與普通指針沒什么差別,只是指向的內容不同而已。 使用函數指針的好處在于,可以將實現同一功能的多個模塊統一起來標識,這樣一來更
    容易后期的維護,系統結構更加清晰。或者歸納為:便于分層設計、利于系統抽象、降低耦 合度以及使接口與實現分開。

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

  • 第一步:void(*) (),可以明白這是一個函數指針類型。這個函數沒有參數,沒有返回值。
  • 第二步:(void(*) ())0,這是將 0 強制轉換為函數指針類型,0 是一個地址,也就是說一個函數存在首地址為 0 的一段區域內。
  • 第三步:(*(void(*) ())0),這是取 0 地址開始的一段內存里面的內容,其內容就是保存在首地址為 0 的一段區域內的函數。
  • 第四步:(*(void(*) ())0)(),這是函數調用。

函數指針數組??char * (*pf[3])(char * p);

  • 這是定義一個函數指針數組。它是一個數組,數組名為 pf,數組內存儲了 3 個指向函數的 指針。這些指針指向一些返回值類型為指向字符的指針、參數為一個指向字符的指針的函 數。這念起來似乎有點拗口。不過不要緊,關鍵是你明白這是一個指針數組,是數組

?

函數指針數組指針?char * (*(*pf)[3])(char * p);

  • 注意,這里的pf和上一節的pf就完全是兩碼事了。上一節的pf并非指針,而是一個數組名; 這里的 pf 確實是實實在在的指針。這個指針指向一個包含了 3 個元素的數組;這個數字里 面存的是指向函數的指針;這些指針指向一些返回值類型為指向字符的指針、參數為一個 指向字符的指針的函數。

?

?

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

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

相關文章

js中select下拉框重置_如何利用CSS3制作炫酷的下拉框

很多小伙伴都不清楚CSS3是做什么&#xff1f;用途是什么&#xff1f;接下來我就給展示一個css3制作一個炫酷下拉框。其實不只是這些&#xff0c;還有很多。CSS3是CSS(層疊樣式表)技術的升級版本&#xff0c;于1999年開始制訂&#xff0c;2001年5月23日W3C完成了CSS3的工作草案&…

select選擇框必輸校驗_輪子這么多,我們為什么選擇自研NewSQL

作者介紹李鑫&#xff0c;滴滴資深軟件開發工程師&#xff0c;多年分布式存儲領域設計及開發經驗。曾參與NoSQL/NewSQL數據庫Fusion、分布式時序數據庫sentry、NewSQL數據庫SDB等系統的設計開發工作。一、背景Fusion-NewSQL是由滴滴自研的在分布式KV存儲基礎上構建的NewSQL存儲…

C語言深度剖析書籍學習記錄 第五章 內存管理

常見的內存錯誤 定義了指針變量&#xff0c;但是沒有為指針分配內存&#xff0c;即指針沒有指向一塊合法的內存。 結構體成員指針未初始化 很多初學者犯了這個錯誤還不知道是怎么回事。這里定義了結構體變量 stu&#xff0c;但是他沒 想到這個結構體內部 char *name 這成員在定…

怎么改電腦網絡ip地址_拋棄重啟路由器獲取ip地址方式,巧妙運用ip代理改IP工具...

網絡是簡單的也是復雜的&#xff0c;在如此龐大的網絡世界里有太多的不確定因素&#xff0c;導致我們遇到IP限制問題&#xff0c;從而影響到我們的網絡訪問&#xff0c;而大家都知道&#xff0c;如果遇到ip被限制的問題&#xff0c;最快速直接的辦法就是把被限制的ip更換一個新…

C語言深度剖析書籍學習記錄 第六章 函數

函數的好處 1、降低復雜性:使用函數的最首要原因是為了降低程序的復雜性&#xff0c;可以使用函數來隱含信息&#xff0c;從而使你不必再考慮這些信息。2、避免重復代碼段:如果在兩個不同函數中的代碼很相似&#xff0c;這往往意味著分解工作有誤。這時&#xff0c;應該把兩個…

如何把word分裝到兩個byte_如何核對兩個Word文檔的內容差別?同事加班半小時,我只花了30秒...

昨天下班前&#xff0c;老板突然發了兩份Word文檔過來&#xff0c;一份是原稿&#xff0c;還有一份是修訂稿&#xff0c;叫我們找出兩份文檔的內容差別之處&#xff0c;我只花了30秒就搞定了&#xff0c;然后準時下班&#xff01;你想知道我是怎么操作的嗎&#xff1f;下面小源…

stm32f767中文手冊_ALIENTEK 阿波羅 STM32F767 開發板資料連載第五章 SYSTEM 文件夾

1)實驗平臺&#xff1a;alientek 阿波羅 STM32F767 開發板2)摘自《STM32F7 開發指南(HAL 庫版)》關注官方微信號公眾號&#xff0c;獲取更多資料&#xff1a;正點原子第五章 SYSTEM 文件夾介紹第三章&#xff0c;我們介紹了如何在 MDK5 下建立 STM32F7 工程。在這個新建的工程之…

手機安卓學習 內核開發

官網開源代碼 Documentation - MiCode/Xiaomi_Kernel_OpenSource - Sourcegraph Xiaomi 11T Pro GitHub - MiCode/Xiaomi_Kernel_OpenSource: Xiaomi Mobile Phone Kernel OpenSourceAndroid 開源項目 | Android Open Source Project google安卓官網 目錄概覽 參考…

vs 啟動調用的目標發生異常_如何解決不可測、異常場景的問題?

阿里QA導讀&#xff1a;在軟件研發過程中&#xff0c;發布前跨多個系統的聯調測試是不可或缺的一環&#xff0c;而在聯調過程中&#xff0c;經常會遇到一些比較棘手的困難&#xff0c;阻塞整個聯調進程。其中比較典型的有&#xff1a;第三方的研發節奏不一致&#xff0c;導致無…

Linux內核 scatterlist介紹

scatterlist 物理內存的散列表。通俗講&#xff0c;就是把一些分散的物理內存&#xff0c;以列表的形式組織起來 誕生背景 假設有三個模塊可以訪問memory&#xff1a;CPU、DMA控制器和某個外設。CPU通過MMU以虛擬地址&#xff08;VA&#xff09;的形式訪問memory&#xff1b;…

www.python123.org_python爬蟲-requests

Requests庫是目前常用且效率較高的爬取網頁的庫1.一個簡單的例子import requests #引入requests庫r requests.get("http://www.baidu.com")  #調用get方法獲取界面print(r.status_code)    #輸出狀態碼print(r.text)    #輸出頁面信息通過以下代碼&#x…

Linux內核 crypto文件夾 密碼學知識學習

密碼算法分類 對稱算法非對稱算法消息摘要&#xff08;單向哈希&#xff09;算法這些算法作為加密函數框架的最底層&#xff0c;提供加密和解密的實際操作。這些函數可以在內核crypto文件夾下&#xff0c;相應的文件中找到。不過內核模塊不能直接調用這些函數&#xff0c;因為…

python隨機出100道加法題_自動出題隨機100題-20以內加減法全部算式

班 級:姓 名:12-819-411-1114-1018-111417-261215-113-417-819-1914-341516-31269619-161159312817-014-1414-1112-501414-017-616-111-012-211520-711113051019-1810619-691118-1220-519-818018114-1416-712-1015-1319-916-714-920-717-118-1611-815-416-1014-919-416-1413-…

Linux crypto相關知識的匯總 Linux加密框架crypto中的算法和算法模式(一)

Linux加密框架中的算法和算法模式 Linux加密框架中的算法和算法模式&#xff08;一&#xff09;_家有一希的博客-CSDN博客 加密框架支持的密碼算法主要是對稱密碼算法和哈希算法&#xff0c;暫時不支持非對稱密碼算法。除密碼算法外&#xff0c;加密框架還包括偽隨機數生成算法…

python3.5.2安裝pygame_【閑來無事,py寫game】Mac-Python3.5安裝pygame 1.9.2 小計

13正文之前沒錯&#xff0c;我就是這么不學無術&#xff0c;C實在學的雞兒疼&#xff0c;所以干脆搞點娛樂措施&#xff0c;昨天趕上了京東圖書做大活動&#xff0c;所以屯了一批書&#xff0c;好久沒碰python了。所以就整本玩玩&#xff01;今天這不就上手了么&#xff01;自己…

Linux crypto相關知識的匯總 Linux加密框架crypto對稱算法和哈希算法加密模式

參考鏈接 Linux加密框架中的算法和算法模式&#xff08;二&#xff09;_家有一希的博客-CSDN博客 對稱算法 分組算法模式 ECB模式 ECB模式下&#xff0c;明文數據被分為大小合適的分組&#xff0c;然后對每個分組獨立進行加密或解密如下圖所示如果兩個明文塊相同&#xff0c…

物化視圖和視圖的最大區別_基于catalyst的物化視圖改寫引擎的實現

更新日志&#xff1a;1. 2020/06/16 group by 視圖的部分描述錯誤&#xff0c;已修正。什么是物化視圖我先用我的話解釋一下什么是物化視圖。假設我們已經有A&#xff0c;B兩張表&#xff0c;現在我創建了一張表C,C是由A,B兩張表經過一條SQL處理得到的&#xff0c;這個時候我們…

Linux加密框架中的算法和算法模式

參考鏈接 Linux加密框架中的算法和算法模式&#xff08;三&#xff09;_家有一希的博客-CSDN博客 對稱算法 14 如上所示&#xff0c;在arc4.c中定義了兩個與RC4算法相關的算法實現&#xff0c;分別為arc4和ecb(arc4)&#xff0c;其中arc4是RC算法的算法實現&#xff0c;而ecb…

python學籍管理系統 flask_taskday05-Python之flask學習 web開發最基本的需要(特別詳細且適用)...

1.首先一個Flask的Web項目的創建需求一(文章概述)&#xff1a;一&#xff1a;必須實現命令工具管理App&#xff0c;用于在命令行輸入命令對項目進行管理&#xff0c;對后期多多益善二&#xff1a;必須實現“藍圖”管理&#xff0c;用于將app啟動函數與路由分開管理&#xff0c;…