13 學習總結:指針 · 其一

目錄

一、內存和地址

(一)內存

(二)內存單元

(三)地址

(四)拓展:CPU與內存的聯系

二、指針變量和地址

(一)創建變量的本質

(二)取地址操作符:&

(三)指針變量和解引用操作符:*

1、指針變量

2、指針變量的理解

(1)【int* pa】的理解

(2)【int*】的理解

3、解引用操作符:*

(四)指針變量的大小

三、指針變量類型的意義

(一)解引用操作時,決定可以操作多少個字節

(二)指針 + -? 整數時,向前/向后走多大的區別

(三)void* 指針

四、const修飾指針

(一)const修飾變量

(二)const修飾指針變量

五、指針的運算

(一)指針 + 或 -? 整數

(二)指針 - 指針

(三)指針的關系運算(指針的比較)

六、野指針

(一)野指針造成的原因

1、指針未初始化

2、指針越界訪問

3、指針指向的空間釋放

(二)如何規避野指針

1、指針初始化

2、小心指針越界

3、指針變量不再使用時,及時置NULL,指針使用之前檢查有效性

4、避免返回局部變量的地址

七、assert斷言

八、指針的使用和傳址調用

(一)指針的使用:strlen的模擬實現

(二)傳值調用和傳址調用


一、內存和地址

(一)內存

????????又稱內存儲器或主存儲器,計算機中所有程序的運行都在內存中進行,計算機上CPU(中央處理器)在處理數據的時候,需要的數據是在內存中讀取的,處理后的數據也會放回內存中,這樣使用內存則需要高效地管理內存空間;

(二)內存單元

????????就是把內存劃分為一個個的內存單元,每個內存單元的大小取1個字節(8個比特位),每個內存單元都有?個編號,有了這個內存單元的編號,CPU就可以快速找到?個內存空間;

(三)地址

????????在計算機中我們把【內存單元的編號】也稱為【地址】,C語言中給【地址】起了新的名字叫:【指針】

? ? ? ? 可以理解為:【內存單元的編號 == 地址 == 指針】

(四)拓展:CPU與內存的聯系

????????有三條總線將CPU與內存連接彼此,交換數據:①地址總線;②數據總線;③控制總線

????????交換過程:地址信息通過【地址總線】被下達給內存,在內存上就可以找到相應的數據,將數據通過【數據總線】傳入CPU做處理,【控制總線】則負責傳遞對數據的操作,如讀操作、寫操作等

二、指針變量和地址

(一)創建變量的本質

????????創建變量的本質是在內存中申請空間,例如創建一個 int 變量就是向內存申請4個字節的空間,每個字節都有自己的編號(地址),變量的名字僅僅是給程序員看的,編譯器不看名字,編譯器是通過地址找內存單元的

(二)取地址操作符:&

?????????使用:拿到變量的地址

????????例如:

int a = 10;&a;

? ? ? ? &a 就可以拿到變量a的地址,雖然整型變量占用4個字節,我們只要知道了第?個字節地址,春藤摸瓜訪問到4個字節的數據也是可行的

? ? ? ? 注:當一個變量占多個內存單元的時候,總會取出該變量的第一個內存單元(地址較小的那個字節)

(三)指針變量和解引用操作符:*

1、指針變量

????????通過取地址操作符(&)拿到的地址是?個數值,比如:0x0012ff40,這個數值有時候也是需要存儲起來,方便后期再使用的,那我們把這樣的地址值存放在哪里呢?答案是:指針變量中,例如:

#include <stdio.h>
int main()
{int a = 10;int * pa = &a;//取出a的地址并存儲到指針變量pa中return 0;
}

????????指針變量也是?種變量,這種變量就是?來存放地址的,存放在指針變量中的值都會理解為地址

2、指針變量的理解

? ? ? ? 上面例子的寫法中的 int *pa 拆開來理解:

(1)【int* pa】的理解

? ? ? ? ①【int *】是變量pa的類型;

? ? ? ? ② pa是一個變量,用來存放地址(指針)的,所以pa又叫指針變量

(2)【int*】的理解

? ? ? ? ① * 表示pa是指針變量;

????????② int 表示【pa 指針變量中保存的地址】所指向的【變量 a】的類型是int

3、解引用操作符:*

? ? ? ? 又稱為間接訪問操作符,用法:

如下演示:
int main()
{int a = 100;int* pa = &a;*pa = 0;此處*pa == a,相當于對a進行修改return 0;
}

