久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3511|回復: 26
收起左側

單片機C語言定義一個變量,如果不賦值,難道不是默認等于0嘛

  [復制鏈接]
ID:1022479 發表于 2023-2-9 20:40 | 顯示全部樓層 |閱讀模式

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

voidLED_Init(void) //也可用蜂鳴器低電平驅動代替
{
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);//初始設置高,防止開始低電平驅動蜂鳴器
}
void LED1_Turn(void) //蜂鳴器狀態翻轉程序
{
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);
}
}
*********************************************/
這是按鍵的相關程序
/*****************************************
#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;//上拉輸入,懸空時為高電平,適合按鍵
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_1 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//只對輸出管用,這里輸入隨便填

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

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

#define di 100


int main(void)
{
uint8_t KeyNum; //main函數內局部變量
LED_Init();
Key_Init();

while(1)
{
KeyNum= Get_KeyNum();

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

}

}
}
*********************************************/
以上看上去確實沒有問題對吧,實際上也沒有問題,
因為這是我發現問題之后,修正過的程序
真正的問題在于,
原來的程序里只有一條語句與這不一樣,
那就是按鍵的相關程序里面的
uint8_tGet_KeyNum(void)函數里的

第一行的uint8_tKeyNum = 0;  這樣寫達到了我的目的:按鍵按下,蜂鳴器響,按鍵按下,蜂鳴器關

原先我寫的是uint8_t KeyNum;這樣執行只有按著按鍵的時候蜂鳴器才會響???非常奇怪的現象

在我學習51單片機的過程中,老師一直對我說的是,如果定義一個變量,不給它賦初值,默認為0。
現在看起來好像是我理解有問題。。。。
uint8_tKeyNum = 0;和uint8_t KeyNum;有啥區別???
如果沒有區別,為什么現象不一樣???
局部變量里面定義了之后,
如果不賦值
Return 返回的難道不是0???是個隨記數??也不對啊,求賜教?
不能理解,所以想請教各位大佬,如覺幼稚,請多多指教。

3-3按鍵控制LED.7z

174.89 KB, 下載次數: 3

回復

使用道具 舉報

ID:883242 發表于 2023-2-10 00:14 | 顯示全部樓層
全局變量默認才是0,如果你老師沒講錯,那就是你記錯了。

建議你看看《數據結構》這本書,遞歸那一章很好的說明了c語言局部變量是從哪里來的,如果你看懂了的話,就很容易知道為什么不是0。

另外,MDK是符合c語言標準的,C51不符合c語言標準,《數據結構》對局部變量的描寫符合MDK,不符合C51。
回復

使用道具 舉報

ID:1061331 發表于 2023-2-10 02:13 | 顯示全部樓層
不確定。 但一般情況是,靜態變量(static)與全局變量都默認為0,局部變量值不確定(很多情況下不為0)。
回復

使用道具 舉報

ID:213173 發表于 2023-2-10 06:27 | 顯示全部樓層
全局變量是個人專用衛生間,用后離開到下次再用內部環境不變。局部變量是公共衛生間,用后離開到下次再用內部環境不確定。可能卷紙抽空了,馬桶還沒沖。所以局部變量一定要先賦值再使用,函數退出時,將釋放其空間。
回復

使用道具 舉報

ID:596109 發表于 2023-2-10 09:04 | 顯示全部樓層
通常情況下定義變量緊跟著就給賦個初值,就是為了防止函數每次調用時局部變量值的不確定
回復

使用道具 舉報

ID:844772 發表于 2023-2-10 10:26 | 顯示全部樓層
要看編譯器的處理方式,不過只有靜態變量才可能初始化為0,局部變量是動態的,就是隨機數了。
回復

使用道具 舉報

ID:146782 發表于 2023-2-10 11:28 | 顯示全部樓層
定義變量后及時賦個初始值是個好的習慣
回復

使用道具 舉報

