找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3578|回復(fù): 26
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)C語(yǔ)言定義一個(gè)變量,如果不賦值,難道不是默認(rèn)等于0嘛

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1022479 發(fā)表于 2023-2-9 20:40 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式

今天測(cè)試了一下按鍵控制蜂鳴器,具體程序見附件
想要實(shí)現(xiàn)按鍵按下,蜂鳴器響,按鍵按下,蜂鳴器關(guān)的功能
這個(gè)按道理很簡(jiǎn)單,可是實(shí)際操作時(shí)發(fā)現(xiàn)了程序里一個(gè)奇怪現(xiàn)象!。
按鍵檢測(cè)使用的是GPIO上拉輸入模式,也就是空懸為高電平
這樣按下按鍵之后檢測(cè)到低電平剛好合適
按鍵一端接gnd,一端接PB0,PB11這里未使用
蜂鳴器是買的低電平驅(qū)動(dòng)的小模塊,3V到5V都兼容,這里只用到了PA1,PA2未使用
具體程序如下
這是蜂鳴器的初始化和翻轉(zhuǎn)單片機(jī)程序
/********************************
#include"stm32f10x.h"                 // Device header

voidLED_Init(void) //也可用蜂鳴器低電平驅(qū)動(dòng)代替
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_1 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;

GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_SetBits(GPIOA,GPIO_Pin_1 | GPIO_Pin_2);//初始設(shè)置高,防止開始低電平驅(qū)動(dòng)蜂鳴器
}
void LED1_Turn(void) //蜂鳴器狀態(tài)翻轉(zhuǎn)程序
{
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==1)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
elseif(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1)==0)
{
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
}
*********************************************/
這是按鍵的相關(guān)程序
/*****************************************
#include"stm32f10x.h"                 // Device header
#include"Delay.h"
void Key_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉輸入,懸空時(shí)為高電平,適合按鍵
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//只對(duì)輸出管用,這里輸入隨便填

GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_1 | GPIO_Pin_11);//初始設(shè)置高,防止低電平驅(qū)動(dòng)蜂鳴器
}

uint8_tGet_KeyNum(void)
{
uint8_t KeyNum = 0;//定義一個(gè)局部變量未檢測(cè)為0,一定要加=0。!
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1)== 0)
{
Delay_ms(20);//按下消抖
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) ==0);  //沒有松手一直執(zhí)行這條
Delay_ms(20);//松開消抖
KeyNum= 1;
}        
if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11)== 0)
{
Delay_ms(20);//按下消抖
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) ==0);  //沒有松手一直執(zhí)行這條,用來(lái)確認(rèn)松手
Delay_ms(20);//松開消抖
KeyNum= 11;
}
returnKeyNum;
}
**********************************************/
以下是main.c內(nèi)的所有調(diào)用函數(shù)
/********************************************
#include"stm32f10x.h"                 // Device header
#include"Delay.h"
#include"LED.h"
#include"Key.h"

#define di 100


int main(void)
{
uint8_t KeyNum; //main函數(shù)內(nèi)局部變量
LED_Init();
Key_Init();

while(1)
{
KeyNum= Get_KeyNum();

if(KeyNum==1) //PB1按鍵按下
{
LED1_Turn();//PA1翻轉(zhuǎn)

}

}
}
*********************************************/
以上看上去確實(shí)沒有問題對(duì)吧,實(shí)際上也沒有問題,
因?yàn)檫@是我發(fā)現(xiàn)問題之后,修正過的程序
真正的問題在于,
原來(lái)的程序里只有一條語(yǔ)句與這不一樣,
那就是按鍵的相關(guān)程序里面的
uint8_tGet_KeyNum(void)函數(shù)里的

第一行的uint8_tKeyNum = 0;  這樣寫達(dá)到了我的目的:按鍵按下,蜂鳴器響,按鍵按下,蜂鳴器關(guān)

原先我寫的是uint8_t KeyNum;這樣執(zhí)行只有按著按鍵的時(shí)候蜂鳴器才會(huì)響???非常奇怪的現(xiàn)象