? ? ? ? 總結:通過【指針變量pa】找到指向的變量a—— *pa(通過pa的值,找到a)

? ? ? ? ① pa —— 指針變量

? ? ? ? ② &pa —— 指針變量pa的地址

? ? ? ? ③ *pa —— pa指向的變量a

(四)指針變量的大小

? ? ? ? 【指針變量類型的大小】取決于【地址的大小】,而地址大小由計算機是32位操作系統還是64位操作系統決定

????????① 指針變量是用來存放地址的,一個地址的存放需要多大空間,那么指針變量類型就是多大,所以32位平臺總共有32根地址總線,每根線的電信號轉化成數字信號后是1或0,那我們把32根地址總線產生的2進制序列作為一個地址,那么一個地址就是32個比特位,就是4個字節;同理,在64位的機器中,一個地址的大小就是8字節

????????② 地址的大小與【指向的原變量的類型大小】無關,就是4字節或者8字節

#include <stdio.h>//指針變量的??取決于地址的??
//32位平臺下地址是32個bit位(即4個字節)
//64位平臺下地址是64個bit位(即8個字節)int main()
{printf("%zd\n", sizeof(char *));printf("%zd\n", sizeof(short *));printf("%zd\n", sizeof(int *));printf("%zd\n", sizeof(double *));return 0;
}

? ? ? ? X86環境輸出結果如下:

? ? ? ? X64環境輸出結果如下:

????????結論:

? 32位平臺下地址是32個bit位,指針變量大小是4個字節

? 64位平臺下地址是64個bit位,指針變量大小是8個字節

? 指針變量的大小和類型是無關的,只要指針類型的變量,在相同的平臺下,大小都是相同的

三、指針變量類型的意義

????????指針變量的大小和類型無關,只要是指針變量,在同?個平臺下,大小都是?樣的,都是4字節或者8字節,為什么還要有各種各樣的指針類型呢?

(一)解引用操作時,決定可以操作多少個字節

? ? ? ? 如下演示:

#include <stdio.h>
int main()
{int a = 0x11223344;int* p = &a;*p = 0;return 0;
}

? ? ? ? 變量a的地址與4個字節的值如下:

? ? ? ? 經過 *p = 0;的語句后,4個字節的值全部改為0,如下:

????????若代碼中指針變量的類型改為char*:

#include <stdio.h>
int main()
{int a = 0x11223344;char* p = &a;*p = 0;return 0;
}

????????變量a的地址與4個字節的值如下:

????????經過 *p = 0;的語句后,4個字節的值只有一個字節改為0,如下:

? ? ??

????????結論:指針的類型決定了,解引用操作時,決定可以操作多少個字節

????????比如: char* 的指針解引用就只能訪問一個字節,而?int* 的指針的解引用就能訪問四個字節

(二)指針 + -? 整數時,向前/向后走多大的區別

? ? ? ? 如下代碼演示:

#include <stdio.h>
int main()
{int n = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc+1);printf("%p\n", pi);printf("%p\n", pi+1);return 0;
}

? ? ? ? 代碼結果如下:

? ? ? ? 從結果可以得出:char* 類型的指針變量+1跳過1個字節, int* 類型的指針變量+1跳過了4個字節;

????????結論:指針的類型決定了指針向前或者向后走一步有多大(距離)? ?????????

?補充:
????????int* pa; ??
????????pa+1——> +1 * sizeof (int)
????????pa+n——> +n * sizeof (int)

????????char* pa; ??
????????pa+1——> +1 * sizeof (char)
????????pa+n——> +n * sizeof (char)

總結:

? ? ? ? 類型* 變量名;

? ? ? ? 變量名 + 1 ——> +1 * sizeof(指針指向的變量類型)

(三)void* 指針

????????void* ——無具體類型的指針(泛型指針)

????????可以接收任何類型的地址,但是正因為他是泛型指針,所以沒有特定類型指針的用法,即無法解引用和進行指針的 + - 操作

????????作用:?般 void* 類型的指針是使用在函數參數的部分,用來接收不同類型數據的地址,這樣的設計可以實現泛型編程的效果,使得?個函數來處理多種類型的數據

四、const修飾指針

(一)const修飾變量

????????const修飾變量的時候,叫:常變量;

????????本質還是變量,只是不能被修改;

????????變量是可以修改的,如果把變量的地址交給?個指針變量,通過指針變量的也可以修改這個變量,若不想變量被直接修改,就使用const修飾變量起限制作用