ID:1039954 發表于 2023-2-10 11:29 | 顯示全部樓層
最近剛好遇到這個問題,把局部轉成靜態變量就好了
回復

使用道具 舉報

ID:1022479 發表于 2023-2-10 11:54 | 顯示全部樓層
Hephaestus 發表于 2023-2-10 00:14
全局變量默認才是0,如果你老師沒講錯,那就是你記錯了。

建議你看看《數據結構》這本書,遞歸那一章很 ...

感謝大佬,學校安排的只有c語言程序設計,還是大一學的,現在看來還是學的太淺了
我會去學學數據結構的,這本書聽說過,趕緊整一本回去惡補
回復

使用道具 舉報

ID:1059013 發表于 2023-2-10 13:40 | 顯示全部樓層
鄭常椿 發表于 2023-2-10 11:54
感謝大佬,學校安排的只有c語言程序設計,還是大一學的,現在看來還是學的太淺了
我會去學學數據結構的 ...

我單片機C編程搞得不錯,但是從來不看什么數據結構,如何?
回復

使用道具 舉報

ID:883242 發表于 2023-2-10 16:58 | 顯示全部樓層
c編程搞得不錯有兩種,一種是真的不錯,另一種是井蛙級搞得不錯,樓上顯然是后一種。
回復

使用道具 舉報

ID:883242 發表于 2023-2-10 20:47 | 顯示全部樓層
補充一下,如果樓主搞過Windows編程,會遇到著名的“手持兩把錕斤拷,口中疾呼燙燙燙”的問題,此問題的根源就是初始化以后的堆棧里面并不是0。
回復

使用道具 舉報

ID:1034262 發表于 2023-2-10 22:01 | 顯示全部樓層
不一定,所以一定要養成清內存或給變量初值的習慣。
回復

使用道具 舉報

ID:879348 發表于 2023-2-13 14:18 | 顯示全部樓層
當然不是,RAM上是隨機值,很多單片機,包括51單片機,STM32單片機等進入mian前還有一段代碼初始化
回復

使用道具 舉報

ID:130230 發表于 2023-2-13 18:00 | 顯示全部樓層
局部變量是定義在棧上的,如果不加static修飾在退出函數后會釋放該空間。所以這個變量每次進入函數都是不同的地址,所以如果這個地址剛好被某個函數使用過那么初始值就不是0.
回復

使用道具 舉報

ID:130230 發表于 2023-2-13 18:03 | 顯示全部樓層
鄭常椿 發表于 2023-2-10 11:54
感謝大佬,學校安排的只有c語言程序設計,還是大一學的,現在看來還是學的太淺了
我會去學學數據結構的 ...

這不是數據結構的內容,是鏈接和作用域的內容。看一遍c primer plus后把基礎搞清楚再看數據結構吧。尤其是指針要搞透徹。
回復

使用道具 舉報

ID:883242 發表于 2023-2-15 17:10 | 顯示全部樓層
對于標準c語言來說,局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關系,局部變量是怎么來的,又是怎么沒的,只有《數據結構》里面遞歸一節說的最清楚。

對于不遵守標準的野路子編譯器,比如Keil C51才跟鏈接有關。
回復

使用道具 舉報

ID:130230 發表于 2023-2-16 17:57 | 顯示全部樓層
Hephaestus 發表于 2023-2-15 17:10
對于標準c語言來說,局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關系,局部變量是怎么來的,又是怎么 ...

你確定你學過C語言?數據結構怎么和c語言綁定了搞不懂。。。
回復

使用道具 舉報

ID:883242 發表于 2023-2-16 19:11 | 顯示全部樓層
jizhongbiao 發表于 2023-2-16 17:57
你確定你學過C語言?數據結構怎么和c語言綁定了搞不懂。。。

c語言教科書一般不會告訴你局部變量是怎么來的,又是怎么沒的,《數據結構》會講。

你說一本講局部變量來歷的教科書好了。
回復

使用道具 舉報

