用c语言编写计算器.docx
- 文档编号:28595234
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:24
- 大小:23.48KB
用c语言编写计算器.docx
《用c语言编写计算器.docx》由会员分享,可在线阅读,更多相关《用c语言编写计算器.docx(24页珍藏版)》请在冰豆网上搜索。
用c语言编写计算器
板书:
1、在编写控制台程序的时候一切流程都是有先后关系、并行的,而且所有函数都是由我们来调用的,比如下面的实例性代码:
printf("确定请输入y,取消输入n");
charc=getchar();
if(c=='y')
{
///
}
elseif(c=='n')
{
///
}
我们可以用getchar来等待用户输入一个值。
但是到了Windows编程中就不一样了,同一时刻用户即可能点击【OK】按钮,又可能点击【Cancel】按钮,又可能在文本框中输入几个字,还可能在窗口上双击几下,这样就无法同时等待用户的这些动作。
为了解决这个问题,Windows引入了消息机制(也可以叫做回调机制或者事件机制)。
在程序启动的时候把函数func1要响应【OK】按钮1的点击动作、函数func2要响应【Cancel】按钮的点击动作、函数func3要响应窗口的双击动作等等这些信息告诉Windows,然后当用户执行相应操作的时候Windows就会来主动调用你注册的函数,主动通知你。
不再是程序调用操作系统的函数,而是操作系统反过来调用你的函数。
Don'tcallme,I'llcallyou!
(也被人称为“好莱坞法则”)。
2、关于上面的这个问题要慢慢来理解,下面就来通过第一个例子来初步理解这个Don'tcallme,I'llcallyou!
创建一个对话框程序,然后来分析代码。
看Main_OnCommand方法,初探windows的消息机制。
voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify)
{
switch(id)
{
caseIDC_OK:
MessageBox(hwnd,"YouclickOK!
","Test003",MB_OK);
EndDialog(hwnd,id);
break;
caseIDC_CANCEL:
MessageBox(hwnd,"YouclickCancel!
","Test003",MB_OK);
EndDialog(hwnd,id);
break;
default:
break;
}
}
按钮被按下的时候Main_OnCommand方法被调用,hwnd是对话框句柄(什么是句柄后面讲,通俗的说就是通过它能够操纵对话框),id是控件的id,后两个参数暂时不关心。
Main_OnCommand方法中根据id,也就是被点击按钮的名字来决定不同的动作,EndDialog用来关闭对话框。
3、定制自己的对话框,向世界问好
首先打开资源编辑器并且打开对话框IDD_MAIN,然后删除对话框上的两个按钮和标签,同时删除main.cpp中的两个Case语句变成:
voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify)
{
switch(id)
{
default:
break;
}
}
然后重新添加一个自己的按钮,在属性中修改Name属性为IDC_BTNHELLO。
控件名字的潜规则:
所有控件的Name都以“IDC_”开头,然后后边跟着控件类型的简称(按钮简称BTN、文本框简称EDT等等),最后才是控件的真正的名字。
修改按钮的Caption属性(也就是按钮上显示的文字)为“问好”。
在代码中怎么得到IDC_BTNHELLO呢?
刚才被删掉的IDC_OK是什么东东呢?
回忆配置ResEd的时候配置的“名称输出格式”和“默认输出文件名”以及“保存时自动输出”。
每次保存对话框的时候ResEd都会帮我们把控件的名字输出到rsrc.inc文件中,打开工程文件夹下的rsrc.inc,内容如下:
#defineIDC_BTNHELLO
1001
Dialog编辑器会自动递增id的取值。
然后生成rsrc.inc,其实就是h头文件,取这些定义的时候要先include这个inc文件。
可以看到rsrc.inc文件中就是这些控件名字的定义,使用的时候只要include这些文件就可以。
“rsrc.inc”和头文件一样。
因此首先在main.cpp中添加“#include"rsrc.inc"”
编辑Main_OnCommand方法:
voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify)
{
switch(id)
{
caseIDC_BTNHELLO:
MessageBox(NULL,TEXT("世界你好"),TEXT("问好"),MB_OK);
break;
default:
break;
}
}
运行程序,点击“问好”按钮,咱们第一个响应按钮动作的程序就做好了。
4、自己动手写计算器1.0版
(1)、得到控件中用户输入的文本
GetDlgItemText(hwnd,IDC_EDTNAME,str,sizeof(str));
第一个参数是对话框的句柄;第二参数就是控件的id(name);第三个参数就是字符串数组的指针;
疑问:
为什么不能像MessageBox一样把字符串做为返回值返回呢?
?
?
这就涉及到C语言中函数返回指针的问题了
inti=20;
charcStr[3];
itoa(i,cStr,10);
char*f1()
{
return"adsfadsfasd";
}
在函数内部返回函数内构建的指针有可能出现数据混乱.
当f1函数在执行的时候,这段内存是被占用的,一旦函数返回,那么内存就标记为可以被其他人、函数占用。
如果你把这段内存中的指针返回了,那么一旦其他地方用了这段内存,那么你引用的就是错误的数据了。
用GetWindowText、GetDlgItemText的时候为什么要传数组名呢?
复习:
数组名就是指针,函数只有得到指针,才能直接操作数组中的数据。
(2)c语言中字符串连接:
strcat(name,"你好");
但是在编写windows程序的时候最好使用lstrcat代替strcat。
lstrcat(name,"你好");
同样代替的有:
strlen→lstrlen;strcmp→lstrcmp
(3)向用户问好
TCHARname[256];
GetDlgItemText(hwnd,IDC_EDTNAME,name,sizeof(name)/sizeof(TCHAR));
lstrcat(name,"你好");
MessageBox(NULL,name,TEXT("问好"),MB_OK);
(4)
C语言里边字符串转换为数字:
atoi:
asciitoint
(5)
编写windows程序的时候最好用TCHAR来代替char,可以避免中文的问题
caseIDC_BTNHELLO:
TCHARname[256];
GetDlgItemText(hwnd,IDC_EDTNAME,name,sizeof(name)/sizeof(TCHAR));
inti=atoi(name);
intj=i*2;
TCHARresult[256];
itoa(j,result,10);
MessageBox(NULL,result,TEXT("问好"),MB_OK);
(6)Get、Set:
配对的,设置对话框的值用SetDlgItemText:
代码:
caseIDC_BTNADD:
//取第一个文本框的字符串,然后得到整数表示
//取第二个文本框的字符串,然后得到整数表示
//计算两个整数的和
//把和重新转换成字符串,然后Messagebox出来。
TCHARcNumber1[256];
GetDlgItemText(hwnd,IDC_EDTNUM1,cNumber1,sizeof(cNumber1)/sizeof(TCHAR));
intn1=atoi(cNumber1);
TCHARcNumber2[256];
GetDlgItemText(hwnd,IDC_EDTNUM2,cNumber2,sizeof(cNumber2)/sizeof(TCHAR));
intn2=atoi(cNumber2);
intn3=n1+n2;
TCHARcResult[256];
itoa(n3,cResult,10);
SetDlgItemText(hwnd,IDC_EDTRESULT,cResult);
break;
(7)代码中有UINT、TCHAR、LRESULT、HWND之类的新的数据类型,其实它们只是一些类型的别名而已,可以通过宏定义看出来。
但是考虑到可移植性,尽量不要使用它们的真实类型
(8)思考:
这个计算两个数的和程序有什么缺陷?
没有阻止用户输入非数字
(9)作业:
做一个面积计算器,用户输入半径,在另外一个文本框中显示面积。
5、得到系统中有哪些逻辑驱动器
DWORDGetLogicalDrives(VOID);
返回值的二进制位标志着存在哪些驱动器。
其中,位0设为1表示驱动器A存在于系统中;位1设为1表示存在B驱动器;以次类推。
比如:
00001100:
有C盘,D盘
000011100:
c、d、e
1101:
A(软驱)、C、D
(1)写程序中的错误排除
"dwDrives"wasnotdeclaredinthescope
declare:
声明;scope:
范围
"dwDrives"没有被声明在这个范围内。
(2)以二进制显示GetLogicalDrives的返回值:
stdlib.h
DWORDds=GetLogicalDrives();
charstr[33];
itoa(ds,str,2);
MessageBox(NULL,str,"",MB_OK);
DWORD是什么类型?
在DWORD上点击右键,选择“转到DWORD的定义”,其实DWORD是“unsignedlong”。
因此str定义成33位(还有最后一位的“\0”)。
(3)课后习题:
判断是否存在D盘。
(4)课后习题:
依次显示系统中所有的盘符。
比如显示出“CDEF”。
(5)课后习题:
显示系统中有多少个逻辑驱动器。
这三道课后作业都是在锻炼位运算。
一定要重视,不要一位没啥意思,很多公司的笔试面试都会考查这一点,这也是继续深入研究C和其他语言的基础。
Main_OnCommand函数的响应按钮段:
CODE:
voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify)
{
TCHARcDriveExists[]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
intnLen=0;
switch(id)
{
caseIDC_BTNRESULT:
//响应计算圆面积按钮
TCHARcBanjing[256];
GetDlgItemText(hwnd,IDC_EDTRADIUS,cBanjing,sizeof(cBanjing)/sizeof(TCHAR));
doublefBanjing,fZhouchang;
fBanjing=atof(cBanjing);
fZhouchang=3.1415926*(fBanjing*fBanjing);
TCHARcZhouchang[256];
gcvt(fZhouchang,10,cZhouchang);
//SetDlgItemText(hwnd,IDC_EDTZHOUCHANG,cZhouchang);
SetDlgItemText(hwnd,IDC_STC,cZhouchang);
break;
caseIDC_BTNCALCHELP:
//响应圆面积帮助按钮
MessageBox(hwnd,TEXT("\n圆形面积计算公式:
\n\n圆面积(s)=圆周率π(3.14)*半径(r)的平方。
\t"),TEXT("计算公式"),MB_OK|MB_ICONASTERISK);
break;
caseIDC_BTNGETDRIVERS:
//获取用户磁盘信息按钮
DWORDdwMydrivers;
dwMydrivers=GetLogicalDrives();
TCHARcDrivers[256];
itoa(dwMydrivers,cDrivers,2);//转换为字符串
strrev(cDrivers);//反转字符串
TCHARcDriverscn[256];
//MessageBox(hwnd,cDrivers,TEXT("调试"),MB_OK);
//列出所有存在盘符
inti;
for(i=0;i { if(cDrivers[i]=='1') { cDriverscn[nLen]=cDriveExists[i]; nLen++; } } cDriverscn[nLen]='\0'; SetDlgItemText(hwnd,IDC_EDTMYDRIVERS,cDriverscn); //判断是否存在D盘 if(cDrivers[4]='1') { SetDlgItemText(hwnd,IDC_EDTYESNOD,TEXT("有")); } else { SetDlgItemText(hwnd,IDC_EDTYESNOD,TEXT("无")); } //计算存在磁盘总数 TCHARcSUM[256]; itoa(nLen,cSUM,10); SetDlgItemText(hwnd,IDC_EDTDRIVERSNUM,cSUM); break; default: break; } } #include"rsrc.inc"rsrc.inc文件里面的内容 CODE: #defineIDC_GRPCALC1001 #defineIDC_GRP11014 #defineIDC_EDTRADIUS1002 #defineIDC_BTNRESULT1003 #defineIDC_BTNCALCHELP1006 #defineIDC_BTNGETDRIVERS1008 #defineIDC_STC11005 #defineIDC_EDTMYDRIVERS1007 #defineIDC_EDTYESNOD1009 #defineIDC_EDTDRIVERSNUM1010 #defineIDC_STC21011 #defineIDC_STC31012 #defineIDC_STC41013 #defineIDC_STC1015 dialogs.dlg文件的内容 CODE: #defineIDC_GRPCALC1001 #defineIDC_GRP11014 #defineIDC_EDTRADIUS1002 #defineIDC_BTNRESULT1003 #defineIDC_BTNCALCHELP1006 #defineIDC_BTNGETDRIVERS1008 #defineIDC_STC11005 #defineIDC_EDTMYDRIVERS1007 #defineIDC_EDTYESNOD1009 #defineIDC_EDTDRIVERSNUM1010 #defineIDC_STC21011 #defineIDC_STC31012 #defineIDC_STC41013 #defineIDC_STC1015 #include"dialogs.h" #include IDD_MAINDIALOGEX122,75,245,193 LANGUAGE4,2 CAPTION"calc" FONT8,"Tahoma",0,0,0 STYLEWS_POPUP|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MAXIMIZEBOX BEGIN CONTROL"",IDC_EDTRADIUS,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP,102,29,54,13,WS_EX_CLIENTEDGE CONTROL"计算",IDC_BTNRESULT,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,162,29,42,13 CONTROL"帮助",IDC_BTNCALCHELP,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,162,46,42,13 CONTROL"获取磁盘信息",IDC_BTNGETDRIVERS,"Button",WS_CHILD|WS_VISIBLE|WS_TABSTOP,90,158,66,13 CONTROL"计算结果: ",IDC_STC1,"Static",WS_CHILD|WS_VISIBLE|WS_GROUP,60,48,40,9 CONTROL"",IDC_EDTMYDRIVERS,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_READONLY,126,118,86,13,WS_EX_CLIENTEDGE CONTROL"",IDC_EDTYESNOD,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_READONLY,126,99,86,13,WS_EX_CLIENTEDGE CONTROL"",IDC_EDTDRIVERSNUM,"Edit",WS_CHILD|WS_VISIBLE|WS_TABSTOP|ES_READONLY,126,136,86,13,WS_EX_CLIENTEDGE CONTROL"系统中是否存在有D盘: ",IDC_STC2,"Static",WS_CHILD|WS_VISIBLE|WS_GROUP,30,101,90,9 CONTROL"系统中存在的所有磁盘: ",IDC_STC3,"Static",WS_CHILD|WS_VISIBLE|WS_GROUP,30,120,88,9 CONTROL"系统中逻辑驱动器个数: ",IDC_STC4,"Static",WS_CHILD|WS_VISIBLE|WS_GROUP,30,138,88,9 CONTROL"请输入圆的半径r=",IDC_TEXT,"Static",WS_CHILD|WS_VISIBLE|WS_GROUP,34,31,68,9 CONTROL"计算圆面积",IDC_GRPCALC,"Button",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,22,14,202,59 CONTROL"本地磁盘信息",IDC_GRP1,"Button",WS_CHILD|WS_VISIBLE|BS_GROUPBOX,22,84,202,94 CONTROL"请输入半径",IDC_STC,"Static",WS_CHILD|WS_VISIBLE,104,48,54,9 END 杨中科at2008-10-2821: 52: 55 diamondboy的答案非常好,值得鼓励! ! ! 你想一下GetLogicalDriver相关的那几道作业题有没有更高效的解法呢? 提示一下使用位运算。 你可以参考咱们以前的C#的课的内容: ...&extra=page%3D1 位运算是语言无关的,而且C#的位运算和C一模一样,完全可以参考。 还是那句话“一通百通”。 咱们的论坛已经可以上传附件了,可以把你的作业上传上来。 再次为diamondboy喝彩。 diamondboyat2008-10-2921: 05: 44 晕了呢,我就搞不懂所谓的位运算是怎么回事呢,二进制的东东看了就懵了。 。 现在就去看老大给的视频去。 。 。 calc.rar (2008-10-2921: 05: 44,Size: 19.9KB,Downloads: 119) shiren1118at2008-10-3121: 37: 09 老杨辛苦,呵呵 willweiweiat2008-12-0900: 37: 10 由itoa是英文integertoarray得atoi是英文arraytointeger XX得到的 貌似不是C语言里边字符串转换为数字: atoi: asciitoint 哈哈 鸡蛋里面挑骨头 Joshuaat2008-12-1221: 31: 13 voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify) { inti=0; DWORDx,t=1; charsz[26],p='A'; if(id==IDC_BTNGET) { x=GetLogicalDrives(); while(x>0) { if((t&x)==1){sz=p;++i;} x>>=1;++p; } SetDlgItemText(hwnd,IDC_EDTOUT,sz); } } 获取本机磁盘列表。 Joshuaat2008-12-1222: 10: 57 更正下: 在SetDlgItemText(hwnd,IDC_EDTOUT,sz);上还要加一句sz='\0'; 635260101at2009-4-0414: 15: 59 先做了计算器... caclv1.rar (2009-04-0414: 15: 59,Size: 31KB,Downloads: 63) makesueat2009-4-1601: 31: 51 本人位运算显示磁盘信息的代码 voidMain_OnCommand(HWNDhwnd,intid,HWNDhwndCtl,UINTcodeNotify) { switch(id) { caseIDC_BTN1: DWORDd=GetLogicalDrives(); if((d&8)>0) { TCHARc[256]; SetDlgItemText(hwnd,IDC_EDT1,TEXT("存在")); } else { SetDlgItemText(hwnd,IDC_EDT1,TEXT("不存在")); } break; caseIDC_BTN2: hanshu(hwnd); break; caseIDC_BTN3: hanshu1(hwnd); break; default: break; } } voidhanshu(HWNDhwnd) { DWORDd1=GetLogicalDrives(); inti=0; while(d1>0) { if((d1&1)>0) { i++; } d
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 编写 计算器