#include <stdio.h>
int main()
{int m = 0;m = 20;//m是可以修改的const int n = 0;n = 20;//n是不能被修改的return 0;
}

????????上述代碼中n是不能被修改的,其實n本質是變量(無法在數組長度中使用),只不過被const修飾后,在語法上加了限制,只要我們在代碼中對n進行修改,就不符合語法規則,就報錯,致使沒法直接修改n

? ? ? ? 但是可以拿到n的地址,通過指針對它進行修改,但這是在打破語法規則

int main()
{const int n = 0;printf("n = %d\n", n);int*p = &n;*p = 20;printf("n = %d\n", n);return 0;
}

? ? ? ? 結果如下:

? ? ? ? 這里的初衷是不讓變量改變,但是通過指針還是能打破const的限制,接下來就要對這一象限改進,直接對指針變量做const限制

(二)const修飾指針變量

?????????般來講const修飾指針變量,可以放在 * 的左邊,也可以放在 * 的右邊,意義是不?樣的

int * p;//沒有const修飾
int const * p;//const 放在*的左邊做修飾
int * const p;//const 放在*的右邊做修飾

? ? ? ? 如下代碼演示:

? ? ? ? 代碼一:

int a = 10;
int b = 20;
int const * p = &a;*p = 200;err
p = &b;√

? ? ? ? 代碼一分析:

????????這個const限制的是 *p,即p指向的變量a不能改變;但是并沒有限制p,所以可以修改p所指向的變量;
????????放在*的左邊,限制的是指針指向的內容,也就是不能通過指針變量來修改它所指的內容;但是指針變量本身可以改變的

? ? ? ? 代碼二:

int a = 10;
int b = 20;
int * const p = &a;*p = 200;√
p = &b;err

? ? ? ? 代碼二分析:

????????放在*的右邊,限制的是指針變量本身,也就是指針變量本身不可以改變,但可以通過指針變量來修改它所指的內容

????????結論:const修飾指針變量的時候

const如果放在 * 的左邊,修飾的是【指針指向的內容 *p】,保證指針指向的內容不能通過指針來改變,但是【指針變量本身 p】的內容可變;
const如果放在*的右邊,修飾的是【指針變量本身 p】,保證了指針變量的地址指向不能修改,但是【指針指向的內容*p】,可以通過指針改變

五、指針的運算

????????指針的基本運算有三種,分別是:

????????? 指針 + 或 -? 整數

????????? 指針 - 指針

????????? 指針的關系運算(指針的比較)

(一)指針 + 或 -? 整數

????????因為數組在內存中是連續存放的,只要知道第?個元素的地址,順騰摸瓜就能找到后?的所有元素

int arr[10] = {1,2,3,4,5,6,7,8,9,10};

#include <stdio.h>
//指針+- 整數
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);for(int i = 0; i < sz; i++){printf("%d ", *(p+i));//p+i 這?就是指針+整數}return 0;
}

????????注意:指針運算是指對 p 進行運算,而不是對*p,若對 *p 運算,就是對變量a運算了

????????在數組中,指針能夠“順騰摸瓜”的原因是:

????????①指針類型決定了【指針+1】的步長,和指針解引用之后的權限;

????????②數組在內存中的地址是連續的

? ? ? ? 錯誤演示代碼:

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};char *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);for(int i = 0; i < sz; i++){printf("%d ", *p);p += 4;}return 0;
}

? ? ? ? 代碼分析:

????????每次打印時,都讓p += 4,在打印1~10時恰好正確,

? ? ? ? 每次訪問都只會訪問第一個字節,后面三個字節是直接跳過的,所以兩位數的時候是正確的,但是數字大一些就會忽略掉第二個字節的數字,就會出錯

(二)指針 - 指針

? ? ? ? 【指針 - 指針】的運算前提條件兩個指針指向的是同一個空間,否則運算無意義;

????????指針 - 指針的【絕對值】,是指針和指針之間【元素的個數】

????????應用:求字符串長度 ,如下代碼演示:

#include <stdio.h>int my_strlen(char *s)
{char *p = s;//設置尾指針while(*p != '\0' )p++;return p-s;
}int main()
{printf("%d\n", my_strlen("abc"));return 0;
}

????????拓展:指針 + 指針?

????????答:無意義,類似于 【日期 +- 天數(計算日期)】、【日期 - 日期(算的是兩個日期之間差多少天)】有意義,而【日期 + 日期】無意義

(三)指針的關系運算(指針的比較)