ID:844772 發表于 2023-2-16 23:24 來自手機 | 顯示全部樓層
Hephaestus 發表于 2023-2-16 19:11
c語言教科書一般不會告訴你局部變量是怎么來的,又是怎么沒的,《數據結構》會講。

你說一本講局部變 ...

學沒學過數據結構是程序員的一個分水嶺,你沒法跟沒學過數據結構的人講清楚原因的,但可以出個題,比如如何寫個走迷宮程序
回復

使用道具 舉報

ID:59202 發表于 2023-2-17 09:28 | 顯示全部樓層
養成良好的編程習慣是對的,否則會經常出現一些讓人頭疼的小問題
回復

使用道具 舉報

ID:883242 發表于 2023-2-17 19:30 | 顯示全部樓層
glinfei 發表于 2023-2-16 23:24
學沒學過數據結構是程序員的一個分水嶺,你沒法跟沒學過數據結構的人講清楚原因的,但可以出個題,比如如 ...

夏蟲不可語冰,井蛙不可語海。
回復

使用道具 舉報

ID:146878 發表于 2023-2-17 21:58 | 顯示全部樓層
定義變量隨手賦值是好習慣,很多低端單片機,是不處理內存初始狀態的。
回復

使用道具 舉報

ID:965301 發表于 2023-2-20 17:36 | 顯示全部樓層
單片機C語言變量默認值有可能不為0,是隨機數,給編譯器有關。
回復

使用道具 舉報

ID:130230 發表于 2023-2-21 18:01 | 顯示全部樓層
Hephaestus 發表于 2023-2-16 19:11
c語言教科書一般不會告訴你局部變量是怎么來的,又是怎么沒的,《數據結構》會講。

你說一本講局部變 ...

所有的教科書都會講啊
回復

使用道具 舉報

ID:130230 發表于 2023-2-21 18:03 | 顯示全部樓層
Hephaestus 發表于 2023-2-15 17:10
對于標準c語言來說,局部變量是在堆棧之上,跟鏈接和作用域沒有一毛錢關系,局部變量是怎么來的,又是怎么 ...

你所謂的遞歸講了是恰好因為遞歸使用了棧,棧是作用域的內容啊。。。算了這論壇水平是在是有限。
回復

使用道具 舉報

ID:130230 發表于 2023-2-21 18:04 | 顯示全部樓層
glinfei 發表于 2023-2-16 23:24
學沒學過數據結構是程序員的一個分水嶺,你沒法跟沒學過數據結構的人講清楚原因的,但可以出個題,比如如 ...

沒學過數據結構的能叫程序員?還寫個迷宮哈哈哈大一的?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 狠狠亚洲| 激情欧美一区二区三区 | 中文字幕日韩一区 | 国产精品不卡一区 | 日日干日日色 | 国产专区免费 | 国产三级精品视频 | 国产亚洲精品综合一区 | 在线中文字幕亚洲 | 精品美女视频在线观看免费软件 | av免费网| 四虎影| 伊人久久精品 | 免费在线黄色av | 久久这里只有精品首页 | 日本久久一区二区三区 | 一区二区高清 | 精品久久久久久 | 丝袜 亚洲 另类 欧美 综合 | 亚洲黄色av| 午夜免费视频 | 成人精品一区亚洲午夜久久久 | 国产一区二区三区四区hd | 日韩在线免费播放 | 欧美精品在欧美一区二区 | 亚洲啪啪 | 欧美精品一区二区三区四区 在线 | 夜夜操天天干 | 日韩羞羞| 成人在线视频免费播放 | 91精品久久久久久久久久入口 | 一区二区三区四区免费视频 | 久久精品久久久久久 | 国产亚洲欧美在线视频 | 日日噜 | 日韩精品一区二区三区免费观看 | 麻豆精品一区二区三区在线观看 | 国产在线精品一区二区三区 | 国产在线精品一区二区三区 | 国产精品色婷婷久久58 | 99爱国产 |