色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

STM32中重要的C語言知識點整理

Q4MP_gh_c472c21 ? 來源:嵌入式ARM ? 作者:里米君 ? 2021-02-10 17:31 ? 次閱讀

說在前面的話

一位初學單片機的小伙伴讓我推薦C語言書籍,因為C語言基礎比較差,想把C語言重新學一遍,再去學單片機,我以前剛學單片機的時候也有這樣子的想法。

其實C語言是可以邊學單片機邊學的,學單片機的一些例程中,遇到不懂的C語言知識,再去查相關的知識點,這樣印象才會深刻些。

下面就列出了一些STM32中重要的C語言知識點,初學的小伙伴可以多讀幾遍,其中大多知識點之前都有寫過,這里重新整理一下,更詳細地分析解釋可以閱讀附帶的鏈接。

assert_param

斷言(assert)就是用于在代碼中捕捉這些假設,可以將斷言看作是異常處理的一種高級形式。

斷言表示為一些布爾表達式,程序員相信在程序中的某個特定點該表達式值為真。

可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言,而在部署時禁用斷言。同樣,程序投入運行后,最終用戶在遇到問題時可以重新啟用斷言。

注意assert()是一個宏,而不是函數。

在STM32中,常常會看到類似代碼:

assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
assert_param(IS_ADC_SINGLE_DIFFERENTIAL(SingleDiff));

這是用來檢查函數傳入的參數的有效性。STM32中的assert_param默認是不使用的,即:

2d8aa14a-5f65-11eb-8b86-12bb97331649.png

如果要使用,需要定義USE_FULL_ASSERT宏,并且需要自己實現assert_failed函數。特別的,使用STM32CubeMX生成代碼的話,會在main.c生成:

2fa39234-5f65-11eb-8b86-12bb97331649.png

我們在這進行填充就好。

下面分享一下assert的應用例子:

//公眾號:嵌入式大雜燴
#include
#include

intmain(void)
{
inta,b,c;
printf("請輸入b, c的值:");
scanf("%d%d",&b,&c);
a=b/c;
printf("a=%d",a);
return0;
}

此處,變量c作為分母是不能等于0,如果我們輸入2 0,結果是什么呢?結果是程序會蹦:

303ac62c-5f65-11eb-8b86-12bb97331649.png

這個例子中只有幾行代碼,我們很快就可以找到程序蹦的原因就是變量c的值為0。但是,如果代碼量很大,我們還能這么快的找到問題點嗎?

這時候,assert()就派上用場了,以上代碼中,我們可以在a = b / c;這句代碼之前加上assert(c);這句代碼用來判斷變量c的有效性。此時,再編譯運行,得到的結果為:

30e2ed20-5f65-11eb-8b86-12bb97331649.png

可見,程序蹦的同時還會在標準錯誤流中打印一條錯誤信息

Assertion failed:c, file hello.c, line 12

這條信息包含了一些對我們查找bug很有幫助的信息:問題出在變量c,在hello.c文件的第12行。這么一來,我們就可以迅速的定位到問題點了。

這時候細心的朋友會發現,上邊我們對assert()的介紹中,有這么一句說明:

如果表達式的值為假,assert()宏就會調用_assert函數在標準錯誤流中打印一條錯誤信息,并調用abort()(abort()函數的原型在stdlib.h頭文件中)函數終止程序。

所以,針對我們這個例子,我們的assert()宏我們也可以用以下代碼來代替:

if(0==c)
{
puts("c的值不能為0,請重新輸入!");
abort();
}

這樣,也可以給我們起到提示的作用:

310ebf90-5f65-11eb-8b86-12bb97331649.png

但是,使用assert()至少有幾個好處:

1)能自動標識文件和出問題的行號。

2)無需要更改代碼就能開啟或關閉assert機制(開不開啟關系到程序大小的問題)。如果認為已經排除了程序的bug,就可以把下面的宏定義寫在包含assert.h的位置的前面:

#defineNDEBUG

并重新編譯程序,這樣編輯器就會禁用工程文件中所有的assert()語句。如果程序又出現問題,可以移除這條#define指令(或把它注釋掉),然后重新編譯程序,這樣就可以重新啟用了assert()語句。