????????應用:做判斷條件使用,數組中,若一個地址小于另一個地址,則執行語句

#include <stdio.h>int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);while(p<arr+sz) //指針的???較{printf("%d ", *p);p++;}return 0;
}

六、野指針

????????概念: 野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)

(一)野指針造成的原因

1、指針未初始化

????????指針變量也是局部變量,不初始化就會給隨機值;

????????如果將未初始化的指針變量的值作為地址來進行解引用操作,就會形成非法訪問

#include <stdio.h>int main()
{ int *p;//局部變量指針未初始化,默認為隨機值*p = 20;return 0;
}

2、指針越界訪問

#include <stdio.h>int main()
{int arr[10] = {0};int *p = &arr[0];int i = 0;for(i=0; i<=11; i++){//當指針指向的范圍超出數組arr的范圍時,p就是野指針*(p++) = i;}return 0;
}

3、指針指向的空間釋放

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

(二)如何規避野指針

1、指針初始化

????????如果明確知道指針指向哪里就直接賦值地址,如果不知道指針應該指向哪里,可以給指針賦值NULL,NULL 是C語言中定義的?個標識符常量,值是0(這個0在C語言中會被強制轉化為void*類型),0也是地址,這個地址是無法使用的,讀寫該地址會報錯

? ? ? ? 演示代碼如下:

#include <stdio.h>
int main()
{int num = 10;int* p1 = &num;int* p2 = NULL;return 0;
}

2、小心指針越界

?????????個程序向內存申請了哪些空間,通過指針也就只能訪問哪些空間,不能超出范圍訪問,超出了就是越界訪問

3、指針變量不再使用時,及時置NULL,指針使用之前檢查有效性

????????當指針變量指向?塊區域的時候,我們可以通過指針訪問該區域,后期不再使用這個指針訪問空間的時候,我們可以把該指針置為NULL;因為約定俗成的?個規則就是:只要是NULL指針就不去訪問,同時使用指針之前可以判斷指針是否為NULL

? ? ? ? 演示代碼如下:

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];for(int i = 0; i<10; i++){*(p++) = i;}//此時p已經越界了,可以把p置為NULLp = NULL;//下次使?的時候,判斷p不為NULL的時候再使?//...p = &arr[0];//重新讓p獲得地址if(p != NULL) //判斷{//...}return 0;
}

4、避免返回局部變量的地址

????????不要返回局部變量的地址

七、assert斷言

????????

????????assert.h 頭文件定義了宏 assert ( ) ,用于在運行時確保程序符合指定條件,如果不符合,就報錯終止運行,這個宏常常被稱為“斷言”

????????使用:#include <assert.h>;assert(表達式)

????????作用:判斷是否符合指定條件,如果不符合就會終止運行;【通常用來判斷指針變量的有效性】

????????判斷:判斷為真則程序繼續向下走,判斷為假則報錯

int* p = NULL;
...
assert(p != NULL); 
此處經過一些列的代碼后,若 p 不等于NULL則正常運行下去,若還是等于NULL,則程序報錯,終止運行

????????若想取消assert斷言,則在#include <assert.h>上面 #define NDEBUG;

????????assert斷言只在Debug版本中有效,在Release版本中會被優化掉

? ? ? ? 缺點:引入了額外的檢查,增加了程序的運行時間

八、指針的使用和傳址調用

(一)指針的使用:strlen的模擬實現

????????庫函數strlen的功能是求字符串?度,統計的是字符串中 \0 之前的字符的個數

????????函數原型如下:

size_t strlen ( const char * str );

????????參數str接收?個字符串的起始地址,然后開始統計字符串中 \0 之前的字符個數,最終返回長度;

????????如果要模擬實現只要從起始地址開始向后逐個字符的遍歷,只要不是 \0 字符,計數器就+1,這樣直到 \0 就停止,代碼如下:

size_t my_strlen(const char * str)
{int count = 0;assert(str);//為了保險,判斷傳來的是不是空地址while(*str){count++;str++;}return count;
}int main()
{size_t len = my_strlen("abcdef");printf("%zd\n", len);return 0;
}

????????注:代碼中的 const(不希望原值被修改)和 assert(保險判斷)來加強代碼使用時的健壯性(魯棒性)
?

(二)傳值調用和傳址調用

????????傳址調用,可以讓函數和主調函數之間建立真正的聯系,在函數內部可以修改主調函數中的變量;所以未來函數中只是需要主調函數中的變量值來實現計算,就可以采用傳值調用,如果函數內部要修改主調函數中的變量的值,就需要傳址調用