在我學(xué)習(xí)51單片機(jī)的過程中,老師一直對(duì)我說(shuō)的是,如果定義一個(gè)變量,不給它賦初值,默認(rèn)為0。
現(xiàn)在看起來(lái)好像是我理解有問題。。。。
uint8_tKeyNum = 0;和uint8_t KeyNum;有啥區(qū)別???
如果沒有區(qū)別,為什么現(xiàn)象不一樣???
局部變量里面定義了之后,
如果不賦值
Return 返回的難道不是0???是個(gè)隨記數(shù)??也不對(duì)啊,求賜教?
不能理解,所以想請(qǐng)教各位大佬,如覺幼稚,請(qǐng)多多指教。

3-3按鍵控制LED.7z

174.89 KB, 下載次數(shù): 3

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:883242 發(fā)表于 2023-2-10 00:14 | 只看該作者
全局變量默認(rèn)才是0,如果你老師沒講錯(cuò),那就是你記錯(cuò)了。

建議你看看《數(shù)據(jù)結(jié)構(gòu)》這本書,遞歸那一章很好的說(shuō)明了c語(yǔ)言局部變量是從哪里來(lái)的,如果你看懂了的話,就很容易知道為什么不是0。

另外,MDK是符合c語(yǔ)言標(biāo)準(zhǔn)的,C51不符合c語(yǔ)言標(biāo)準(zhǔn),《數(shù)據(jù)結(jié)構(gòu)》對(duì)局部變量的描寫符合MDK,不符合C51。
回復(fù)

使用道具 舉報(bào)

板凳
ID:1061331 發(fā)表于 2023-2-10 02:13 | 只看該作者
不確定。 但一般情況是,靜態(tài)變量(static)與全局變量都默認(rèn)為0,局部變量值不確定(很多情況下不為0)。
回復(fù)

使用道具 舉報(bào)

地板
ID:213173 發(fā)表于 2023-2-10 06:27 | 只看該作者
全局變量是個(gè)人專用衛(wèi)生間,用后離開到下次再用內(nèi)部環(huán)境不變。局部變量是公共衛(wèi)生間,用后離開到下次再用內(nèi)部環(huán)境不確定?赡芫砑埑榭樟,馬桶還沒沖。所以局部變量一定要先賦值再使用,函數(shù)退出時(shí),將釋放其空間。
回復(fù)

使用道具 舉報(bào)

5#
ID:596109 發(fā)表于 2023-2-10 09:04 | 只看該作者
通常情況下定義變量緊跟著就給賦個(gè)初值,就是為了防止函數(shù)每次調(diào)用時(shí)局部變量值的不確定
回復(fù)

使用道具 舉報(bào)

6#
ID:844772 發(fā)表于 2023-2-10 10:26 | 只看該作者
要看編譯器的處理方式,不過只有靜態(tài)變量才可能初始化為0,局部變量是動(dòng)態(tài)的,就是隨機(jī)數(shù)了。
回復(fù)

使用道具 舉報(bào)

7#
ID:146782 發(fā)表于 2023-2-10 11:28 | 只看該作者
定義變量后及時(shí)賦個(gè)初始值是個(gè)好的習(xí)慣
!
回復(fù)

使用道具 舉報(bào)

8#
ID:1039954 發(fā)表于 2023-2-10 11:29 | 只看該作者
最近剛好遇到這個(gè)問題,把局部轉(zhuǎn)成靜態(tài)變量就好了
回復(fù)

使用道具 舉報(bào)

9#
ID:1022479 發(fā)表于 2023-2-10 11:54 | 只看該作者
Hephaestus 發(fā)表于 2023-2-10 00:14
全局變量默認(rèn)才是0,如果你老師沒講錯(cuò),那就是你記錯(cuò)了。

建議你看看《數(shù)據(jù)結(jié)構(gòu)》這本書,遞歸那一章很 ...

感謝大佬,學(xué)校安排的只有c語(yǔ)言程序設(shè)計(jì),還是大一學(xué)的,現(xiàn)在看來(lái)還是學(xué)的太淺了
我會(huì)去學(xué)學(xué)數(shù)據(jù)結(jié)構(gòu)的,這本書聽說(shuō)過,趕緊整一本回去惡補(bǔ)
回復(fù)

使用道具 舉報(bào)

10#
ID:1059013 發(fā)表于 2023-2-10 13:40 | 只看該作者
鄭常椿 發(fā)表于 2023-2-10 11:54
感謝大佬,學(xué)校安排的只有c語(yǔ)言程序設(shè)計(jì),還是大一學(xué)的,現(xiàn)在看來(lái)還是學(xué)的太淺了
我會(huì)去學(xué)學(xué)數(shù)據(jù)結(jié)構(gòu)的 ...

