C語言-指針變量和變量指針

指針

預備知識

內存地址
  • 字節:字節是內存的容量單位,英文名Byte,1Byte=8bits

  • 地址:系統為了便于區分每一個字節面對它們的逐一進行編號(編號是唯一的),稱為內存地址,簡稱地址。int a=5;

基地址(首地址)
  • 單字節數據:對于單字節數據而言,其地址就是其字節編號。舉例:char a='A'

  • 多字節數據:對于多字節數據而言,其地址是所有字節中編號最小的那個,稱為基地址()

取地址符
  • 每個變量都是一塊的內存,都可以通過取址符&獲取其地址。

  • 例如:

    ?int a=100;printf("整型變量a的地址是:%p\n",&a);//64位系統,是12位16進制int c='x';printf("字符變量c的地址是:%c");
  • 主語:

    • 雖然不同的變量的尺寸是不同的,但是它們的地址尺寸是一致的。

    • 不同的地址雖然形式上看起來是一樣的,但由于它們代表的內存尺寸和類型都不同,因此它們在邏輯上嚴格區分的。

為什么要引入指針

  • 為函數修改實參提供支持。

  • 為動態內存管理提供支持。

  • 為動態的的數據結構(鏈表、隊列等)提供支持

  • 為內存訪問提拱了另一種途徑。

變量指針與指針變量

指針概念
內存單元與地址機制
  • 內存單元劃分

    • 系統將內存劃分為連續的基本存儲單元,每個單元的容量為1字節(8bits)

    • 每個內存單元擁有唯一編號。稱為內存地址(十六進制表示:)

  • 變量存儲特性

    • 變量根據數據類型占據不同數量的內存單元:

      • char 類型占1個字節(1個單元)

      • int 類型占4個字節(4個單元)

      • double類型占8個字節(8個單元)

    • 變量的基地址(首地址)是其首個內存單元的地址(首地址一般是這個一組編號中最小的那個)