? ? ? ? 以上內容僅供分析,若有錯誤,請多多指正

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

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

相關文章

Ansible常用模塊

華子目錄 Ansible四個命令模塊1.組成2.特點3.區別3.1command、shell模塊3.2raw模塊 4.command模塊4.1參數表4.2free_form參數 5.shell模塊5.1作用5.2例如 6.script模塊6.1示例 7.raw模塊7.1參數7.2示例 文件操作模塊1.file模塊1.1參數1.2示例 2.copy模塊2.1參數 Ansible四個命令…

用4個方法檢查家里的燈是否傷孩子的眼睛

為什么小孩子帶眼鏡的越來越多&#xff1f;      現在的孩子都在樓上玩手機看電視&#xff0c;當然它就傷眼睛了      除了這些電子產品傷眼睛&#xff0c;還有一處隱形的因素被忽略了      你主要看4個標準      1&#xff0c;你看看燈的照度&#xff0c;有些…

ASRock Creator系列GPU:為AI推理及多GPU系統打造,采用16針電源接口的Radeon RX 7900系列顯卡

ASRock 正在籌備推出專為人工智能推理和多GPU系統設計的AMD GPU——Creator系列顯卡。這一系列顯卡采用雙槽位、吹風式設計&#xff0c;并配備16針電源連接器&#xff0c;首發產品包括基于Navi 31架構的AMD Radeon RX 7900XTX和RX 7900 XT型號。這些原屬于WS系列的顯卡最初在20…

2024年華為OD機試真題-小朋友來自多少小區-C++-OD統一考試(C卷D卷)

2024年OD統一考試(D卷)完整題庫:華為OD機試2024年最新題庫(Python、JAVA、C++合集) 題目描述: 幼兒園組織活動,老師布置了一個任務:每個小朋友去了解與自己同一個小區的小朋友還有幾個。我們將這些數量匯總到數組garden中。 請根據這些小朋友給出的信息,計算班級小朋…

機器學習與現代醫療設備的結合:革新醫療健康的未來

&#x1f3ac; 鴿芷咕&#xff1a;個人主頁 &#x1f525; 個人專欄: 《C干貨基地》《粉絲福利》 ??生活的理想&#xff0c;就是為了理想的生活! 引言 隨著技術的不斷進步&#xff0c;機器學習&#xff08;Machine Learning, ML&#xff09;在現代醫療設備中的應用正在改變著…

python基礎語法 006 內置函數

1 內置函數 材料參考&#xff1a;內置函數 — Python 3.12.4 文檔 Python 解釋器內置了很多函數和類型&#xff0c;任何時候都能直接使用 內置函數有無返回值&#xff0c;是python自己定義&#xff0c;不能以偏概全說都有返回值 以下為較為常用的內置函數&#xff0c;歡迎補充…

【華為OD題目0008-雙十一】

華為OD題目0008-雙十一 華為OD題目0008-雙十一 華為OD題目0008-雙十一 題目描述 雙十一眾多商品進行打折銷售&#xff0c;小明想購買一些自己心儀的商品&#xff0c; 但由于受購買資金限制&#xff0c;所以他決定從眾多心意商品中購買3件&#xff0c; 而且想盡可能的花完資金&…

什么是CTO?如何成為一名優秀的CTO?

一、什么是CTO&#xff1f; 首席技術官&#xff08;CTO&#xff09;是一位負責領導和管理企業技術戰略的高級職務。CTO的主要職責包括規劃技術戰略、監督研發活動、領導技術團隊等。 二、CTO的主要職責 首席技術官&#xff0c;即CTO&#xff0c;是企業中負責技術和研發的高級管…

Redies基礎篇(一)

Redis 是一個高性能的key-value數據庫。Redies支持存儲的value類型相對更多&#xff0c;包括string(字符串)、list(鏈表)、set(集合)和zset(有序集合)。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作&#xff0c;而且這些操作都是原子性的&#xff…

【ETABS】【RHINO】案例:Swallow to ETABS

文章目錄 01. Swallow Overview總覽1 LOAD&#xff1a;Defination of LoadCase、Response Combo2 SectionArea Section and Area Load&#xff08;面截面定義與指定&#xff0c;面荷載指定&#xff09;Frame Section with rebarattr and linear load&#xff08;帶鋼筋屬性框架…

下載,連接mysql數據庫驅動(最詳細)