相關文章:【C語言筆記】assert()怎么用?

預處理指令

1、#error

#error"PleaseselectfirstthetargetSTM32L4xxdeviceusedinyourapplication(instm32l4xx.hfile)"

#error 指令讓預處理器發出一條錯誤信息,并且會中斷編譯過程。

#error的例子:

//公眾號:嵌入式大雜燴
#include

#defineRX_BUF_IDX100

#ifRX_BUF_IDX==0
staticconstunsignedintrtl8139_rx_config=0;
#elifRX_BUF_IDX==1
staticconstunsignedintrtl8139_rx_config=1;
#elifRX_BUF_IDX==2
staticconstunsignedintrtl8139_rx_config=2;
#elifRX_BUF_IDX==3
staticconstunsignedintrtl8139_rx_config=3;
#else
#error"Invalidconfigurationfor8139_RXBUF_IDX"
#endif

intmain(void)
{
printf("helloworld
");
return0;
}

這段示例代碼很簡單,當RX_BUF_IDX宏的值不為0~3時,在預處理階段就會通過#error 指令輸出一條錯誤提示信息:

"Invalid configuration for 8139_RXBUF_IDX"

下面編譯看一看結果:

31e7c60a-5f65-11eb-8b86-12bb97331649.png

2、#if、#elif、#else、#endif、#ifdef、#ifndef

(1)#if

#if(USE_HAL_ADC_REGISTER_CALLBACKS==1)
void(*ConvCpltCallback)(struct__ADC_HandleTypeDef*hadc);
//......
#endif/*USE_HAL_ADC_REGISTER_CALLBACKS*/

#if的使用一般使用格式如下

#if整型常量表達式1
程序段1
#elif整型常量表達式2
程序段2
#else
程序段3
#endif

執行起來就是,如果整形常量表達式為真,則執行程序段1,以此類推,最后#endif是#if的結束標志。

(2)#ifdef、#ifndef

#ifdefHAL_RTC_MODULE_ENABLED
#include"stm32l4xx_hal_rtc.h"
#endif/*HAL_RTC_MODULE_ENABLED*/

#ifdef的作用是判斷某個宏是否定義,如果該宏已經定義則執行后面的代碼,一般使用格式如下:

#ifdef宏名
程序段1
#else
程序段2
#endif

它的意思是,如果該宏已被定義過,則對程序段1進行編譯,否則對程序段2進行編譯,通#if一樣,#endif也是#ifdef的結束標志。

#ifndef__STM32L4xx_HAL_ADC_EX_H
#define__STM32L4xx_HAL_ADC_EX_H
//......
#endif

#ifndef的作用與#ifdef的作用相反,用于判斷某個宏是否沒被定義。

(3)#if defined、#if !defined

defined用于判斷某個宏是否被定義, !defined與defined的作用相反。這樣一來#if defined可以達到與#ifdef一樣的效果。如例子:

#ifdefined(STM32L412xx)
#include"stm32l412xx.h"
#elifdefined(STM32L422xx)
#include"stm32l422xx.h"
//........
#elifdefined(STM32L4S9xx)
#include"stm32l4s9xx.h"
#else
#error"PleaseselectfirstthetargetSTM32L4xxdeviceusedinyourapplication(instm32l4xx.hfile)"
#endif

如果STM32L412xx宏被定義,則包含頭文件stm32l412xx.h,以此類推。

既然已經有#ifdef、#ifndef了,#if defined與#if !defined是否是多余的?

不是的,#ifdef和#ifndef僅能一次判斷一個宏名,而defined能做到一次判斷多個宏名,例如:

#ifdefined(STM32L4R5xx)||defined(STM32L4R7xx)||defined(STM32L4R9xx)||defined(STM32L4S5xx)||defined(STM32L4S7xx)||defined(STM32L4S9xx)
//......
#endif/*STM32L4R5xx||STM32L4R7xx||STM32L4R9xx||STM32L4S5xx||STM32L4S7xx||STM32L4S9xx*/

更進一步,可以構建一些更密切地因果處理,如:

#ifdefined(__ARMCC_VERSION)&&(__ARMCC_VERSION
#definePI(3.14)
#defineR(6)

#ifdefined(PI)&&defined(R)
#defineAREA(PI*R*R)
#endif

3、#pragma指令

#pragma指令為我們提供了讓編譯器執行某些特殊操作提供了一種方法。這條指令對非常大的程序或需要使用特定編譯器的特殊功能的程序非常有用。

#pragma指令的一般形式為:#pragma para,其中,para為參數。如

#ifdefined(__GNUC__)
#pragmaGCCdiagnosticpush
#pragmaGCCdiagnosticignored"-Wsign-conversion"
#pragmaGCCdiagnosticignored"-Wconversion"
#pragmaGCCdiagnosticignored"-Wunused-parameter"
#endif

這一段的作用是忽略一些gcc的警告。#pragma命令中出現的命令集在不同的編譯器上是不一樣的,使用時必須查閱所使用的編譯器的文檔來了解有哪些命令、以及這些命令的功能。

下面簡單看一下#pragma命令的常見用法。

(1)、#pragma pack

我們可以利用#pragma pack來改變編譯器的對齊方式:

#pragmapack(n)/*指定按n字節對齊*/
#pragmapack()/*取消自定義字節對齊*/

我們使用#pragma pack指令來指定對齊的字節數。例子:

①指定按1字節對齊

32690288-5f65-11eb-8b86-12bb97331649.png

運行結果為:

32e162be-5f65-11eb-8b86-12bb97331649.png

②指定2字節對齊

3344df38-5f65-11eb-8b86-12bb97331649.png

運行結果為:

34721150-5f65-11eb-8b86-12bb97331649.png

可見,指定的對齊的字節數不一樣,得到的結果也不一樣。指定對齊有什么用呢,大概就是可以避免了移植過程中編譯器的差異帶來的代碼隱患吧。比如兩個編譯器的默認對齊方式不一樣,那可能會帶來一些bug。

(2)#pragma message

該指令用于在預處理過程中輸出一些有用的提示信息,如:

3504cc66-5f65-11eb-8b86-12bb97331649.png

運行結果為:

356976f2-5f65-11eb-8b86-12bb97331649.png

如上,我們平時可以在一些條件編譯塊中加上類似信息,因為在一些宏選擇較多的情況下,可能會導致代碼理解起來會混亂。不過現在一些編譯器、編輯器都會對這些情況進行一些很明顯的區分了,比如哪塊代碼沒有用到,那塊代碼的背景色就會是灰色的。

(3)#pragma warning

該指令允許選擇性地修改編譯器警告信息。

例子:

#pragmawarning(disable:450734;once:4385;error:164)

等價于:

#pragmawarning(disable:450734)//不顯示4507和34號警告信息
#pragmawarning(once:4385)//4385號警告信息僅報告一次
#pragmawarning(error:164)//把164號警告信息作為一個錯

這個指令暫且了解這么多,知道有這么一回事就可以。

關于#pragma指令還有很多用法,但比較冷門,這里暫且不列舉,有興趣的朋友可以自行學習。

相關文章:認識認識#pragma、#error指令

extern "C"

#ifndef__STM32L4S7xx_H
#define__STM32L4S7xx_H

#ifdef__cplusplus
extern"C"{
#endif/*__cplusplus*/

#ifdef__cplusplus
}
#endif/*__cplusplus*/

#endif/*__STM32L4S7xx_H*/

加上extern "C"后,會指示編譯器這部分代碼按C語言(而不是C++)的方式進行編譯。因為C、C++編譯器對函數的編譯處理是不完全相同的,尤其對于C++來說,支持函數的重載,編譯后的函數一般是以函數名和形參類型來命名的。

例如函數void fun(int, int),編譯后的可能是_fun_int_int(不同編譯器可能不同,但都采用了類似的機制,用函數名和參數類型來命名編譯后的函數名);而C語言沒有類似的重載機制,一般是利用函數名來指明編譯后的函數名的,對應上面的函數可能會是_fun這樣的名字。

相關文章:干貨 | extern "C"的用法解析

#與##運算符

#define__STM32_PIN(index,gpio,gpio_index)
{
index,GPIO##gpio##_CLK_ENABLE,GPIO##gpio,GPIO_PIN_##gpio_index
}

1、#運算符

我們平時使用帶參宏時,字符串中的宏參數是沒有被替換的。例如:

35aeaa24-5f65-11eb-8b86-12bb97331649.jpg

輸出結果為:

36103dde-5f65-11eb-8b86-12bb97331649.jpg

然而,我們期望輸出的結果是:

5+20=25
13+14=27

這該怎么做呢?其實,C語言允許在字符串中包含宏參數。在類函數宏(帶參宏)中,#號作為一個預處理運算符,可以把記號轉換成字符串。

例如,如果A是一個宏形參,那么#A就是轉換為字符串"A"的形參名。這個過程稱為字符串化(stringizing)。以下程序演示這個過程:

3659ffc8-5f65-11eb-8b86-12bb97331649.jpg

輸出結果為:

368ee36e-5f65-11eb-8b86-12bb97331649.jpg

這就達到我們想要的結果了。所以,#運算符可以完成字符串化(stringizing)的過程。

2、##運算符

與#運算符類似,##運算符可用于類函數宏(帶參宏)的替換部分。##運算符可以把兩個記號組合成一個記號。例如,可以這樣做:

#defineXNAME(n)x##n

然后,宏XNAME(4)將展開x4。以下程序演示##運算符的用法:

39f2fc7a-5f65-11eb-8b86-12bb97331649.jpg

輸出結果為:

3d91189e-5f65-11eb-8b86-12bb97331649.jpg

注意:PRINT_XN()宏用#運算符組合字符串,##運算符把記號組合為一個新的標識符。

其實,##運算符在這里看來并沒有起到多大的便利,反而會讓我們感覺到不習慣。但是,使用##運算符有時候是可以提高封裝性及程序的可讀性的。

相關文章:這兩個C運算符你可能沒用過,但卻很有用~

_IO、 _I、 _O、volatile

一些底層結構體成員中,常常使用_IO、 _O、 _I這三個宏來修飾,如:

typedefstruct
{
__IOuint32_tTIR;/*!

而這三個宏其實是volatile的替換,即:

#define__Ivolatile/*!

volatile的作用就是不讓編譯器進行優化,即每次讀取或者修改值的時候,都必須重新從內存或者寄存器中讀取或者修改。在我們嵌入式中, volatile 用在如下的幾個地方:

中斷服務程序中修改的供其它程序檢測的變量需要加 volatile;

多任務環境下各任務間共享的標志應該加 volatile;

存儲器映射的硬件寄存器通常也要加 volatile 說明,因為每次對它的讀寫都可能由不 同意義;

例如:

/*假設REG為寄存器的地址*/
uint32*REG;
*REG=0;/*點燈*/
*REG=1;/*滅燈*/

此時若是REG不加volatile進行修飾,則點燈操作將被優化掉,只執行滅燈操作。

位操作

STM32中,使用外設都得先配置其相關寄存器,都是使用一些位操作。比如庫函數的內部實現就是一些位操作:

staticvoidTI4_Config(TIM_TypeDef*TIMx,uint16_tTIM_ICPolarity,uint16_tTIM_ICSelection,
uint16_tTIM_ICFilter)
{
uint16_ttmpccmr2=0,tmpccer=0,tmp=0;

/*DisabletheChannel4:ResettheCC4EBit*/
TIMx->CCER&=(uint16_t)~TIM_CCER_CC4E;
tmpccmr2=TIMx->CCMR2;
tmpccer=TIMx->CCER;
tmp=(uint16_t)(TIM_ICPolarity<CCMR2=tmpccmr2;
TIMx->CCER=tmpccer;
}

看似很復雜,其實就是按照規格書來配置就可以。雖然實際應用中,很少會采用直接配置寄存器的方法來使用,但是也需要掌握,一些特殊的地方可以直接操控寄存器,比如中斷中。

位操作簡單例子:

首先,以下是按位運算符:

3dd5a702-5f65-11eb-8b86-12bb97331649.png

在嵌入式編程中,常常需要對一些寄存器進行配置,有的情況下需要改變一個字節中的某一位或者幾位,但是又不想改變其它位原有的值,這時就可以使用按位運算符進行操作。下面進行舉例說明,假如有一個8位的TEST寄存器:

3e4bb1fe-5f65-11eb-8b86-12bb97331649.png

當我們要設置第0位bit0的值為1時,可能會這樣進行設置:

TEST=0x01;

但是,這樣設置是不夠準確的,因為這時候已經同時操作到了高7位:bit1~bit7,如果這高7位沒有用到的話,這么設置沒有什么影響;但是,如果這7位正在被使用,結果就不是我們想要的了。

在這種情況下,我們就可以借用按位操作運算符進行配置。

對于二進制位操作來說,不管該位原來的值是0還是1,它跟0進行&運算,得到的結果都是0,而跟1進行&運算,將保持原來的值不變;不管該位原來的值是0還是1,它跟1進行|運算,得到的結果都是1,而跟0進行|運算,將保持原來的值不變。

所以,此時可以設置為:

TEST=TEST|0x01;

其意義為:TEST寄存器的高7位均不變,最低位變成1了。在實際編程中,常改寫為:

TEST|=0x01;

這種寫法可以一定程度上簡化代碼,是 C 語言常用的一種編程風格。設置寄存器的某一位還有另一種操作方法,以上的等價方法如:

TEST|=(0x01<

第幾位要置1就左移幾位。

同樣的,要給TEST的低4位清0,高4位保持不變,可以進行如下配置:

TEST&=0xF0;

相關文章:C語言、嵌入式位操作精華技巧大匯總

do {}while(0)

這是在宏定義中用的,STM32的標準庫中沒有使用這種用法,HAL庫中有大量的用法例子,如:

#define__HAL_FLASH_INSTRUCTION_CACHE_RESET()do{SET_BIT(FLASH->ACR,FLASH_ACR_ICRST);
CLEAR_BIT(FLASH->ACR,FLASH_ACR_ICRST);
}while(0)

下面以一個例子來分析do {}while(0)的用法:

//公眾號:嵌入式大雜燴
#defineDEBUG1

#ifDEBUG
#defineDBG_PRINTF(fmt,args...)
{
printf("<>",__FILE__,__LINE__,__FUNCTION__);
printf(fmt,##args);
}
#else
#defineDBG_PRINTF(fmt,args...)
#endif

這個宏打印有什么缺陷?

我們與if、else使用的時候,會有這樣的一種使用情況:

3eb2b3c2-5f65-11eb-8b86-12bb97331649.png

此時會報語法錯誤。為什么呢?

同樣的,我們可以先來看一下我們的demo代碼預處理過后,相應的宏代碼會被轉換為什么。如:

3ef6807a-5f65-11eb-8b86-12bb97331649.png

這里我們可以看到,我們的if、else結構代碼被替換為如下形式:

if(c)
{/*.......*/};
else
{/*.......*/};

顯然,出現了語法錯誤。if之后的大括號之后不能加分號,這里的分號其實可以看做一條空語句,這個空語句會把if與else給分隔開來,導致else不能正確匹配到if,導致語法錯誤。

為了解決這個問題,有幾種方法。第一種方法是:把分號去掉。代碼變成:

3fcd7b2a-5f65-11eb-8b86-12bb97331649.png

第二種方法是:在if之后使用DBG_PRINTF打印調試時總是加{}。代碼變成:

400db794-5f65-11eb-8b86-12bb97331649.png

以上兩種方法都可以正常編譯、運行了。

但是,我們C語言中,每條語句往往以分號結尾;并且,總有些人習慣在if判斷之后只有一條語句的情況下不加大括號;而且我們創建的DBG_PRINTF宏函數的目的就是為了對標printf函數,printf函數的使用加分號在任何地方的使用都是沒有問題的。

基于這幾個原因,我們有必要再對我們的DBG_PRINTF宏函數進行一個改造。

下面引入do{}while(0)來對我們的DBG_PRINTF進行一個簡單的改造。改造后的DBG_PRINTF宏函數如下:

#defineDBG_PRINTF(fmt,args...)
do
{
printf("<>",__FILE__,__LINE__,__FUNCTION__);
printf(fmt,##args);
}while(0)

這里的do...while循環的循環體只執行一次,與不加循環是效果一樣。并且,可以避免了上面的問題。預處理文件:

4070f78c-5f65-11eb-8b86-12bb97331649.png

我們的宏函數實體中,while(0)后面不加分號,在實際調用時補上分號,既符合了C語言語句分號結尾的習慣,也符合了do...while的語法規則。

使用do{}while(0)來封裝宏函數可能會讓很多初學者看著不習慣,但必須承認的是,這確確實實是一種很常用的方法。

推薦文章:C語言、嵌入式中幾個非常實用的宏技巧

static與extern

1、static

40eb53a6-5f65-11eb-8b86-12bb97331649.png

static主要有三種用法:在函數內用于修飾變量、用于修飾函數、用于修飾本.c文件全局變量。后兩個容易理解,用于修飾函數與全局變量表明變量與函數在本模塊內使用。

下面看看static在函數內用于修飾變量的例子:

//公眾號:嵌入式大雜燴
#include

voidtest(void)
{
intnormal_var=0;
staticintstatic_var=0;

printf("normal_var:%dstatic_var:%d
",normal_var,static_var);
normal_var++;
static_var++;
}

intmain(void)
{
inti;

for(i=0;i

運行結果:

4165b448-5f65-11eb-8b86-12bb97331649.jpg

可以看出,函數每次被調用,普通局部變量都是重新分配,而static修飾的變量保持上次調用的值不變,即只被初始化一次。

2、extern

extern的用法簡單,用于聲明多個模塊共享的全局變量、聲明外部函數。

42255c58-5f65-11eb-8b86-12bb97331649.png

責任編輯:xj

原文標題:STM32中C語言知識點:初學者必看,老鳥復習(長文總結)

文章出處:【微信公眾號:嵌入式ARM】歡迎添加關注!文章轉載請注明出處。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2270

    文章

    10896

    瀏覽量

    355781
  • C語言
    +關注

    關注

    180

    文章

    7604

    瀏覽量

    136713
  • 開發板
    +關注

    關注

    25

    文章

    5035

    瀏覽量

    97386

原文標題:STM32中C語言知識點:初學者必看,老鳥復習(長文總結)

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    接口測試理論、疑問收錄與擴展相關知識點

    本文章使用王者榮耀游戲接口、企業微信接口的展示結合理論知識,講解什么是接口測試、接口測試理論、疑問收錄與擴展相關知識點知識學院,快來一起看看吧~
    的頭像 發表于 11-15 09:12 ?308次閱讀
    接口測試理論、疑問收錄與擴展相關<b class='flag-5'>知識點</b>

    C語言C++結構體的區別

    同樣是結構體,看看在C語言C++中有什么區別?
    的頭像 發表于 10-30 15:11 ?199次閱讀

    C語言與Java語言的對比

    C語言和Java語言都是當前編程領域中的重要成員,它們各自具有獨特的優勢和特點,適用于不同的應用場景。以下將從語法特性、內存管理、跨平臺性、性能、應用領域等多個方面對
    的頭像 發表于 10-29 17:31 ?318次閱讀

    C語言與其他編程語言的比較

    C語言作為一種歷史悠久的編程語言,自其誕生以來,一直在軟件開發領域扮演著重要角色。它以其高效、靈活和可移植性強的特點,成為了系統級編程的首選語言
    的頭像 發表于 10-29 17:30 ?265次閱讀

    技術干貨驛站 ▏深入理解C語言:掌握程序結構知識

    在計算機編程的世界C語言被廣泛認可為一門強大而高效的編程語言,其簡潔的語法和直接的指令使得它成為了許多程序員的首選。了解C
    的頭像 發表于 07-27 08:45 ?1360次閱讀
    技術干貨驛站 ▏深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:掌握程序結構<b class='flag-5'>知識</b>

    C++語言基礎知識

    電子發燒友網站提供《C++語言基礎知識.pdf》資料免費下載
    發表于 07-19 10:58 ?7次下載

    PLC編程語言C語言的區別

    在工業自動化和計算機編程領域中,PLC(可編程邏輯控制器)編程語言C語言各自扮演著重要的角色。盡管兩者都是編程語言,但它們在多個方面存在顯
    的頭像 發表于 06-14 17:11 ?2789次閱讀

    stm32單片機學習路線

    第一步 編程及硬件基礎知識 1.掌握C語言基礎 作為STM32的主要編程語言C
    發表于 05-10 15:34

    模擬電子技術知識點問題總結概覽

    給大家分享模擬電子技術知識點問題總結。
    的頭像 發表于 05-08 15:16 ?1149次閱讀
    模擬電子技術<b class='flag-5'>知識點</b>問題總結概覽

    如何成為一名嵌入式C語言高手?

    。 三、通過實踐項目提升技能理論知識是建立在實踐基礎之上的。選擇一些小型的嵌入式項目,例如LED閃爍、溫度監測等簡單的應用,將所學的C語言知識應用到實際
    發表于 04-07 16:03

    如何成為一名嵌入式C語言高手?

    。 三、通過實踐項目提升技能理論知識是建立在實踐基礎之上的。選擇一些小型的嵌入式項目,例如LED閃爍、溫度監測等簡單的應用,將所學的C語言知識應用到實際
    發表于 03-25 14:12

    收藏!IGBT7系列分立器件核心知識點最全整理

    英飛凌IGBT7單管系列,作為目前炙手可熱的光儲應用新星產品,正受到眾多玩家的追捧。本篇文章特地為大家貼心整理該系列產品的核心知識大全,希望大家買得放心,用得順手~ 更全型號選擇,總有一款適合你
    的頭像 發表于 03-13 15:14 ?473次閱讀
    收藏!IGBT7系列分立器件核心<b class='flag-5'>知識點</b>最全<b class='flag-5'>整理</b>!

    IGBT7系列分立器件核心知識點最全整理

    英飛凌IGBT7單管系列,作為目前炙手可熱的光儲應用新星產品,正受到眾多玩家的追捧。本篇文章特地為大家貼心整理該系列產品的核心知識大全,希望大家買得放心,用得順手~更全型號選擇,總有一款適合你
    的頭像 發表于 02-23 08:13 ?516次閱讀
    IGBT7系列分立器件核心<b class='flag-5'>知識點</b>最全<b class='flag-5'>整理</b>!

    c語言,c++,java,python區別

    C語言C++、Java和Python是四種常見的編程語言,各有優點和特點。 C語言
    的頭像 發表于 02-05 14:11 ?2371次閱讀

    淺談初級電工必備知識點

    對于初學電工的朋友來說,掌握一些基礎且實用的知識點是非常重要的。本文旨在分享初級電工應該掌握的核心知識,幫助新手電工更好地入門和提升技能。
    的頭像 發表于 12-26 10:44 ?1095次閱讀
    主站蜘蛛池模板: 国产免费变态视频网址网站| 狠狠干女人| 精品日韩视频| 欧美 亚洲 日韩 中文2019| 天天色狠狠干| 60老妇性xxxxhd| 国产a级黄色毛片| 久久中文字幕亚洲| 私人玩物黑丝| 2017必看无码作品| 国产精品亚洲欧美| 蜜桃99影院| 亚洲成AV人片一区二区不卡| 98久久人妻无码精品系列蜜桃| 国产睡熟迷奷系列精品| 男女做爽爽爽视频免费软件| 性奴公司 警花| JAPANRCEP老熟妇乱子伦视频| 国产午夜小视频| 欧美在线看费视频在线| 夜夜躁日日躁狠狠| 高清国产在线观看| 美女胸网站| 97在线视频免费观看97| 冰山高冷受被c到哭np双性 | fyeex性欧美人与曾| 国产人成无码视频在线观看 | 肉肉高潮液体高干文H| 在线中文字幕亚洲日韩| 国产乱国产乱老熟300部视频| 欧美极限变态扩张video| 野花韩国在线观看| 国产精品久久久久影院免费| 免费看到湿的小黄文软件APP| 亚洲精品视频在线免费| 国产91网站在线观看免费| 男女AA片免费| 曰产无码久久久久久精品| 国产精品无码麻豆放荡AV| 强奸日本美女小游戏| 538在线播放|