我單片機(jī)C編程搞得不錯(cuò),但是從來(lái)不看什么數(shù)據(jù)結(jié)構(gòu),如何?
回復(fù)

使用道具 舉報(bào)

11#
ID:883242 發(fā)表于 2023-2-10 16:58 | 只看該作者
c編程搞得不錯(cuò)有兩種,一種是真的不錯(cuò),另一種是井蛙級(jí)搞得不錯(cuò),樓上顯然是后一種。
回復(fù)

使用道具 舉報(bào)

12#
ID:883242 發(fā)表于 2023-2-10 20:47 | 只看該作者
補(bǔ)充一下,如果樓主搞過Windows編程,會(huì)遇到著名的“手持兩把錕斤拷,口中疾呼燙燙燙”的問題,此問題的根源就是初始化以后的堆棧里面并不是0。
回復(fù)

使用道具 舉報(bào)

13#
ID:1034262 發(fā)表于 2023-2-10 22:01 | 只看該作者
不一定,所以一定要養(yǎng)成清內(nèi)存或給變量初值的習(xí)慣。
回復(fù)

使用道具 舉報(bào)

14#
ID:879348 發(fā)表于 2023-2-13 14:18 | 只看該作者
當(dāng)然不是,RAM上是隨機(jī)值,很多單片機(jī),包括51單片機(jī),STM32單片機(jī)等進(jìn)入mian前還有一段代碼初始化
回復(fù)

使用道具 舉報(bào)

15#
ID:130230 發(fā)表于 2023-2-13 18:00 | 只看該作者
局部變量是定義在棧上的,如果不加static修飾在退出函數(shù)后會(huì)釋放該空間。所以這個(gè)變量每次進(jìn)入函數(shù)都是不同的地址,所以如果這個(gè)地址剛好被某個(gè)函數(shù)使用過那么初始值就不是0.
回復(fù)

使用道具 舉報(bào)

16#
ID:130230 發(fā)表于 2023-2-13 18:03 | 只看該作者
鄭常椿 發(fā)表于 2023-2-10 11:54
感謝大佬,學(xué)校安排的只有c語(yǔ)言程序設(shè)計(jì),還是大一學(xué)的,現(xiàn)在看來(lái)還是學(xué)的太淺了
我會(huì)去學(xué)學(xué)數(shù)據(jù)結(jié)構(gòu)的 ...

這不是數(shù)據(jù)結(jié)構(gòu)的內(nèi)容,是鏈接和作用域的內(nèi)容?匆槐閏 primer plus后把基礎(chǔ)搞清楚再看數(shù)據(jù)結(jié)構(gòu)吧。尤其是指針要搞透徹。
回復(fù)

使用道具 舉報(bào)

17#
ID:883242 發(fā)表于 2023-2-15 17:10 | 只看該作者
對(duì)于標(biāo)準(zhǔn)c語(yǔ)言來(lái)說(shuō),局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關(guān)系,局部變量是怎么來(lái)的,又是怎么沒的,只有《數(shù)據(jù)結(jié)構(gòu)》里面遞歸一節(jié)說(shuō)的最清楚。

對(duì)于不遵守標(biāo)準(zhǔn)的野路子編譯器,比如Keil C51才跟鏈接有關(guān)。
回復(fù)

使用道具 舉報(bào)

18#
ID:130230 發(fā)表于 2023-2-16 17:57 | 只看該作者
Hephaestus 發(fā)表于 2023-2-15 17:10
對(duì)于標(biāo)準(zhǔn)c語(yǔ)言來(lái)說(shuō),局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關(guān)系,局部變量是怎么來(lái)的,又是怎么 ...

你確定你學(xué)過C語(yǔ)言?數(shù)據(jù)結(jié)構(gòu)怎么和c語(yǔ)言綁定了搞不懂。。。
回復(fù)

使用道具 舉報(bào)

19#
ID:883242 發(fā)表于 2023-2-16 19:11 | 只看該作者
jizhongbiao 發(fā)表于 2023-2-16 17:57
你確定你學(xué)過C語(yǔ)言?數(shù)據(jù)結(jié)構(gòu)怎么和c語(yǔ)言綁定了搞不懂。。。

