① 求4為7段共陽極數碼管c語言程序,用定時計數
/***源程序默認硬體環境:52單片機,12MHz晶振,四位共陽數碼管,P0段選,P20-P23低電平位選,P23最高位,P20最低位***/
#include"reg52.h"
//包含52頭文件
#define
TRUE
1
//定義布爾量'1':真
#define
FALSE
0
//定義布爾量'0':假
#define
uchar
unsigned
char
//定義
無符號字元型數據
簡稱
#define
uint
unsigned
int
//定義
無符號整型數據
簡稱
#define
th0
0x3c
#define
tl0
0xb0
//50ms
at
12MHz(定時器工作模式1
狀態)
#define
th1
0xfc
#define
tl1
0x18
//1ms
at
12MHz(定時器工作模式1
狀態)
#define
T1sAt50msCount
20
//定義
1s
在
50ms
計時基準狀態下
的計數值
為20
#define
SEG_Num
4
#define
SEG_Data
P0
//數碼管段驅動介面
#define
SEG_En
P2
//數碼管位驅動介面
#define
SEG_AllOff
(SEG_En|=0x0f)
//關閉所有數碼管(位驅動)
#define
DisTimeAt1msCount
4
//單'位'數碼管顯示時間,數碼管刷新頻率f=1/(N*t),其中
N為數碼管位數,t
為單'位'數碼管顯示時間
uchar
SEG_B_List[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//共陽數碼管代碼表"0-9"
uchar
Sec,Min;
uchar
bdata
Flag=2;
sbit
T1sTimesUpFlag=Flag^0;
sbit
DisplayFlag=Flag^1;
void
Timer0()
interrupt
1
//定時器0中斷函數
{
static
uchar
t50ms;
TL0=tl0;
TH0=th0;
t50ms=++t50ms%T1sAt50msCount;
//先對50ms計時變數加1,後對變數范圍進行限制(0~19)(即對20取模)
if(!t50ms)
T1sTimesUpFlag=TRUE;
//若計時變數歸0,表示計時變數曾經到達20(1s),則對1s計時標志位
置位
}
void
Timer1()
interrupt
3
{
static
uchar
t1ms;
TL1=tl1;
TH1=th1;
t1ms=++t1ms%DisTimeAt1msCount;
//先計數值加1,後對計數范圍進行限制0~(DisTimeAt1msCount-1)
if(!t1ms)
DisplayFlag=TRUE;
//若定時計數值歸0,則表示計數值曾到達
單'位'顯示時間(DisTimeAt1msCount),顯示標志
置位
}
void
TimerInit()
{
TMOD=0x11;
//開啟定時器0、定時器1,並都工作在模式1
TH0=th0;
TL0=tl0;
TR0=1;
//啟動T0定時器
計時
ET0=1;
//允許定時器0中斷
TH1=th1;
TL1=tl1;
TR1=1;
//啟動T1定時器
計時
ET1=1;
//允許定時器1中斷
EA=1;
//開啟系統中斷功能
}
void
TimesUpdata()
//時間更新函數
{
if(T1sTimesUpFlag)
//若
1s計時標志位
為
真,即
1s定時時間到
{
Sec=++Sec%60;
//秒Sec在0-59范圍內加1
if(!Sec)
Min=++Min%60;
//若秒Sec
重歸0,則分Min在0-59范圍內加1
T1sTimesUpFlag=FALSE;
//清
1s計時標志位
}
}
float
Pow_Self(float
x,uint
y)//自編簡易
x
的
y
次方函數,y只能是
非負整數
{
float
sum;
if(x==0
&&
y==0)
return;
//0
的
0
次方無意義
else
if(x==0)
sum=0;
//可有可無,y!=0的情況已經包含x=0,不加不影響結果,但影響運算速度
else
if(y==0)
sum=1;
//除上述情況外,任何數的
0
次方均為
1
else
if(y==1)
sum=x;
//任何數的
1
次方
均為
本身
else
if(y>1)
sum=Pow_Self(x,--y)*x;
//遞歸調用,降冪
return
sum;
//返回計算結果
}
void
Display(uint
dis_num)
//顯示函數,顯示內容為
無符號整型數據
dis_num
{
static
dis_loca;
//定義靜態變數
顯示位置
dis_loca=++dis_loca%SEG_Num;
//先對
顯示位置
加1,後對變數范圍進行限制
0~(SEG_Num-1)
SEG_AllOff;
//關閉所有數碼管顯示(位驅動)
SEG_Data=SEG_B_List[(dis_num/(uint)(Pow_Self(10,dis_loca)))%10];
//將顯示內容(dis_num)
本次需顯示的位(dis_loca)上的數值轉成代碼,並送到數據埠
if(dis_loca==2)
SEG_Data
&=0x7f;
//顯示
小數點,用於區分
Min
跟
Sec
SEG_En&=~(1<<dis_loca);
//開啟本次需要顯示的位驅動(低驅動)
}
void
ClockDisplay()
//時鍾顯示函數
{
if(DisplayFlag)
//若
顯示標志位
為
真
{
Display(Min*100+Sec);
//調用
顯示函數,顯示內容為:高2位顯示
分Min,低2位顯示
秒Sec
DisplayFlag=FALSE;
//清
顯示標志
}
}
void
main()
{
TimerInit();
//調用
定時器初始化函數
while(1)
//循環系統
{
TimesUpdata();
//調用
時間更新函數
ClockDisplay();
//調用
時鍾顯示函數
}
}
② 單片機C語言編程
KEY4EQU30H
KEY2EQU31H
ORG0000H
LJMPMAIN
ORG0030H
MAIN:
CLREA
MOVSP,#5FH
MOVKEY2,#0
MOVKEY4,#0
LOOP:
JBP1.0,LOOP
MOVR7,#10
LCALLDELAY
JBP1.0,LOOP
JNBP1.0,$
MOVP3,#0C0H
LOOP0:
LCALLKEYDEAL
MOVA,KEY4
JNZLOOP41
MOVA,P3
ANLA,#0F0H
ORLA,#0EH
MOVP3,A
SJMPLOOP21
LOOP41:
DECA
JNZLOOP42
MOVA,P3
ANLA,#0F0H
ORLA,#0DH
MOVP3,A
SJMPLOOP21
LOOP42:
DECA
JNZLOOP43
MOVA,P3
ANLA,#0F0H
ORLA,#0BH
MOVP3,A
SJMPLOOP21
LOOP43:
DECA
JNZLOOP21
MOVA,P3
ANLA,#0F0H
ORLA,#07H
MOVP3,A
LOOP21:
MOVA,KEY2
JNZLOOP22
MOVA,P3
ANLA,#0FH
ORLA,#20H
MOVP3,A
SJMPLOOP3
LOOP22:
DECA
JNZLOOP3
MOVA,P3
ANLA,#0FH
ORLA,#10H
MOVP3,A
LOOP3:
LJMPLOOP0
;----------------------------
DELAY:
MOVR2,#2
DLY1:
MOVR3,#250
DJNZR3,$
DJNZR2,DLY1
DJNZR7,DELAY
RET
;-----------------------------
KEYDEAL:
JBP1.1,KEYEN1
MOVR7,#10
LCALLDELAY
JBP1.1,KEYEN1
JNBP1.1,$
INCKEY4
MOVA,KEY4
ANLA,#03H
MOVKEY4,A
KEYEN1:
JBP1.2,KEYEN2
MOVR7,#10
LCALLDELAY
JBP1.2,KEYEN2
JNBP1.2,$
INCKEY2
MOVA,KEY2
ANLA,#01H
MOVKEY2,A
KEYEN2:
RET
;-----------------------------
③ C語言編程,應該在頭文件里定時變數還是該在源文件里定義變數
頭文件中,一般定義全局變數,可供更多的源代碼共享。
但全局變數盡可能的少使用,不得於代碼的穩定性。
④ 怎麼用C語言編定時器
Windows提供了定時器,幫助我們編寫定期發送消息的程序。定時器一般通過一下兩中方式通知應用程序間隔時間已到。
⑴ 給指定窗口發送WM_TIMER消息,也就是下面的給出在窗口類中使用的方法。
⑵ 調用一個應用程序定義的回調函數,也就是在非窗口類中使用方法。
4.1 在窗口類中使用定時器
在窗口類中使用定時器比較簡單。假如我們想讓這個窗口上放置一個電子鍾,這樣我們必須每1秒或者0.5秒鍾去更新顯示顯見。按照下面的步驟,就可以完成這個電子鍾程序,並且知道如何在窗口類中使用定時器:
首先做在我們新建項目的主窗口上添加一個Label控制項,用來顯示時間。接著
⑴ 用函數SetTimer設置一個定時器,函數格式如下: UINT SetTimer( UINT nIDEvent,
UINT nElapse,
void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD));
這個函數是CWnd類的一個成員函數,其參數意義如下:
nIDEvent: 為設定的定時器指定的定時器標志值,設置多個定時器的時候,每個定時器的值都不同,消息處理函數就是通過這個參數來判斷是哪個定時器的。這里我們設定為1。
nElapse: 指定發送消息的時間間隔,單位是毫秒。這里我們設定為1000,也就是一秒。
lpfnTimer: 指定定時器消息由哪個回調函數來執行,如果為空,WM_TIMER將加入到應用程序的消息隊列中,並由CWnd類來處理。這里我們設定為NULL。
最後代碼如下:SetTimer(1,1000,NULL);
⑵ 通過Class Wizard給主窗口類添加一個WM_TIMER消息的映射函數,默認為OnTimer(UINT nIDEvent)。
⑶ 然後我們就可以在OnTimer(UINT nIDEvent)的函數實現中添加我們的代碼了。參數nIDEvent就是我們先前設定定時器時指定的標志值,在這里我們就可以通過它來區別不同的定時器,而作出不同的處理。添加的代碼如下:switch(nIDEvent)
{
case 1:
CTime m_SysTime = CTime::GetCurrentTime();
SetDlgItemText(IDC_STATIC_TIME,m_SysTime.Format("%Y年%m月%d日 %H:%M:%S"));
break;
}
代碼中的IDC_STATIC_TIME就是我們先前添加的Label控制項的ID。
至此,我們的電子鍾的程序就完成了。
4.2 在非窗口類中使用定時器
在非窗口類中使用定時器就要用到前面我們介紹到的所有知識了。因為是無窗口類,所以我們不能使用在窗口類中用消息映射的方法來設置定時器,這時候就必須要用到回調函數。又因為回調函數是具有一定格式的,它的參數不能由我們自己來決定,所以我們沒辦法利用參數將this傳遞進去。可是靜態成員函數是可以訪問靜態成員變數的,因此我們可以把this保存在一個靜態成員變數中,在靜態成員函數中就可以使用該指針,對於只有一個實例的指針,這種方法還是行的通的,由於在一個類中該靜態成員變數只有一個拷貝,對於有多個實例的類,我們就不能用區分了。解決的辦法就是把定時器標志值作為關鍵字,類實例的指針作為項,保存在一個靜態映射表中,因為是標志值是唯一的,用它就可以快速檢索出映射表中對應的該實例的指針,因為是靜態的,所以回調函數是可以訪問他們的。
首先介紹一下用於設置定時的函數:
UINT SetTimer(
HWND hWnd, // handle of window for timer messages
UINT nIDEvent, // timer identifier
UINT uElapse, // time-out value
TIMERPROC lpTimerFunc // address of timer procere
);
其中的參數意義如下:
hWnd: 指定與定時器相關聯的窗口的句柄。這里我們設為NULL。
nIDEvent: 定時器標志值,如果hWnd參數為NULL,它將會被跳過,所以我們也設定為NULL。
uElapse: 指定發送消息的時間間隔,單位是毫秒。這里我們不指定,用參數傳入。
lpTimerFunc: 指定當間隔時間到的時候被統治的函數的地址,也就是這里的回調函數。這個函數的格式必須為以下格式:
VOID CALLBACK TimerProc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime // current system time
);
其中的參數意義如下:
hwnd: 與定時器相關聯的窗口的句柄。
uMsg: WM_TIMER消息。
idEvent: 定時器標志值。
deTime: 系統啟動後所以經過的時間,單位毫秒。
最後設定定時器的代碼為:m_nTimerID = SetTimer(NULL,NULL,nElapse,MyTimerProc);
先通過Class Wizard創建一個非窗口類,選擇Generic Class類類型,類名稱為CMyTimer,該類的作用是每隔一段時間提醒我們做某件事情,然後用這個類創建三個實例,每個實例以不同的時間間隔提醒我們做不同的事情。
MyTimer.h#include
class CMyTimer;
//用模板類中的映射表類定義一種數據類型
typedef CMap CTimerMap;
class CMyTimer
{
public:
//設置定時器,nElapse表示時間間隔,sz表示要提示的內容
void SetMyTimer(UINT nElapse,CString sz);
//銷毀該實例的定時器
void KillMyTimer();
//保存該實例的定時器標志值
UINT m_nTimerID;
//靜態數據成員要提示的內容
CString szContent;
//聲明靜態數據成員,映射表類,用於保存所有的定時器信息
static CTimerMap m_sTimeMap;
//靜態成員函數,用於處理定時器的消息
static void CALLBACK MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
CMyTimer();
virtual ~CMyTimer();
};
MyTimer.cpp#include "stdafx.h"
#include "MyTimer.h"
//必須要在外部定義一下靜態數據成員
CTimerMap CMyTimer::m_sTimeMap;
CMyTimer::CMyTimer()
{
m_nTimerID = 0;
}
CMyTimer::~CMyTimer()
{
}
void CALLBACK CMyTimer::MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
{
CString sz;
sz.Format("%d號定時器:%s",
idEvent,
m_sTimeMap[idEvent]->szContent);
AfxMessageBox(sz);
}
void CMyTimer::SetMyTimer(UINT nElapse,CString sz)
{
szContent = sz;
m_nTimerID = SetTimer(NULL,NULL,nElapse,MyTimerProc);
m_sTimeMap[m_nTimerID] = this;
}
void CMyTimer::KillMyTimer()
{
KillTimer(NULL,m_nTimerID);
m_sTimeMap.RemoveKey(m_nTimerID);
}
這樣就完成了在非窗口類中使用定時器的方法。以上這些代碼都在Windwos 2000 Professional 和 Visual C++ 6.0中編譯通過。
⑤ 求C語言編程題
邏輯運算和判斷選取控制
1、編製程序要求輸入整數a和b,若a2+b2大於100,則輸出a2+b2百位以上的數字,否則輸出兩數字之和。
#include<stdio.h>
int main()
{
int a,b;
printf("input two number:");
scanf("%d %d",&a,&b);
if((a*a+b*b)>=100)
printf("\n %d",(a*a+b*b)/100);
else
printf("\n %d",a+b);
getch();
}
2、試編程判斷輸入的正整數是否既是5又是7的整數倍數。若是,則輸出yes;否則輸出no。
#include<stdio.h>
int main()
{
int a;
printf("input a number:");
scanf("%d",&a);
if(a%5==0 && a%7==0)
printf("yes");
else
printf("no");
getch();
}
指針
1、編一程序,將字元串computer賦給一個字元數組,然後從第一個字母開始間隔的輸出該串,請用指針完成。
#include<stdio.h>
int main()
{
char string[]="computer";
char *p=string;
while(*p)
{
printf("%c",*p);
p++;
p++;
}
getch();
}
2、輸入一個字元串string,然後在string裡面每個字母間加一個空格,請用指針完成。
#include<stdio.h>
#include<CONIO.H>
#include<STDLIB.H>
#define max 100
char * String;
void (char *,char*);
void insert(char *);
int main()
{
char * string;
string = (char *)malloc(max*sizeof(char));
scanf("%s",string);
insert(string);
printf("%s",string);
getch();
return 0;
}
void (char * c,char * s)
{
while(*s!='\0')
{
*c=*s;
s++;
c++;
}
*c='\0';
}
void insert(char * s)
{
String = (char*)malloc(2*max*sizeof(char));
(String,s);
while(*String!='\0')
{
*s=*String;
s++;
String++;
*s=' ';
s++;
}
*s='\0';
}
一.選擇:
1.給出以下定義:
char acX[ ]= "abcdefg";
char acY[ ]= {'a','b','c','d','e','f','g'};
則正確的敘述為( )
A) 數組acX和數組acY等價 B) 數組acX和數組acY的長度相同
C) 數組acX的長度大於數組acY的長度 D) 數組acX的長度小於數組acY的長度
答案:C
2.
void example(char acHello[])
{
printf("%d", sizeof(acHello));
return;
}
void main()
{
char acHello[] = "hello";
example(acHello);//數組名稱作參數,傳的是地址,一個地址佔四個位元組
return;
}
的輸出是
A 4 B 5 C 6 D不確定
答案:A
3. 有以下程序段
char acArr[]= "ABCDE";
char *pcPtr;
for(pcPtr = acArr; pcPtr < acArr + 5; pcPtr++)
{
printf("%s\n", pcPtr);
}
return;
輸出結果是( )
A) ABCD B) A C) E D) ABCDE
B D BCDE
C C CDE
D B DE
E A E
答案:D
4.在中斷中,不能同步獲取信號量,但是可以釋放信號量。
A.正確 B.錯誤
答案:A
5.以下敘述中不正確的是( )
A) 在不同的函數中可以使用相同名字的變數
B) 函數中的形式參數是局部變數
C) 在一個函數內定義的變數只在本函數范圍內有效
D) 在一個函數內的復合語句中定義的變數在本函數范圍內有效(復合語句指函數中的成對括弧構成的代碼)
答案:D
6.設有如下定義:
unsigned long pulArray[] = {6, 7, 8, 9, 10};
unsigned long *pulPtr;
則下列程序段的輸出結果為( )
pulPtr = pulArray;
*(pulPtr + 2) += 2;
printf ("%d,%d\n", *pulPtr, *(pulPtr + 2));
A)8,10 B)6,8 C)7,9 D)6,10
答案:D
7. 定義結構體時有下面幾種說法,請指出正確的(多選):______
A、結構體中的每個部分,最好進行四位元組對齊;
B、結構體的總長度最好是四位元組對齊;
C、結構中成員的存放不用考慮位元組對齊情況;
答案:A、B
8.void example()
{
int i;
char acNew[20];
for(i = 0; i < 10; i++)
{
acNew[i] = '0';
}
printf("%d\n", strlen(acNew));
return;
}
的輸出為( )
A 0 B 10 C 11 D不確定
答案:D
9.switch(c)中的c的數據類型可以是char、long、float、unsigned、bool. ( )
A. 正確 B. 錯誤
答案:B
10. 網路上傳輸的位元組序默認是大位元組的,如果主機是小位元組序,在網路通信時則須進行位元組序轉換;如果主機是
大位元組序,為了程序的一致性及可移植性,最好也在程序中加上位元組序轉換的操作(空操作)。
A. 正確 B.錯誤
答案:A
11. struct stu
{
int num;
char name[10];
int age;
};
void fun(struct stu *p)
{
printf("%s\n", (*p).name);
return;
}
void main()
{
struct stu students[3]={ {9801,"Zhang",20},
{9802,"Wang",19},
{9803,"Zhao",18} };
fun(students + 2);
return;
}
輸出結果是( )
A) Zhang B)Zhao C) Wang D) 18
答案:B
12.以下程序運行後,輸出結果是( )
void main( )
{
char *szStr = "abcde";
szStr += 2;
printf("%lu \n",szStr);
return;
}
A cde B 字元c的ASCLL碼值
C "abcde"這個常串中字元c所在的地址 D 出錯
答案:C
13. 在X86下,有下列程序
#include <stdio.h>
void main()
{
union
{
int k;
char i[2];
}*s,a;
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n", a.k);
}
輸出結果是( )
A) 3839 B) 3938 C) 380039 D) 不可預知
答案:D
14. 全局變數可以定義在被多個.C文件包含著的頭文件中。
A. 正確 B. 錯誤
答案:B
15.void example()
{
int i;
char acNew[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
for(i = 0; i < 10; i++)
{
acNew[i] = '0';
}
printf("%d\n", strlen(acNew));
return;
}
的輸出為:
A 0 B 10 C 11 D不確定
答案:B
16.下列定義正確的有(多選):( )
A: char *pcPtr = "abcd";
B: char pc[4]= "abcd";
C: char pc[] = "abcd";
D: char pc[] = 'abcd';
E: char pc[] = {'a','b','c','d','\0'};
F: char pc[] = 'a' 'b' 'c' 'd';
答案:ACE
17.在函數內部定義的變數(靜態變數、寄存器變數等特殊變數除外)的內存是在棧內存中,所以在定義函數內部的變數的時候,一定要保證棧不能夠溢出。如果臨時變數
佔用空間較大,應該使用內存申請的方式,這樣該變數指向的內存就是在堆內存中了。
A. 正確 B. 錯誤
答案:A
18.局部變數可以和全局變數重名,編譯的時候不會出現錯誤,但一旦不小心,就可能導致使用錯誤變數,所以在定時局部變數的時候,不要和全局變數重名。
A. 正確 B. 錯誤
答案:A
19.設有以下宏定義:
#define N 3
#define Y(n) ((N+1)*n) /*這種定義在編程規范中是嚴格禁止的*/
則執行語句:z = 2 * (N + Y(5 + 1));後,z的值為( )
A) 出錯 B) 42 C) 48 D)54
答案:C
20. int *(*ptr)();
則以下敘述中正確的是( )
A) ptr是指向一維組數的指針變數
B) ptr是指向int型數據的指針變數
C) ptr是指向函數的指針,該函數返回一個int型數據
D) ptr是指向函數的指針,該函數的返回值是指向int型數據的指針
答案:D
21. 0x12345678 在採用BigEndian中內存的排列順序是______,在採用LittleEndian內存中的排列順序是_______.
(答案從左到右內存地址依次增加)
A.12 34 56 78 B.34 12 78 56
C.78 56 34 12 D.56 78 12 34
答案:A C
二、填空:
1. .struct tagAAA
{
unsigned char ucId:1;
unsigned char ucPara0:2;
unsigned char ucState:6;
unsigned char ucTail:4;
unsigned char ucAvail;
unsigned char ucTail2:4;
unsigned long ulData;
}AAA_S;
問:AAA_S在位元組對齊分別為1、4的情況下,佔用的空間大小是多少?
答案:9 12
2.typedef struct tagTest
{
UCHAR ucFlag;
ULONG ulLen;
}TEST_S;
TEST_S test[10];
四位元組對齊方式時: sizeof(TEST_S) = ______, sizeof(test)________.
答案:8 80
3
char acHello[] = "hello\0world";
char acNew[15] = {0};
strcpy(acNew,acHello);
strlen(acNew) = _____
sizeof(acHello) = ______
答案:5 12
4.#pragma pack(4)/*編譯選項,表示4位元組對齊*/
int main(int argc, char* argv[])
{
struct tagTest1
{
short a;
char d;
long b;
long c;
};
struct tagTest2
{
long b;
short c;
char d;
long a;
};
struct tagTest3
{
short c;
long b;
char d;
long a;
};
struct tagTest1 stT1;
struct tagTest2 stT2;
struct tagTest3 stT3;
printf("%d %d %d", sizeof(stT1), sizeof(stT2), sizeof(stT3));
return 0;
}
#pragma pack()(編譯選項結束)
請問輸出結果是:_________
答案:12 12 16
5. enum ENUM_A
{
X1,
Y1,
Z1 = 5,
A1,
B1
};
enum ENUM_A enumA = Y1;
enum ENUM_A enumB = B1;
請問 enumA = ____; enumB = ______;
答案:1 7
6.以下程序的輸出結果是________.
#include <stdio.h>
int fun(int x,int y)
{
static int m = 0;8
static int i = 2;3
i += m + 1;12
m = i + x + y;
return m;
}
void main()
{
int j = 4;
int m = 1;
int k;
k = fun(j, m);
printf("%d,", k);
k=fun(j, m);
printf("%d\n", k);
return;
}
答案:8 17
7.以下程序的輸出結果為________
#define CIR(r) r*r /*請注意這種定義的缺陷,不允許這么定義*/
void main()
{
int a = 1;
int b = 2;
int t;
t = CIR(a + b);
printf("%d\n", t);
return;
}
答案:5
8.在VRP中,實現了strncpy類似的函數,定義如下:
#define CHAR char
#define ULONG unsigned long
#define VOID void
#define MACRO_COPYWORLDLENGTH 4
CHAR *VOS_strncpy(CHAR *pcDest, const CHAR *szSrc, ULONG ulLength)
{
CHAR *pcPoint = pcDest;
if(( NULL == szSrc ) || ( NULL == pcDest ) ))
{
return NULL;
}
while(ulLength && (*pcPoint = *szSrc))/*這里採用了在判斷語句中賦值的方式(*pcPoint = *szSrc),建議盡量不使用*/
{
pcPoint++;
szSrc++;
ulLength--;
}
if(!ulLength)
{
*pcPoint = '\0';
}
return pcDest;
}
VOID main(VOID)
{
CHAR szStrBuf[ ] = "1234567890";
CHAR szStrBuf1[ ] = "1234567890";
CHAR *szHelloWorld = "Hello World!";
strncpy(szStrBuf, szHelloWorld, MACRO_COPYWORLDLENGTH);
VOS_strncpy(szStrBuf1, szHelloWorld, MACRO_COPYWORLDLENGTH);
printf("%s %s", szStrBuf, szStrBuf1);
}
程序的輸出結果為________
答案:Hell567890 Hell
9.
char acHello[] = "hello\0world";
char acNew[15] = {0};
memcpy(acNew,acHello,12);
strlen(acNew) = _____
sizeof(acHello) = _____
答案:5 12
10. typedef struct Head
{
UCHAR aucSrc[6];
ULONG ulType;
} HEAD_S;
在強制一位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
在強制二位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
在強制四位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
答案:10 10 12
11.union tagAAAA
{
struct
{
char ucFirst;
short usSecond;
char ucThird;
}half;
long lI;
}number;
struct tagBBBBB
{
char ucFirst;
short usSecond;
char ucThird;
short usForth;
}half;
struct tagCCCC
{
struct
{
char ucFirst;
short usSecond;
char ucThird;
}half;
long lI;
};
在位元組對齊為1下,sizeof(union tagAAAA)、sizeof(struct tagBBBBB)、sizeof(struct tagCCCC)是____ ____ _____
在位元組對齊為4下,sizeof(union tagAAAA)、sizeof(struct tagBBBBB)、sizeof(struct tagCCCC)是____ ____ _____
答案:4 6 8
8 8 12
12.struct tagABC
{
char cB;
short sC;
char cD;
long lA;
}*pAbc;
pAbc = 0x100000;
那麼pAbc+0x100 = 0x_________; (ULONG)pAbc + 0x100 = 0x_________;(ULONG *)pAbc + 0x100 = 0x_________;(char *)pAbc + 0x100 = 0x_______;
答案:100C00 100100 100400 100100
13.unsigned long FUNC_C ( unsigned long ulAction )
{
unsigned long ulResult = 0 ;
switch ( ulAction )
{
case ACTION_A:
{
ulResult += 1 ;
break ;
}
case ACTION_B:
{
ulResult += 1 ;
}
default:
{
ulResult += 1 ;
}
}
printf( "ulResult = %u", ulResult ) ;
return ulResult ;
}
當輸入為ACTION_B時,輸出結果為: ulResult = _________;
答案:2(因為此分支沒有break分支)
14.下面的代碼中,函數Test執行完畢後,列印的結果是 _____。
unsigned long g_ulGlobal = 0;
void GlobalInit(unsigned long ulArg)
{
ulArg = 0x01;
return;
}
void Test()
{
GlobalInit(g_ulGlobal);
printf("%lu", g_ulGlobal);
return;
}
答案:0
15.以下程序的輸出的結果是___________
int x = 3;
void incre();
void main()
{ int i;
for (i = 1; i < x; i++)
{
incre();
}
return;
}
void incre()
{
static int x = 1;
x *= (x + 1);
printf("%d ",x);
return;
}
答案:2 6
16.以下程序的輸出的結果是___________
#pragma pack(4)/*四位元組對齊*/
int main(int argc, char* argv[])
{
unsigned char puc[4];
struct tagPIM
{
unsigned char ucPim1;
unsigned char ucData0:1;
unsigned char ucData1:2;
unsigned char ucData2:3;
}*pstPimData;
pstPimData = (struct tagPIM *)puc;
memset(puc, 0, 4);
pstPimData->ucPim1 = 1;
pstPimData->ucData0 = 2;
pstPimData->ucData1 = 3;
pstPimData->ucData2 = 4;
printf("%02X %02X %02X %02X\n", puc[0], puc[1], puc[2], puc[3]);
return 0;
}
#pragma pack()/*恢復預設對齊方式*/
答案:01 26 00 00
17.
char *pcColor = "blue1" ;
char acColor[] = "blue1" ;
strlen(pcColor) = _____
strlen(acColor) = _____
sizeof(pcColor) = _____
sizeof(acColor) = _____
答案:5 5 4 6
18.
char str[] = "\\\0";
char *p = str;
int n = 1000;
請計算
sizeof (str ) = ____________
sizeof ( p ) = ______________
sizeof ( n ) = ______________
答案:3 4 4
19.UCHAR *pucCharArray[10][10];
typedef union unRec
{
ULONG ulIndex;
USHORT usLevel[6];
UCHAR ucPos;
}REC_S;
REC_S stMax,*pstMax;
四位元組對齊方式時: sizeof(pucCharArray) = __指針的數組,每個指針的地址都是4位元組____, sizeof(stMax)=_______, sizeof(pstMax)=__地址______,sizeof(*pstMax)=________.
答案:400 12 4 12
20.typedef union unHead
{
UCHAR aucSrc [6];
struct tagContent
{
UCHAR ucFlag[3];
ULONG ulNext;
}Content;
}HEAD_S;
32CPU,VC編譯環境下:
在強制一位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
在強制二位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
在強制四位元組對齊情況下,請指出sizeof(HEAD_S) = ________;
答案:7 8 8
21.
UCHAR *pszTest = "hello";
UCHAR aucTest[] = "hello";
請問 sizeof(pszTest) = _____ , sizeof(*pszTest) = ______, sizeof(aucTest) = ______.
答案:4 1 6
22. struct BBB
{
long lNum;
char *pcName;
short sDate;
char cHa[2];
short sBa[6];
}*p;
p = 0x100000;
p + 0x1 = 0x____
(unsigned long)p + 0x1 = 0x______
(unsigned long *)p + 0x1 = 0x______
(char *)p + 0x1 = 0x______
答案:100018 100001 100004 100001
23.在4位元組對齊的情況:
typedef struct tagRec
{
long lA1;
char cA2;
char cA3;
long lA4;
long lA5;
} REC_S;
void main(int argc, char *argv[])
{
REC_S stMax ;
printf("\r\n sizeof(stMax)= %d",sizeof(stMax));
return;
}
輸出結果為:
sizeof(stMax)=____
答案:16
24.void main ()
{
unsigned long ulA = 0x11000000;
printf("\r\n%x",*(unsigned char *)&ulA);
return;
}
輸出結果為:
答案:0
三、指出下列程序中導致不能出現預期結果的唯一錯誤(不考慮編程規范錯誤)
1.下面程序用於輸出用戶輸入的字元串。請指出其中的問題
#define OK 0
#define ERR 1
#define ERROR (-1)
#define BUFFER_SIZE 256
int GetMemory(char **ppszBuf, int num)
{
if( NULL == ppszBuf )
{
ASSERT(0);
return ERROR;
}
*ppszBuf = (char *)malloc(num);
if(NULL == *ppszBuf)
{
return ERROR;
}
return OK;
}
void Test(void)
{
char *pcStr = NULL;
if(OK == GetMemory(&pcStr, BUFFER_SIZE))
{
scanf("%s",pcStr);/*這里假定BUFFER_SIZE足夠大,不會導致越界*/
printf(pcStr);
free(pcStr);
}
return;
}
答案:要採用printf("%s", str)的形式列印,否則如果輸入為%s, %d等形式可能會導致不可知現象。
2.此函數實現把32位IP地址(主機序)以字元串的方式列印出來,請找出代碼中的錯誤:
char *IpAddr2Str(unsigned long ulIpAddr)
{
char szIpAddr[32];
(void)VOS_sprintf(szIpAddr, "%d.%d.%d.%d", ulIpAddr >> 24,
(ulIpAddr >> 16) & 0xff, (ulIpAddr >> 8) & 0xff, ulIpAddr & 0xff);
return szIpAddr;
}
答案:函數的局部變數是存放在堆棧中的,此函數返回了堆棧中的地址,函數退出後堆棧中的內容不可用。
3.如下程序用於輸出"Welcome Home"。請指出其中的錯誤:
void Test(void)
{
char pcArray[12];
strcpy(pcArray,"Welcome Home");
printf("%s!", pcArray);
return;
}
答案:數組越界。
4.如下程序用於把"blue"字元串返回,請指出其中的錯誤:
char *GetBLUE(void)
{
char* pcColor ;
char* pcNewColor;
pcColor = "blue";
pcNewColor = (char*)malloc(strlen(pColor));
if(NULL == pcNewColor)
{
return NULL;
}
strcpy(pcNewColor, pcColor);
return pcNewColor;
}
答案:申請內存空間不足,字元串結尾還有'\0'。
5.下面程序期望輸出str = hello world,請指出其中的錯誤:
char * GetStr(char *p)
{
p = "hello world";
return p;
}
void main()
{
char *str = NULL;
if(NULL != GetStr(str))
{
printf("\r\n str = %s",str);
}
return;
}
答案:無法返回字元串,參數使用錯誤。
⑥ 單片機c語言編寫產生1秒定時的程序,怎麼寫
如果是51單片機的話其實很簡單的,這里假設晶振頻率是12M(一般都是的),你可以選用定時器0,工作在工作狀態2,因為這個狀態下裝入初始值幾乎不需要時間,所以定時精確,也就是8位預置數狀態,將初始值設為6,這樣每次定時就是250微秒,在中斷程序中定義一個靜態變數,每次中斷加一,這樣當這個變數值為4000時就剛好是1S鍾。
關鍵程序是:
void main()
{
TMOD=OX02;
EA=1;
ET0=1;
TH0=0X06;
TL0=0X06;
while(1);
}
void timer0() interrupt 1
{
static unsigned int times=0;
times++;
if(times==4000)
{
times=0;
//自己的程序
}}
⑦ 新手請教:單片機C語言怎麼用定時器進行延時排隊編程
51單片機只有兩個定時器,你雖然有四種定時,但沒有同時進行,所以你在每次定時結束後,在下一次定時器打開的時候重裝初值就可以了,實際上只要一個定時器就可以了。
有問題再交流!!
⑧ 單片機C語言編程如何實現定時器中斷1s編程
以下是一個實時時鍾的程序,裡麵包含有1S定時器,你也可以使用延時程序,但是不精確
/*備註:按鍵一為功能鍵,按一下調年,按兩下調月,按三下調日,按四下調時,按五下調分*/
/* 按六下退出,或者在任何時候按鍵四退出設定狀態。在設定狀態鍵二加一,鍵三減一*/
/* 鍵四退出,正常狀態鍵二顯示年,鍵三顯示月日,鍵四顯示星期和秒*/
/* 星期根據日期計算得出,其已全部調試通過,為了時間精確,要調一個誤差值*/
#include<reg2051.h>
#include<stdio.h>
#include<absacc.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code led_xs[12]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09,0xff,0xfd};
uchar data led_data[4];
volatile uchar data a; //定義按鍵一志標
volatile uchar data month=4; //定義月並賦初值
volatile uchar data date=29; //定義日並賦初值
volatile uchar data week; //定義星期並賦初值
volatile uchar data hour; //定義時
volatile uchar data min; //定義分
volatile uchar data sec=0; //定義秒
volatile uint data zn=0; //定義中間存儲變數
volatile uint data year=2007; //定義年並賦初值
sbit md=P3^7; //定義秒點
sbit k1=P1^0; //定義按鍵一
sbit k2=P1^1; //定義按鍵二
sbit k3=P1^2; //定義按鍵三
sbit k4=P1^3; //定義按鍵四
sbit hs=P1^4; //定義顯示片選信號一
sbit hg=P1^5; //定義顯示片選信號二
sbit ms=P1^6; //定義顯示片選信號三
sbit mg=P1^7; //定義顯示片選信號四
bit sans; //定義閃爍標志
bit b; //定義按鍵二標志
bit c; //定義按鍵三標志
bit w; //定義按鍵四標志
bit x; //定義24小時到標志
bit y; //定義日期加一標志
keyscan(); //申明鍵盤掃描函數
void display(); //申明顯示函數
void chushihua(void); //申明初始化函數
void delay_10ms(void); //申明10ms延時函數
dateadd(); //申明日期加函數
datesub(); //申明日期減函數
weekjs(); //星期計算函數
void main(void)
{
weekjs(); //計算初值星期幾
x=y=0; //日期加初始化
chushihua(); //調初始化函數,初始化定時器,中斷
do{
keyscan(); //鍵盤掃描
display(); //調用顯示函數
if((!y)==x)dateadd(); //判斷是否有24小時,有就調用日期加函數
}
while(1); //先調用顯示鍵盤
}
void chushihua(void) //初始化函數
{
TMOD=0x02; //定時器0以方式2工作,自動重裝初值
IE=0x82; //開總中斷和TO中斷
TH0=0x06; //T0高位置初值
TL0=0x06; //T0低位置初值
TR0=1; //啟動TO
}
timer0 () interrupt 1 //T0中斷函數
{
if(zn<4000){zn++;if(zn==2000)sans=!sans;}
else {zn=0;sec++;sans=!sans;
if(sec==60){sec=0;min++;
if(min==60){min=0;hour++;
if(hour==24){hour=0;x=!x;}
}
}
}
}
void display()
{
uchar k;
uint d;
uchar e;
SCON=0x00;
P1=0x0f;
if((a!=0)&&sans){
led_data[3]=10;
led_data[2]=10;
led_data[1]=10;
led_data[0]=10;
}
else {
switch(a){
case 0 :led_data[3]=hour/10;
led_data[2]=hour%10;
led_data[1]=min/10;
led_data[0]=min%10;
break;
case 1 :led_data[3]=year/1000;
d=year%1000;
led_data[2]=d/100;
e=d%100;
led_data[1]=e/10;
led_data[0]=e%10;
break;
case 2 :led_data[3]=month/10;
led_data[2]=month%10;
led_data[1]=10;
led_data[0]=10;
break;
case 3 :led_data[3]=10;
led_data[2]=10;
led_data[1]=date/10;
if(led_data[1]==0)led_data[1]=10;
led_data[0]=date%10;
break;
case 4 : led_data[3]=hour/10;
led_data[2]=hour%10;
led_data[1]=10;
led_data[0]=10;
md=0;
break;
case 5 : led_data[3]=10;
led_data[2]=10;
led_data[1]=min/10;
led_data[0]=min%10;
md=0;
break;
default: break;
}
}
if(b){
led_data[3]=year/1000;
d=year%1000;
led_data[2]=d/100;
e=d%100;
led_data[1]=e/10;
led_data[0]=e%10;
}
else if(c){
led_data[3]=month/10;
led_data[2]=month%10;
led_data[1]=date/10;
if(led_data[1]==0)led_data[1]=10;
led_data[0]=date%10;
}
else if(w){
led_data[3]=week;
led_data[2]=11;
led_data[1]=sec/10;
led_data[0]=sec%10;
}
if((led_data[3]==0)&&(!w))led_data[3]=10;
k=led_data[3];
SBUF=led_xs[k];
while(!TI){}
TI=0;
hs=1;
for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
hs=0;
k=led_data[2];
SBUF=led_xs[k];
while(!TI){}
TI=0;
hg=1;
for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
hg=0;
k=led_data[1];
SBUF=led_xs[k];
while(!TI){}
TI=0;
ms=1;
for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
ms=0;
k=led_data[0];
SBUF=led_xs[k];
while(!TI){}
TI=0;
mg=1;
for(k=0;k<255;k++){_nop_();_nop_();_nop_();}
mg=0;
if(!(a||b||c||w)){
SBUF=0xff;
while(!TI){}
TI=0;
ms=1;
mg=1;
md=sans;
for(k=0;k<255;k++){_nop_();_nop_();}
P1=0x0f;
md=1;
}
}
keyscan()
{
uchar key_value,reread_key;
P1=0x0f;
key_value=P1&0x0f;
if(key_value!=0x0f){
delay_10ms();
reread_key=P1&0x0f;
if(key_value==reread_key){
switch(key_value){
case 0x0e : if(!(b||c||w)){a++;if(a==6)a=0;}
else b=c=w=0;
break;
case 0x0d : switch(a){
case 0 : b=!b;c=w=0;break;
case 1 : year++;break;
case 2 : if(month<12)month++;else month=1;break;
case 3 : dateadd();break;
case 4 : hour++;if(hour==24)hour=0;break;
case 5 : min++;if(min==60)min=0;break;
default: break;
}
break;
case 0x0b : switch(a){
case 0 : c=!c;b=w=0;break;
case 1 : year--;break;
case 2 : month--;if(month==0)month=12;break;
case 3 : datesub();break;
case 4 : hour--;if(hour==0xff)hour=23;break;
case 5 : min--;if(min==0xff)min=59;break;
default: break;
}
break;
case 0x07 : if(a==0){w=!w;b=c=0;}
else{a=0;b=c=w=0;}
break;
default : break;
}
P1=0x0f;
reread_key=P1&0x0f;
while(key_value==reread_key){
reread_key=P1&0x0f;
display();
}
}
}
}
void delay_10ms(void)
{
uchar o,p,q;
for(o=5;o>0;o--)
for(p=4;p>0;p--)
for(q=248;q>0;q--);
}
datesub()
{
switch(month){
case 1 : date--;if(date==0) date=31;break;
case 2 : date--;if(((year%4==0)&&(date==0))==1)date=29;
else if(date==0) date=28;break;
case 3 : date--;if(date==0) date=31;break;
case 4 : date--;if(date==0) date=30;break;
case 5 : date--;if(date==0) date=31;break;
case 6 : date--;if(date==0) date=30;break;
case 7 : date--;if(date==0) date=31;break;
case 8 : date--;if(date==0) date=31;break;
case 9 : date--;if(date==0) date=30;break;
case 10: date--;if(date==0) date=31;break;
case 11: date--;if(date==0) date=30;break;
case 12: date--;if(date==0) date=31;break;
default: break;
}
weekjs();
}
weekjs()
{
uchar c,m,wk,pd,yz;
uint y,p;
if(month==1){m=13;y=year-1;}
else if(month==2){m=14;y=year-1;}
else {y=year;m=month;}
c=y/100;
yz=y%100;
wk=2*c+1;
p=26*(m+1);
pd=p/10;
pd=pd+yz+(yz/4)+(c/4)+date;
if(pd>wk)week=(pd-wk)%7;
else if(pd<wk){week=(7-((wk-pd)%7));if(week==7)week=0;}
else week=0;
}
dateadd()
{
switch(month){
case 1 : date++;if(date==32){date=1;if(a!=3)month++;}break;
case 2 : date++;if(((year%4==0)&&(date==30))==1){date=1;if(a!=3)month++;}
else if(date==29){date=1;if(a!=3)month++;}break;
case 3 : date++;if(date==32){date=1;if(a!=3)month++;}break;
case 4 : date++;if(date==31){date=1;if(a!=3)month++;}break;
case 5 : date++;if(date==32){date=1;if(a!=3)month++;}break;
case 6 : date++;if(date==31){date=1;if(a!=3)month++;}break;
case 7 : date++;if(date==32){date=1;if(a!=3)month++;}break;
case 8 : date++;if(date==32){date=1;if(a!=3)month++;}break;
case 9 : date++;if(date==31){date=1;if(a!=3)month++;}break;
case 10: date++;if(date==32){date=1;if(a!=3)month++;}break;
case 11: date++;if(date==31){date=1;if(a!=3)month++;}break;
case 12: date++;if(date==32){date=1;if(a!=3)month++;}break;
default: break;
}
if(month==13){month=1;year++;}
y=x;
weekjs();
}
⑨ 單片機c語言編程中關於定時器賦值的問題
程序是利用2種類型數據轉換的方式來賦值的,一般來講16位數賦給8位數時,高8位就被屏蔽掉,只賦值低8位給th0和th1。
程序中有點問題的,,其中TH1是放高8位地址所以應該放左移後的8位數,而TL1是放低8位地址,直接復制就可以,,不用&0xff,&了浪費了運行時間。
TH1=(0xffff-40000)>>8;
TL1=(0xffff-40000);
就可以了。
⑩ c語言的變數定義
C語言中變數遵循「先定義後使用」的原則:
1、定義變數的格式:數據類型 變數名;
首先要強調的一點是:變數的定義是一條語句,每條語句都是以分號結尾的。故定義完變數,後面不要漏掉「;」分號。
在變數定義中,「數據類型」表示想要存儲什麼類型的數據就定義什麼類型的變數。
如想要存儲整數就定義成 int 型;想要存儲小數就定義成 float 型或 double 型;想要存儲字元就定義成 char 型等等。
「變數名」就是你想給這個變數起個什麼名字,通常都是用字母、數字與下劃線組合而成。比如:
「int i;double price;double goods_price2」等等。
就表示定義了一個整型變數 i、小數型變數price、goods_price2;
2、變數定義完成後,接下來就是使用變數,為變數賦值。
將一個值放到一個變數中,這個動作叫「賦值」。通俗點講,「給變數賦值」意思就是將一個值傳給一個變數。
賦值的格式是:
變數名 = 要賦的值;
它的意思是將=右邊的數字賦給左邊的變數。比如:
i = 3;
這就表示將 3 賦給了變數 i,此時 i 就等於 3 了。
3、變數的定義和賦值,可以分成兩步寫,也可以將它們合成一步,而且事實上,在實際編程中用得最多的也是合二為一的寫法。
形式如下:
數據類型 變數名 = 要賦的值;
比如:int i = 3;
就表示定義了一個變數 i,並把 3 賦給這個變數。它與
int i;
i =3;
是等價的。
在定義變數時也可以一次性定義多個變數,比如:
int i, j;
這就表示定義了變數 i 和 j。這里需要強調的是,當同時定義多個變數時,變數之間是用逗號隔開的,千萬別寫成分號。這是很多新手最容易犯的錯誤,即將逗號和分號記混了。
同樣也可以在定義多個變數的同時給它們賦值:
int i = 3, j = 4;
中間還是用逗號隔開,最後別忘記輸入分號。
最後需要注意的是,在較老的 C89/C90 標准(也稱 ANSI C 標准)中,變數只能在程序的開頭定義,或者說變數定義的前面不能有其他非聲明或非定義的語句。
(10)c語言編程定時變數擴展閱讀:
在主回答中,提到了變數定義時,變數名通常都是用字母、數字與下劃線組合而成,但是實際上,變數名也不是隨便組合的,變數定義需要遵循一定的規范,否則容易產生歧義,影響整體程序代碼 的可讀性。
所以在定義變數的時候,要注意以下命名規范:
(1)、變數名的開頭必須是字母或下劃線,不能是數字。實際編程中最常用的是以字母開頭,而以下劃線開頭的變數名是系統專用的。命名應當直觀且可以拼讀,可望文知意,便於記憶和閱讀。
標識符最好採用英文單詞或其組合,不允許使用拼音。程序中的英文單詞一般不要太復雜,用詞應當准確。
(2)、變數名中的字母是區分大小寫的。比如 a 和 A 是不同的變數名,num 和 Num 也是不同的變數名。當標識符由多個片語成時,每個詞的第一個字母大寫,其餘全部小寫。
比如: int CurrentVal;
這樣的名字看起來比較清晰,遠比一長串字元好得多。
(3)、變數名絕對不可以是C語言關鍵字,不能有空格。
(4)、變數名的長度應當符合「min-length && max-information」原則。
C 是一種簡潔的語言, 命名也應該是簡潔的。例如變數名MaxVal 就比MaxValueUntilOverflow 好用。標識符的長度一般不要過長,較長的單詞可通過去掉「母音」形成縮寫。
另外,英文詞盡量不縮寫,特別是非常用專業名詞,如果有縮寫,在同一系統中對同一單詞必須使用相同的表示法,並且註明其意思。