變量指針與指針變量
對比維度變量指針指針變量
本質內存地址(首地址\基地址) 變量指針其實就是變量的首地址存儲地址的普通變量
操作符&(取地址符)*(聲明符,解引用符,如:int *p
代碼示例&a(獲取變量a地址)int* p =&a
核心特性不可修改(地址由系統分配)可修改指向(p=&b
指向:
指針變量中存放 誰 的地址,就說明該指針變量指向了 誰
指針的尺寸

系統類型指針尺寸地址位數十六進制顯示長度
32位系統4字節(int)32bit8位(如0x0804A000)
64位系統8字節(long)48bit12位(如0x7FFDEADBEEF)
指針的本質
  • 變量指針:數據的門牌號(&a)

  • 指針變量:存儲門牌號的筆記本(int *p)

  • 指向操作:通過門牌號訪問數據(*p)

?int a=10;printf("%d\n",a);//訪問a的值?int *p=&a;printf("%d\n",*p);//訪問p指向a的值,其實就是訪問a的值

小貼士:

Linux系統中打印地址時,最多顯示12個十六進制數,為什么? Linux64位操作系統中,一個內存地址占8個字節,一個字節8bit位,所以一個地址88=64bit位,每4個bit可以表示1個十六進制數; 64個bit位用十六進制表示最多有16個數值位; 系統為了尋址方便,默認當前計算機系統沒必要尋址64bit為,只尋址了48個bit為,所以用12個十六進制數表示一個地址 二進制: 01001010 十六進制:0x4A 416+10=74 注意: 在Linux64位操作系統中,指針類型的變量占8個字節的內存空間 在Linux32位操作系統中,指針類型的變量占4個字節的內存空間

內存數據的存取方式

在c語言中對內存數據(變量、數組元素等)的存取有兩種方式:

直接存取
  • 通過基本類型(整型、浮點型、字符型)的變量,訪問這個變量代表內存空間的數據

  • 通過數組元素的引用,訪問這個引用代表的內存空間數據

    ?//基本類型變量int a=10;//存printf("%d\n",a);//取?//數組元素int arr[]={11,12,13};//存arr[0]=66;//存printf("%d\n",arr[0]);//取
間接存取
  • 通過指針變量,間接訪問內存中的數據

  • 解引用符*:讀作聲明符或者解引用符。如果*前面有數據類型,讀作聲明指針;如果*前面沒有數據類型,讀作解引用。

    案例

    ? #include <stdio.h>int main(int argc,char *argv[]){// 定義一個普通變量int a = 3;?// 定義一個指針變量,并賦值int* p = &a; // *p前面的數據類型是用來修飾 = 后面的 a的類型// 訪問變量a,直接訪問printf("直接訪問-%d\n",a);// 訪問變量a,通過指針變量p訪問,間接訪問printf("間接訪問-%d\n",*p);// *p 叫做解引用// 訪問指針變量p的值,也就是訪問變量a的地址 %p 輸出 變量的地址printf("地址訪問-%p,%p,%p\n",p,&p,&a);return 0;}??

    變量指針與指針變量

    指針變量的定義

    語法:

    ?數據類型 *變量列表

    舉例:

    ?int a;//普通變量,擁有真實的數據存放空間int *a_,*b_;//指針變量,無法存放數據,只能存儲其他變量的地址

    注意:指針變量的值只能是8、12位的十六進制整數

    注意:

    ①雖然定義指針變量*a,是在變量名前加上*,但是實際變量名依然為a,而不是*a

    ②使用指針變量間接訪問內存數據時,指針變量必須要明確的指向。(指向:指針變量存放誰的地址,就指向誰)

    ③如果想要借助指針變量間接訪問指針變量保存的內存地址上的數據,可以使用指針變量前加*,來間接返回訪問。指針變量前加*,如果不帶數據類型,就稱之為對指針變量解引用

    ?int i=5,*p;p=&i;//將i的地址賦值給指針變量p;printf("%lx,%p,%p\n",p,p,&p); %p-&p(p自己的地址) ?%p- p(i對應的地址)printf("%d\n",*p);解引用所儲存變量空間的地址*p=10;//間接給p對應的地址上的數據空間賦值,也就是給變量i賦值printf("%d,%d\n",*p,i);//10 10

    ④指針變量只能指向同類型的變量,借助指針變量訪問內存,一次訪問內存

    大小是取決于指針變量的類型

    ?int a=10;int *p=&a;//*p前面的類型是p指向變量a的類型,這個類型要么完全一致,要么可以轉換

    ⑤指針變量在定義時可以初始化,這一點和普通變量是一樣的。

    ?int a=5;int *p=&a;//定義指針變量的同時初始化printf("%d\n",*p);?int b;int *p1=&b; //指針初始化的時候,不需要關注指向變量空間中是否有值printf("%d\n",*p1); 會出錯
    指針變量的使用

    使用

    • 指針變量的賦值

      ?//方式1int a, *p;p=&a;// 先定義,后賦值??//方式2int a1,*p1,*q1=&al; //定義并初始化p1=ql;//其實就是變量賦值,指針變量q1的值賦值給p1,此時q1和p1同時指向a1
    • 操作指針變量的值

      ?int a,*p,*q=&a;p=q;//將指針變量q的值賦值給指針變量p,此時p和q都指向了變量a?printf("%p",p);//訪問的是指針變量p的值(也就是變量a的地址)printf("%p",q);
    • 操作指針變量指向的值

      ?int a=6;*q=&a,b=25;//一定要注意指針變量q的變量名就是q*q=10;//訪問q指向的變量a的空間,其實就是間接的給a賦值(a=10)printf("%d,%d\n",*q,a);//10  10?q=&b;//一個指針變量只能同一時刻指向一個變量,但是一個變量可以同時被多個指針變量指向?printf("%d,%d\n",*q,a);// 25  10
    兩個指針運算符使用
    • &取地址運算符。&a是變量a的地址。這個是變量指針

    • *指針運算符、解引用符、間接訪問運算符,*p是指針變量p指向的對象值。這個是指針變量。

    案例

    案例1

    • 需求:通過指針變量訪問整型變量

    • 分析:

    • 代碼:

      ?#include <stdio.h>?void main(){int a=3,b=4,*p1=&a,*p2=&b;printf("a=%d,b=%d\n",*p1,*p2);?}

    案例2

    • 需求:聲明a,b兩個變量,使用間接存取的方式實現數據交換。

    • 分析:

    • 代碼:

      ?#include <stdio.h>int main(){int a=3,b=4,*p_a=&a,*p_b=&b,*p_t;printf("交換前為%d,%d\n",*p_a,*P_b);//3,4//交換位置p_t=p_a;P_a=P_b;p_b=p_t;printf("交換后為%d,%d,%d,%d\n",*p_a,*P_b);}

      總結:此時改變的只是指針的指向,原始變量a,b中數據并沒有發生改變

    • 代碼:數據改變,不推薦

      ?#include <stdio.h>int main(){int a=3,b=4,*p_a=&a,*p_b=&b,temp;printf("交換前為%d,%d\n",*p_a,*P_b);//3,4//交換位置temp=*p_a;*P_a=*P_b;*p_b=temp;printf("交換后為%d,%d\n",*p_a,*P_b);}

      總結:此時改變的只是指針的指向,原始變量a,b中數據發生改變

    案例3

    • 需求:輸入a、b兩個整數,按先大后小的順序輸出a和b

    • 分析:

    • 代碼:指向改變

      ?#include <stdio.h>int main(){int a=3,b=4,*p_a=&a,*p_b=&b,*p_t;if(a<b){p_t=p_a;P_a=P_b;p_b=p_t;}//交換位置printf("按從小到大的順序輸出a,b的值%d>%d\n",*p_a,*P_b);}

    • 代碼:

      ?#include <stdio.h>int main(){int a=3,b=4,*p_a=&a,*p_b=&b,temp;printf("交換前為%d,%d\n",*p_a,*P_b);//3,4if(a<b){//交換位置temp=*p_a;*P_a=*P_b;*p_b=temp;}printf("按從小到大的順序輸出a,b的值%d>%d\n",*p_a,*P_b);}

    指針變量做函數參數

    指針變量做函數參數往往傳遞的是變量的地址(基地址),借助與指針變量間接訪問是可以修改實參變量數據的。

    案例:

    • 需求:有a,b兩個變量,要求交換后輸出(要求函數處理,用指針變量做函數的參數)

    • 方式1:交換指向(指針指向發生改變,指針指向的對象的值不變)

      ?#include <stdio.h>//定義一個函數,實現兩個數的交換?void swap(int *p_a,int *p_b){int *p_t;//以下寫法只會改變指針指向 不會改變指向對象的值p_t=p_a;P_a=P_b;p_b=p_t;printf("%d,%d\n",*P_a,*p_b);}?int main(){int a=3,b=5,*p_a=&a,*p_b=&b,*p_t;swap(&a,&b);printf("a=%d,b=%d\n",a,b)return 0;}

    • 方式2:交換數據(指針指向不改變,指針指向對象的值發生變化)

      ?#include <stdio.h>?void swap(int *p_a,int *p_b){int temp;//以下寫法只會改變指針指向 不會改變指向對象的值temp=*p_a;*P_a=*P_b;*p_b=temp;printf("%d,%d\n",*P_a,*p_b);}??int main(){int a=3,b=4,*p_a=&a,*p_b=&b,temp;swap(&a,&b);printf("a=%d,b=%d\n",a,b);}

    指針變量指向數組元素
    數組元素指針
    • 數組的指針就是數組中的第一個元素的地址,也就是數組的首地址

    • 數組元素的指針是指數組的首地址。因此,同樣可以用指針變量來指向數組或數組元素。

    • 在C語言中,由于數組名代表數組的首地址,因此,數組名實際上也是指針,訪問數組名就是訪問數組首地址

    ?#include <stdio.h>//定義一個函數,實現兩個數的交換???int main(){int arr[]={11,12,13};int *p1=arr[0];int *p2=arr;printf("%p,%p,%p\n",p1,p2,arr);return 0;}

    注意:雖然我們定義一個指針變量接收了數組地址,但不能理解為指針變量指向了數組。而應該理解為指向了數組的元素(默認為第1個元素)。

    指針運算

    指針運算:前提是指針變量必須要指向數組的某個元素。(指針運算只能發生在同一數組)

    序號指針運算說明
    1自增:p++、++p、p=p+1、p+=1指向下一個元素的地址
    2自減:p--、--p、p-=1指向下一個元素的地址
    3加n個數:p+n(n*sizeof(type))后n個元素的(首)地址
    4減n個數:p-n前n個元素的(首地址)
    5指針相減:p1-p2p1,p2之間相差幾個元素
    6指針比較:p1<p2前面的指針小于后面的指針

    說明: ①如果指針變量p已指向數組中的一個元素,則p+1指向同一數組中的下一個元素,p-1指向同一數組中的上一個元素。即p+1或p-1也表示地址。但要注意的是,雖然指針變量p中存放的是地址,但p+1并不表示該地址加1,而表示在原地址的基礎上加了該數據類型所占的字節數d(d=sizeof(數據類型))。 ②如果p原來指向a[0],執行++p后p的值改變了,在p的原值基礎上加d,這樣p就指向數組的下一個元素a[1]。d是數組元素占的字節數。 ③如果p的初值為&a[0]則p+i和a+i就是數組元素a[i]的地址,或者說,它們指向a數組的第i個元素。 ④*(p+i)(a+i)是p+i或a+i所指向的數組元素,即a[i]。 ⑤如果指針變量p1和p2都指向同一數組,如執行p2-p1,結果是兩個地址之差除以數組元素的長度d。

    ?#include <stdio.h>?int main(){int arr[]={11,22,33,44,55};int *p1=arr+4;//55等價于arr[4]int *p2=arr+1;//22等價于arr[1]aiprintf("%ld\n",p1-p2);//3 ? ?  4*4-1*4=12 ? 12(相差的字節數)/4(每個元素的大小ai)=3(元素的大小)return 0;}
    案例

    案例1

    • 需求:通過下標法和指針法遍歷數組

    • 代碼:

      ?#include <stdio.h>?//下標法遍歷數組void arr1(int arr[],int len){//通過循環遍歷for(int i=0;i<len;i++){printf("%-3d",arr[i]);}printf("\n");}?void arr2(int arr[],int len){int *p=arr;register int i=0;for(;i<len;i++){printf("%-3d",*p;p++;}printf("\n");?}??void arr3(int arr[],int len){int *p=arr;register int i=0;for(;i<len;i++){printf("%-3d",*(arr+i));}printf("\n");}??int main(){int array[]={11,22,33,44,55};int len=sizeof(arr)/sizeof(arr[0]);arr1(array,len);arr2(array,len);arr3(array,len);return 0;}??
      ?#include <stdio.h>?int arr2() {int arr1[] = {11, 22, 33, 44, 55, 66, 77, 88};int *p = arr1;?// 1. 輸出數組首元素 11printf("%d\n", *p); ?// 2. 指針后移,輸出 22p++;printf("%d\n", *p); ?// 3. 先取值 22,指針再后移。此時 x=22,p 指向 33int x = *p++; printf("%d,%d\n", x, *p); // 輸出 22,33?// 4. 指針先前移到 44,取值 44。y=44,p 指向 44int y = *(++p); printf("%d,%d\n", y, *p); // 輸出 44,44?// 5. 對當前指向的元素(44)自增,變為 45(*p)++; printf("%d\n", *p); // 輸出 45?return 0;}?int main(int argc, char *argv[]) {arr2();return 0;}

      *p++ 先解引用p,然后p這個指針自增

      ?int arr[]={11,22,33},*p=arr;int x=*p++; ?   

      (*p)++ 先解引用p,然后使用解引用出來的數據自增

      ?int arr[]={11,22,33};*p=arr;int x=(*p)++;

    通過指針引用數組元素

    引用一個數組元素,可以用:

    ①下標法:如:arr[i]形式

    ②指針法:如:*(arr+i)或者*(p+i),其中arr是數組名,p是指向數組元素的指針變量,其初始值;p=arr;

    案例:

    需求:有一個整型數組arr,有十個元素,輸出數組中的全部元素。

    • 下標法:(通過改變下標輸出所有元素)

      ?#include <stdio.h>void main(){int arr[10];int i;// 給數組元素賦值for(i = 0; i < 10; i++)scanf("%d",&arr[i]);// 遍歷數組元素for(i = 0; i < 10; i++)printf("%-4d%",*(arr + i));printf("\n"); ? }

    • 指針法(地址):(通過數組名計算出數組元素地址,找出數組元素)

      ?#include <stdio.h>void main(){int arr[10];int i;// 給數組元素賦值for(i = 0; i < 10; i++)scanf("%d",&arr[i]);// 遍歷數組元素for(i = 0; i < 10; i++)printf("%-4d%",arr[i]);printf("\n"); ? }

    • 指針法(指針變量):用指針變量指向數組元素

      ?#include <stdio.h>void main(){int arr[10];int *p, i;// 給數組元素賦值for(i = 0; i < 10; i++)scanf("%d",&arr[i]);// 遍歷數組元素for(p = arr; p < (arr + 10); p++)printf("%-4d%",*p);printf("\n"); ? }

    注意:數組一旦創建,就無法改變其值

    以上三種寫法比較:

    • 第種寫法和第②種寫法執行效率相同。系統是將arr[]轉換為*(arr+i)處理的,即先計算出地址,因此比較費時。

    • 第③種方法比①②種方法快。用指針變量直接指向數組元素,不必每次都重新計算地址。(p++)能大大提高執行效率。

    • 用第①種寫法比較直觀,而用地址法或者指針變量的方法難以很快判斷出當前處理的元素。

    使用指針變量指向數組元素時(上面第③種寫法),注意以下三點:

    *(p--)相當于arr[i--],先*p,在p--*(p++)相當于arr[i++],先*p,在p++

    *(++p)相當于arr[++i],先++p,在**(--p)相當于arr[--i],先--p,在*

    *p++先*p,在p++

    (*p)++先*p,在*p++

    *p++ (p++) (*p)++

    具體關系參照下面表格

    數組名做函數參數

    表現形式:

    ①形參和實參都是數組名

    ?void fun(int arr[],int len){......}void main(){int arr[]={11,22,33};fun(arr,sizeof(arr)/sizeof(arr[0]));}

    ②實參用數組名,形參用指針變量

    ?void fun(int *p,int len){......}void main(){int arr[]={11,22,33};fun(p,sizeof(arr)/sizeof(arr[0]));}

    ③實參和形參都用指針變量

    ?void fun(int *p,int len){......}void main(){int arr[]={11,22,33};int *p=arr;fun(p,sizeof(arr)/sizeof(arr[0]));}

    ④實參用指針,形參用數組名

    ?void fun(int arr[],int len){......}void main(){int arr[]={11,22,33};int *p=arr;fun(p,sizeof(arr)/sizeof(arr[0]));}

    案例:

    需求:將數組a中n個元素

    分析:

    代碼:

    ?#include <stdio.h>/*** 數組的反轉:數組實現*/ void inv(int arr[], int len){// 反轉思路:將第0個和len -1個進行對調,將第1個和len-2個進行對調...// 定義循環變量和臨時變量register int i = 0, temp;// 遍歷數組for(; i < len/2; i++){// 交換temp = arr[i];arr[i] = arr[len - 1 - i];arr[len - 1 - i] = temp;}}/*** 數組的反轉:指針實現*/ void inv2(int *p, int len){// 反轉思路:將第0個和len -1個進行對調,將第1個和len-2個進行對調...// 定義循環變量和臨時變量int *i = p, *j = p + len - 1, temp;// 遍歷數組for(; i < j;i++,j--){// 交換temp = *i;*i = *j;*j = temp;}}/*** 遍歷數組*/ void list(const int arr[],int len)for(int i = 0; i < len; i++) printf("%-3d",arr[i]);printf("\n");}int main(int argc,char *argv[]){int arr[] = {11,22,33,44,55,66};int len = sizeof(arr) / sizeof(arr[0]);list(arr,len);inv(arr,len);list(arr,len);inv2(arr,len);list(arr,len);return 0;}?

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

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

相關文章

unityAB包(1/2)

unityAB包學習 1.AB包的導出擴展BuildAssetBundleOptions無特殊選項壓縮相關選項 2.AB包資源管理3.Resource和AssetBundle加載方式的區別4.預設體5.Unity Asset Bundle Browser 工具5為什么要勾選拷貝到StreamingAsset里面。6.AB包的加載 1.AB包的導出 首先在Project窗口&…

算法——廣度優先搜索——跨步迷宮

原題鏈接 思路&#xff1a;找出最短路徑&#xff0c;然后判斷是否存在連續三個點是橫縱坐標相等的&#xff0c;如果有就步數減1 但是有兩個樣例過不了 錯誤原因&#xff1a;在錯誤的測試案例中&#xff0c;最短路徑可能有多條&#xff0c;而我剛好選了一條比較曲折的&#x…

某酒企數字化轉型及電商規劃項目啟動會暨培訓會v(60頁PPT)(文末有下載方式)

詳細資料請看本解讀文章的最后內容。 在當今數字化浪潮席卷之下&#xff0c;企業的發展面臨著前所未有的機遇與挑戰。對于某酒企而言&#xff0c;數字化轉型和電商規劃已成為其實現 “二次騰飛”、邁向世界級酒企的關鍵戰略舉措。本次啟動會暨培訓會&#xff0c;為該酒企的轉型…

NET6 WebApi第5講:中間件(源碼理解,俄羅斯套娃怎么來的?);Web 服務器 (Nginx / IIS / Kestrel)、WSL、SSL/TSL

一、NET6的啟動流程 區別&#xff1a; .NET6 WebApi第1講&#xff1a;VSCode開發.NET項目、區別.NET5框架【兩個框架啟動流程詳解】_vscode webapi-CSDN博客 2、WebApplicationBuilder&#xff1a;是NET6引入的一個類&#xff0c;是建造者模式的典型應用 1>建造者模式的…

vue中根據html動態渲染內容

需求&#xff1a;根據數據中的html&#xff0c;因為我是在做填空&#xff0c;所以是需要將html中的_____替換成input&#xff0c;由于具體需求我使用的是元素contenteditable代替的可編輯的input html部分 <div class"wrap"><component :is"rendered…

【AI】AI編程助手:Cursor、Codeium、GitHub Copilot、Roo Cline、Tabnine

文章目錄 一、基本特性對比二、收費標準三、私有部署能力1、Tabnine2、Roo Code 三、代碼補全與自然語言生成代碼四、安裝獨立的IDE安裝插件安裝 五、基本使用&#xff08;一&#xff09;Cursor&#xff08;二&#xff09;GitHub Copilot1、獲取代碼建議2.聊天1&#xff09;上下…

三軸云臺之角速度信號篇

三軸云臺的角速度信號主要通過其內置的傳感器&#xff08;如陀螺儀&#xff09;來感知和測量。 一、角速度信號的感知與測量 在三軸云臺中&#xff0c;陀螺儀是測量角速度的關鍵組件。它通常安裝在三個互相垂直的軸上&#xff08;通常為X、Y、Z軸&#xff09;&#xff0c;能夠…

Grid 布局實現三欄布局

使用 CSS Grid 布局實現三欄布局(左右固定 100px,中間自適應)的核心原理是通過網格模板精確控制列寬分配。以下是具體實現方法及優化技巧: 一、基礎實現 ?父容器設置 為外層容器添加 display: grid 使其成為網格容器,并通過 grid-template-columns 定義列寬 css .contain…

綠盟春招實習一面

《網安面試指南》https://mp.weixin.qq.com/s/RIVYDmxI9g_TgGrpbdDKtA?token1860256701&langzh_CN 5000篇網安資料庫https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247486065&idx2&snb30ade8200e842743339d428f414475e&chksmc0e4732df793fa3bf39…

進制轉換(R轉十)(1290. 二進制轉換十進制、1292. 十六進制轉十進制、1291. 八進制轉十進制、1405. 小麗找潛在的素數)

題單地址&#xff1a;題單中心-東方博宜OJ 這里以二進制轉十進制為例&#xff08;按位加權求和法&#xff09; 1290. 二進制轉換十進制 問題描述 請將一個 25 位以內的 2 進制正整數轉換為 1010 進制&#xff01; 輸入 一個 25 位以內的二進制正整數。 輸出 該數對應的…

Redis 本地安裝

首先安裝&#xff1a; https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-from-source/ 進入root目錄 tar -xzvf redis-stable.tar.gz cd redis-stable make然后 install sudo make install最后可以直接啟動 redis-server但是此時啟…

9.嗅探與Wireshark進階分析

嗅探與Wireshark進階分析 第一部分&#xff1a;嗅探的概念與重要性第二部分&#xff1a;Wireshark進階功能第三部分&#xff1a;嗅探實踐與分析總結 目標&#xff1a; ? 理解嗅探&#xff08;Sniffing&#xff09;的概念及其在網絡安全中的作用 ? 掌握Wireshark的進階功能&a…

在 VSCode 遠程開發環境下使用 Git 常用命令

在日常開發過程中&#xff0c;無論是單人項目還是團隊協作&#xff0c;Git 都是版本管理的利器。尤其是在使用 VSCode 連接遠程服務器進行代碼開發時&#xff0c;Git 不僅能幫助你管理代碼版本&#xff0c;還能讓多人協作變得更加高效。本文將介紹一些常用的 Git 命令&#xff…

npm 命令使用文檔

目錄 簡介安裝與配置基礎命令依賴管理版本控制腳本管理包發布高級命令配置管理最佳實踐常見問題 1. 簡介 npm (Node Package Manager) 是 Node.js 的官方包管理工具&#xff0c;提供&#xff1a; 130萬 開源包的注冊表訪問依賴解析與版本管理項目腳本自動化私有包管理能力完…

【Linux篇】進程控制

&#x1f4cc; 個人主頁&#xff1a; 孫同學_ &#x1f527; 文章專欄&#xff1a;Liunx &#x1f4a1; 關注我&#xff0c;分享經驗&#xff0c;助你少走彎路&#xff01; 1. 進程創建 1.1 fork函數 在linux中fork函數是非常重要的函數&#xff0c;它從已存在進程中創建一個…

HyperAD:學習弱監督音視頻暴力檢測在雙曲空間中的方法

文章目錄 速覽摘要1. 引言2. 相關工作弱監督暴力檢測雙曲空間中的神經網絡 3. 預備知識雙曲幾何切空間&#xff08;Tangent Space&#xff09;指數映射與對數映射&#xff08;Exponential and Logarithmic Maps&#xff09;3.1 雙曲圖卷積網絡&#xff08;Hyperbolic Graph Con…

動態規劃(6.不同路徑II)

題目鏈接&#xff1a;63. 不同路徑 II - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 本題為不同路徑的變型&#xff0c;只不過有些地方有「障礙物」&#xff0c;只要在「狀態轉移」上稍加修改就可解決。 狀態表示&#xff1a; 對于這種Γ路徑類」的問題&#xf…

深度洞察:DeepSeek 驅動金融行業智能化轉型變革

該文章為軟件測評&#xff0c;不是廣告&#xff01;&#xff01;&#xff01;&#xff01; 目錄 一.金融行業的智能化轉型浪潮? 二.DeepSeek的核心技術剖析 1.DeepSeek 模型的金融智慧? 2.實時聯網搜索&#xff1a;把握金融市場脈搏? 3.RAG 能力&#xff1a;鑄就精準金…

藍橋杯備考----》暴力枚舉---金盞花

這道題&#xff0c;一共12位&#xff0c;給了后六位&#xff0c;我們只要枚舉前六位就行了&#xff0c;當然如果是10的12次方的話&#xff0c;必須要開long long才可以存下&#xff0c;這點我們不要忘了 然后題目中又告訴了沒有前導0&#xff0c;我們可以從100000開始枚舉&…

RAG各類方法python源碼解讀與實踐:利用Jupyter對RAG技術綜合評測【3萬字長文】

檢索增強生成&#xff08;RAG &#xff09;是一種結合信息檢索與生成模型的混合方法。它通過引入外部知識來提升語言模型的性能&#xff0c;從而提高回答的準確性和事實正確性。為了簡單易學&#xff0c;不使用LangChain框架或FAISS向量數據庫&#xff0c;而是利用Jupyter Note…