前言 本篇博客&#xff0c;我講講如何連接數據庫&#xff1f;我使用mysql數據庫舉例。 目錄 下載對應的數據庫jar 包 百度網盤 存有8.4.0版本壓縮包&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/13uZtXRmuewHRbXaaCU0Xsw?pwduipy 提取碼&#xff1a;uipy 復制這…

STM32-TIM定時器

本內容基于江協科技STM32視頻內容&#xff0c;整理而得。 文章目錄 1. TIM1.1 TIM定時器1.2 定時器類型1.3 基本定時器1.4 通用定時器1.4 高級定時器1.5 定時中斷基本結構1.6 預分頻器時序1.7 計數器時序1.8 計數器無預裝時序1.9 計數器有預裝時序1.10 RCC時鐘樹 2. TIM庫函數…

前端面試題11(淺談JavaScript深拷貝與淺拷貝)

在JavaScript中&#xff0c;數據的復制可以分為淺拷貝&#xff08;Shallow Copy&#xff09;和深拷貝&#xff08;Deep Copy&#xff09;。這兩種拷貝方式主要區別在于如何處理對象中的嵌套對象。下面我會詳細解釋這兩者的概念、區別&#xff0c;并提供相應的實現代碼。 淺拷貝…

【機器學習實戰】Datawhale夏令營:Baseline精讀筆記2

# AI夏令營 # Datawhale # 夏令營 在原有的Baseline上除了交叉驗證&#xff0c;還有一種關鍵的優化方式&#xff0c;即特征工程。 如何優化特征&#xff0c;關系著我們提高模型預測的精準度。特征工程往往是對問題的領域有深入了解的人員能夠做好的部分&#xff0c;因為我們要…

鏈式二叉樹oj題

1.輸入k &#xff0c;找第k層節點個數 int TreeKlevel(BTNode*root,int k) {if (root NULL) {return 0;}if (k 1) {return 1;}return TreeKlevel(root->left, k - 1)TreeKlevel(root->right, k - 1); } 在這里我們要確定遞歸子問題&#xff0c;第一個就是NULL時返回&…

26_嵌入式系統網絡接口

以太網接口基本原理 IEEE802標準 局域網標準協議工作在物理層和數據鏈路層&#xff0c;其將數據鏈路層又劃分為兩層&#xff0c;從下到上分別為介質訪問控制子層(不同的MAC子層&#xff0c;與具體接入的傳輸介質相關),邏輯鏈路控制子層(統一的LLC子層&#xff0c;為上層提供統…

非同步升壓轉換器,效率95%你信嗎?ETA1611輸出電流2A, 22V DCDC

前言&#xff1a; 截止24年7月7日某創報價&#xff1a;500&#xff1a; &#xffe5;0.7856 / 個 建議使用前同時了解下方器件。 2毛錢的SOT23-5封裝28V、1.5A、1.2MHz DCDC轉換器用于LCD偏置電源和白光LED驅動等MT3540升壓芯片 描述 ETA1611 SOT23-6封裝 絲印GVYW&#xff0…

c進階篇(三):字符串函數

1.strlen: strlen - C Reference strlen 函數是一個標準庫函數&#xff0c;用于計算以 null 結尾的字符串的長度&#xff0c;也就是字符串中實際字符的數量&#xff0c;不包括最后的 null 終止符 \0。它定義在 <string.h> 頭文件中。 函數原型:size_t strlen(const ch…

一篇就夠了,為你答疑解惑:鋰電池一階模型-在線參數辨識(附代碼)

鋰電池一階模型-在線參數辨識 背景在線 VS 離線 參數辨識遞推最小二乘法一階戴維南Z域離散表達式 背景 鋰電池一階戴維南等效模型的基礎知識和離線辨識方法&#xff0c;已經在上一期非常詳細地講解了一輪&#xff08;上期文章請戳此處&#xff09;&#xff0c;本期繼續講解一下…

【數據結構】經典鏈表題目詳解集合(反轉鏈表、相交鏈表、鏈表的中間節點、回文鏈表)

文章目錄 一、反轉鏈表1、程序詳解2、代碼 二、相交鏈表1、程序詳解2、代碼 三、鏈表的中間節點1、程序詳解2、代碼 四、回文鏈表1、程序詳解2、代碼 一、反轉鏈表 1、程序詳解 題目&#xff1a;給定單鏈表的頭節點 head &#xff0c;請反轉鏈表&#xff0c;并返回反轉后的鏈…