c語(yǔ)言教科書一般不會(huì)告訴你局部變量是怎么來(lái)的,又是怎么沒的,《數(shù)據(jù)結(jié)構(gòu)》會(huì)講。

你說(shuō)一本講局部變量來(lái)歷的教科書好了。
回復(fù)

使用道具 舉報(bào)

20#
ID:844772 發(fā)表于 2023-2-16 23:24 來(lái)自手機(jī) | 只看該作者
Hephaestus 發(fā)表于 2023-2-16 19:11
c語(yǔ)言教科書一般不會(huì)告訴你局部變量是怎么來(lái)的,又是怎么沒的,《數(shù)據(jù)結(jié)構(gòu)》會(huì)講。

你說(shuō)一本講局部變 ...

學(xué)沒學(xué)過數(shù)據(jù)結(jié)構(gòu)是程序員的一個(gè)分水嶺,你沒法跟沒學(xué)過數(shù)據(jù)結(jié)構(gòu)的人講清楚原因的,但可以出個(gè)題,比如如何寫個(gè)走迷宮程序
回復(fù)

使用道具 舉報(bào)

21#
ID:59202 發(fā)表于 2023-2-17 09:28 | 只看該作者
養(yǎng)成良好的編程習(xí)慣是對(duì)的,否則會(huì)經(jīng)常出現(xiàn)一些讓人頭疼的小問題
回復(fù)

使用道具 舉報(bào)

22#
ID:883242 發(fā)表于 2023-2-17 19:30 | 只看該作者
glinfei 發(fā)表于 2023-2-16 23:24
學(xué)沒學(xué)過數(shù)據(jù)結(jié)構(gòu)是程序員的一個(gè)分水嶺,你沒法跟沒學(xué)過數(shù)據(jù)結(jié)構(gòu)的人講清楚原因的,但可以出個(gè)題,比如如 ...

夏蟲不可語(yǔ)冰,井蛙不可語(yǔ)海。
回復(fù)

使用道具 舉報(bào)

23#
ID:146878 發(fā)表于 2023-2-17 21:58 | 只看該作者
定義變量隨手賦值是好習(xí)慣,很多低端單片機(jī),是不處理內(nèi)存初始狀態(tài)的。
回復(fù)

使用道具 舉報(bào)

24#
ID:965301 發(fā)表于 2023-2-20 17:36 | 只看該作者
單片機(jī)C語(yǔ)言變量默認(rèn)值有可能不為0,是隨機(jī)數(shù),給編譯器有關(guān)。
回復(fù)

使用道具 舉報(bào)

25#
ID:130230 發(fā)表于 2023-2-21 18:01 | 只看該作者
Hephaestus 發(fā)表于 2023-2-16 19:11
c語(yǔ)言教科書一般不會(huì)告訴你局部變量是怎么來(lái)的,又是怎么沒的,《數(shù)據(jù)結(jié)構(gòu)》會(huì)講。

你說(shuō)一本講局部變 ...

所有的教科書都會(huì)講啊
回復(fù)

使用道具 舉報(bào)

26#
ID:130230 發(fā)表于 2023-2-21 18:03 | 只看該作者
Hephaestus 發(fā)表于 2023-2-15 17:10
對(duì)于標(biāo)準(zhǔn)c語(yǔ)言來(lái)說(shuō),局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關(guān)系,局部變量是怎么來(lái)的,又是怎么 ...

你所謂的遞歸講了是恰好因?yàn)檫f歸使用了棧,棧是作用域的內(nèi)容啊。。。算了這論壇水平是在是有限。
回復(fù)

使用道具 舉報(bào)

27#
ID:130230 發(fā)表于 2023-2-21 18:04 | 只看該作者
glinfei 發(fā)表于 2023-2-16 23:24
學(xué)沒學(xué)過數(shù)據(jù)結(jié)構(gòu)是程序員的一個(gè)分水嶺,你沒法跟沒學(xué)過數(shù)據(jù)結(jié)構(gòu)的人講清楚原因的,但可以出個(gè)題,比如如 ...

沒學(xué)過數(shù)據(jù)結(jié)構(gòu)的能叫程序員?還寫個(gè)迷宮哈哈哈大一的?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表