如何用指向函数的指针替换switch-case
- 格式:doc
- 大小:49.00 KB
- 文档页数:4
习题解答一、单项选择题1.若定义了int n=2, *p=&n, *q=p;则下面【】的赋值是非法的。
A.p=qB. *p=*qC. n=*qD. p=n【答案】D2.若定义了double *p, a;则能通过scanf函数给输入项读入数据的程序段是【】。
A.p=&a; scanf(“%1e”,p);B. *p=&a; scanf(“%1f”,p);C. p=&a; scanf(“%f”,p);D. p=&a; scanf(“%1f”,a);【答案】C3.若定义了int a[10], i=3, *p; p=&a[5];下面不能表示为a数组元素的是【】。
A.p[-5]B. a[i+5]C. *p++D. a[i-5]【答案】D4.若有如下定义:int n[5]={1,2,3,4,5},*p=n;则值为5的表达式是【】。
A.*+5B. *(p+5)C. *p+=4D. p+4【答案】C5.设变量b的地址已赋给指针变量ps,下面为“真”的表达式是【】。
A.b==&psB. b==psC. b==*psD. &b==&ps【答案】C6.设有以下定义和语句:int a[3][2]={1,2,3,4,5,6},*p[3];p[0]=a[1];则*(p[0]+1)所代表的数组元素是【】。
A.a[0][1]B. a[1][0]C. a[1][1]D. a[1][2]【答案】C7.若定义了char *str=”Hello!”;下面程序段中正确的是【】。
A.char c[ ], *p=c; strcpy(p,str);B.char c[5], *p; strcpy(p=&c[1],&str[3]);C.char c[5]; strcpy(c,str);D.char c[5]; strcpy(p=c+2,str+3);【答案】B8.若有下面的程序段,则不正确的fxy函数的首部是【】。
在C++中存在两种转换:隐式转换和显式转换(强制转换)。
一、隐式类型转换C++定义了一组内置类型对象之间的标准转换,在必要时它们被编译器隐式地应用到对象上。
隐式类型转换发生在下列这些典型的情况下;1、在混合类型的算术表达式中。
在这种情况下,最宽的数据类型成为目标转换类型。
这也被称为算术转换arithmetic conversion 例如:int ival = 3;double dval = 3.14159;// ival 被提升为double 类型: 3.0 (是一种保值转换)ival + dval;2、用一种类型的表达式赋值给另一种类型的对象。
在这种情况下,目标转换类型是被赋值对象的类型。
例如,在下面第一个赋值中文字常量0 的类型是int 它被转换成int*型的指针表示空地址在第二个赋值中double 型的值被截取成int 型的值。
// 0 被转换成int*类型的空指针值int *pi = 0;// dval 被截取为int值3 (这不是保值转换),一般情况下编译器会给出warning.ival = dval;3、把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同。
在这种情况下,目标转换类型是形式参数的类型。
例如:extern double sqrt( double );// 2 被提升为double 类型: 2.0cout4、从一个函数返回一个表达式,表达式的类型与返回类型不相同。
在这种情况下,目标转换类型是函数的返回类型。
例如:double difference( int ival1, int ival2 ){// 返回值被提升为double 类型return ival1 - ival2;}二、显示转换(强制转换)(一)、旧式强制类型转换:由static_cast,cons_cast 或reinterpret_cast 强制转换符号语法,有时被称为新式强制转换符号,它是由标准C++引入的。
精心整理页脚内容+、-、*、/解释:C 语言的运算符——加、减、乘、除。
+=、-=、*=、/=、%=解释:C 语言的运算符——修改和替代。
.解释:C 语言的运算符——结构或联合的成员选择。
,解释:~解释:*解释:!解释:&解释:&&%解释:;解释::::++--=解释:C 语言的①运算符——赋值。
②分隔符——用于分隔变量说明和初始化表。
==解释:C 语言的运算符——等于。
!=解释:C 语言的运算符——不等于。
>=解释:C 语言的运算符——大于等于。
>解释:C 语言的运算符——大于。
精心整理页脚内容<=解释:C语言的运算符——小于等于。
<解释:C语言的运算符——小于。
->解释:C语言的运算符——指向结构(C++语言中的类)成员的指针引用。
<<解释:C语言的运算符——字位左移。
>>解释:C语言的运算符——字位右移。
^解释:C语言的运算符——按位异或。
|解释:||[](){}(类型名\\\0\a\b\n\r\t解释:C语言的转义(换码)序列——制表符。
abstract解释:Java类修饰符(定义类时用),表示该类是一个抽象类,不能直接产生该类的一个对象。
auto解释:C语言的存储类区分符(一种说明区分符)。
break解释:C语言的转移语句——终止执行switch语句,或跳出循环语句。
case解释:C语言的标号。
用于开关语句中。
.char解释:C语言的数据类型区分符(说明区分符)。
定义单字节变量。
class解释:C++语言的合成类型区分符(说明区分符)。
说明“类”类型。
const解释:C++语言的类型区分符(说明区分符)。
continue解释:C语言的转移语句——跳过位于continue后面的语句,立即开始下一轮循环。
default解释:C语言的标号。
用于开关语句中。
delete解释:C++语言的释放内存语句。
double解释:C语言的数据类型区分符(说明区分符)。
易语言指针调用方法在易语言中,指针是一个非常重要的概念,它可以用来实现各种高级的操作。
指针是一个变量,它存储的是另一个变量的地址。
通过指针,我们可以访问和修改另一个变量的值。
在本文中,我们将介绍如何使用指针来调用函数和方法。
首先,我们需要了解指针的类型。
在易语言中,指针有两种类型,分别是整型指针和字符型指针。
整型指针指向一个整数变量的地址,而字符型指针指向一个字符变量的地址。
我们可以使用以下语句声明一个指针变量:整型指针:Dim p As Integer字符型指针:Dim p As Char接下来,我们将介绍如何使用指针来调用函数和方法。
调用函数要使用指针来调用函数,我们需要先将函数的地址保存到指针变量中。
以下是一个简单的例子:Function Test(a As Integer, b As Integer) As IntegerReturn a + bEnd Function'声明一个指向Test函数的指针Dim p As Integerp = GetFuncAddress('Test')'调用Test函数Dim result As Integerresult = CallFuncByAddr(p, 1, 2)Print(result)在上面的例子中,我们使用GetFuncAddress函数来获取Test函数的地址,并将其保存到指针变量p中。
然后,我们使用CallFuncByAddr函数来调用Test函数,并传递参数1和2。
最后,我们将Test函数返回的结果打印出来。
调用方法要使用指针来调用方法,我们需要先获取类的实例对象的地址,并将其保存到指针变量中。
以下是一个简单的例子:Class TestClassMethod TestMethod(a As Integer, b As Integer) As Integer Return a + bEnd MethodEnd Class'创建一个TestClass的实例对象Dim obj As New TestClass'获取TestClass实例对象的地址Dim objAddr As IntegerobjAddr = ObjToPtr(obj)'声明一个指向TestMethod方法的指针Dim p As Integerp = GetMethodAddress(objAddr, 'TestMethod')'调用TestMethod方法Dim result As Integerresult = CallMethodByAddr(p, objAddr, 1, 2)Print(result)在上面的例子中,我们创建了一个TestClass的实例对象,并将其保存到obj变量中。
c语言重命名替换库函数-回复C语言是一种流行的程序设计语言,广泛用于各种领域的软件开发。
C 语言提供了丰富的标准库函数,这些函数可以帮助开发人员完成各种常见的任务。
然而,有时候我们需要对这些库函数进行一些修改或替换,以满足特定需求。
本文将介绍如何在C语言中重命名和替换库函数。
一、为什么需要重命名和替换库函数?在实际的软件开发过程中,我们有时会遇到一些特殊的情况,需要对库函数进行修改或替换。
这些情况可能包括以下几种:1. 与其他库函数冲突:在某些情况下,我们引入了一个新的库函数,但是它与某个已经存在的库函数名字相同,这就会导致冲突。
为了解决这个问题,我们需要对其中一个库函数进行重命名。
2. 功能扩展或改进:有时候我们需要对某个库函数的功能进行扩展或改进,以满足特定需求。
这可能需要对函数进行修改或完全替换。
3. 库函数不可用:在某些嵌入式系统或特定的环境下,一些标准的库函数可能不可用。
这就需要我们自己实现一个替代的函数。
二、重命名库函数的步骤如果我们需要对某个库函数进行重命名,可以按照以下步骤进行:1. 确定要重命名的函数:首先,我们需要确定要重命名的函数是哪个。
这可能是由于与其他函数冲突或者需要修改函数功能。
2. 找到函数的定义:然后,我们需要找到该函数的定义和声明。
这通常可以在相应的头文件或库文件中找到。
我们需要确保我们找到了所有相关的定义和声明。
3. 修改函数的名字:一旦我们找到了函数的定义和声明,我们可以将函数的名字修改为我们希望的新名字。
这个新名字不能与其他函数或变量冲突,最好是具有描述性和一致性的。
4. 修改函数的调用:接下来,我们需要在代码中将函数的所有调用处修改为新的函数名字。
这可能需要在整个项目中进行全局搜索替换。
5. 编译项目并测试:完成上述步骤后,我们需要编译整个项目,并进行测试以确保重命名的函数没有引入新的问题。
三、替换库函数的步骤如果我们需要替换某个库函数,可以按照以下步骤进行:1. 确定要替换的函数:首先,我们需要确定要替换的函数是哪个。
C语⾔switchcase圈复杂度优化重构软件重构是改善代码可读性、可扩展性、可维护性等⽬的的常见技术⼿段。
圈复杂度作为⼀项软件质量度量指标,能从⼀定程度上反映这些内部质量需求(当然并不是全部),所以圈复杂度往往被很多项⽬采⽤作为软件质量的度量指标之⼀。
C语⾔开发的项⽬中,switch/case代码块是⼀个很容易造成圈复杂度超标的语⾔特性,所以本⽂主要介绍下降低switch/case圈复杂度的重构⽅法(如下图)。
switch圈复杂度优化重构可分为两部分:程序块的重构和case的重构。
程序块重构是对代码的局部优化,⽽case重构是对代码的整体设计,所涉及的重构⼿段也各不相同。
程序块重构程序块重构指的是每个case内的代码段重构。
Martin Fowler 的《》()书中总结了80多种重构⽅法。
书中针对每种技术都给出了⽰例说明,另外、还提供了其他语⾔的⽰例和进⼀步介绍。
因为存在⼤量⽰例,所以本⽂针对这些⽅法不再给出⽰例,有兴趣的同学可以通过上⾯⼏种途径了解学习。
不过这些技术中有些是改善代码的可读性,有些是改善代码的可扩展性,并不是每项技术都能有效减低圈复杂度。
其中可以降低圈复杂度的⽅法有如下⼏种:提炼函数(Extract Method)。
你有⼀段代码可以被组织在⼀起并独⽴出来。
将这段代码放进⼀个独⽴函数中,并将函数名称解释该函数的⽤途。
分解条件表达式(Decompose Conditional)。
你有⼀个复杂的条件(if-then-else)语句。
从if、then、else三分段落中分别提炼出独⽴函数。
合并条件表达式(Consolidate Conditional Expression)。
你有⼀系列条件测试,都得到相同结果。
将这些测试合并为⼀个条件表达式,并将这个条件表达式提炼成为⼀个独⽴函数。
合并重复的条件⽚段(Consolidate Duplicate Conditional Fragments)。
1.switch…case结构中case后的表达式必须为常量表达式。
(1分)正确错误2.C 语言程序中可以有多个函数, 但只能有一个主函数。
(1分)正确错误3.printf()的输出项既可以是表达式和变量,也可以是常量和函数调用。
(1分)正确错误4.可以在程序中的任何位置声明变量。
(1分)正确错误5.C语言中引用数组元素时,数组元素的下标从0始。
(1分)正确错误6.do-while构成的循环,当while中的表达式的值为零时结束循环(1分)正确错误7.调用函数时,只能把实参的值传送给形参,形参的值不能传送给实参(1分)正确错误8.do-while语句构成的循环必须用break语句才能退出(1分)正确错误9.在C语言中,定义数组时如果要对部分数组元素赋初值,所有的下标均可省略。
(1分)正确错误10.在for循环中,不能用break语句跳出循环体(1分)正确错误11.有定义语句int x=12;double b=3.14;则表达式'A'+x+b的值类型为char.(1分)正确错误12.多分支结构中,switch后的表达式必须为常量。
(1分)正确错误13.在C语言中,指针变量不能作为函数的形式参数。
(1分)正确错误14.main可作为用户标识符,用以定义任意一个函数(1分)正确错误15.在C语言中,若有如下定义:int a;int *p=a;是可以的。
(1分)正确错误16.在C语言中,用数组名作为函数的实参,实际上是将数组的首地址传递给被调用函数(1分)正确错误17.在C语言程序中,被调用的函数必须在main函数中定义(1分)正确错误18.C语言中同一数组中的各数组元素会被随机分配在一段不连续的内存区域中。
(1分)正确错误19.只能在循环体内和switch语句体内使用break语句(1分)正确错误20.在C语言中,用数组名作为函数的实参,被调用函数中形参所指向数组元素的值的改变不会引起原数组值的改变。
C51编译器识别错类型有三种1、致命错误:伪指令控制行有错,访问不存在的原文件或头文件等。
2、语法及语义错误:语法和语义错误都发生在原文件中。
有这类错误时,给出提示但不产生目标文件,错误超过一定数量才终止编译。
3、警告:警告出现并不影响目标文件的产生,但执行时有可能发生问题。
程序员应斟酌处理。
D.1 致命错误C_51 FATAL_ERRORACTION: <当前行为>LINE: <错误所在行>ERROR: <错误信息> terminated或C_51 FATAL ERRORACTION: <当前行为>FILE: <错误所在文件>ERROR: <错误信息> terminatedC_51 TERMINATED C_51(1) ACTION 的有关信息*PARSING INVOKE-/#PRAGMA_LINE在对#pragma 指明的控制行作此法分析时出错。
*ALLOCATING MEMORY系统分配存储空间时出错。
编译较大程序需要512k空间。
*OPENING INPUT_FILE打开文件时,未找到或打不开源文件/头文件。
*CREATE LIST_FILE/OBJECT_FILE/WORK_FILE不能创建上述文件。
可能磁盘满或文件已存在而且写保护。
*PARSING SOURCE_FILE/ANALYZING DECLARATIONS分析源程序时发现外部引用名太多。
*GENERATING INTERMEDIATE CODE源代码被翻译成内部伪代码,错误可能来源于函数太大而超过内部极限。
*WRITING TO FILE在向文件(work,list,prelist或object file)写时发生错误。
(2)ERROR的有关信息*MEMORY SPACE EXHAUSTED所有可用系统空间耗尽。
至少需要512k 字节空间。
没有足够空间,用户必须检查常驻内存的驱动程序是否太多。
指针的三种表示方法
指针是C语言中一种重要的数据类型,它是用来存储变量地址的。
在C语言中,指针可以用三种方式来表示,分别是指针变量、指针常量和指向指针的指针。
1. 指针变量
指针变量是指存储变量地址的变量。
它的声明方式为:数据类型*变量名;其中,数据类型表示指针变量所指向的数据类型,而变量
名则是指针变量的名称。
指针变量可以通过取地址符&来获取变量的
地址,并且可以通过解引用符*来访问指针变量所指向的变量。
2. 指针常量
指针常量是指不能改变其所指向的变量地址的指针。
它的声明方式为:const 数据类型 *变量名;其中,const关键字表示该指针常量的值不可被修改。
指针常量可以用于函数参数中,以确保函数内部不会修改该指针所指向的变量地址。
3. 指向指针的指针
指向指针的指针是指一个指针变量指向另一个指针变量的地址。
它的声明方式为:数据类型 **变量名;其中,数据类型表示指向指
针变量所指向的数据类型,而变量名则是指向指针的指针的名称。
指向指针的指针可以用于多级指针的情况,如在动态内存分配中的链表或树等数据结构中。
以上就是指针的三种表示方法,掌握它们对于学习C语言编程非常重要。
程序中当switch-case里面有很多分支,且每个分支有很多操作要做时,会花费很多时间,优化的方法有很多,比如将可能性大的放在前
面,将case操作压缩,其实,最好的方法利用指向函数的指针解决问题,下面我们来看一个例子:
先来一个switch-case的模板:
view plaincopy to clipboardprint?
1. #include
2. #include
3.
4. enum MsgType{ Msg1=1 ,Msg2 ,Msg3 ,Msg4 };
5.
6. int menu()
7. {
8. int choice;
9. printf("1.ADD/n");
10. printf("2.DEL/n");
11. printf("3.SORT/n");
12. printf("4.exit/n");
13. printf("input your choice:/n");
14. scanf("%d",&choice);
15. return choice;
16. }
17.
18. void ADD()
19. {
20. NULL;
21. //
22. }
23.
24. void DEL()
25. {
26. NULL;
27. //
28. }
29.
30. void SORT()
31. {
32. NULL;
33. //
34. }
35.
36. int main()
37. {
38. while(1)
39. {
40. switch(menu())
41. {
42. case Msg1:
43. ADD();
44. break;
45. case Msg2:
46. DEL();
47. break;
48. case Msg3:
49. SORT();
50. break;
51. case Msg4:
52. exit(0);
53. break;
54. default:
55. printf("input error/n");
56. break;
57. }
58. }
59. return 0;
60. }
61.
62.
那我们怎样将这个switch-case的模板改成利用指向函数的指针解决的问题呢?答案就在下面:
view plaincopy to clipboardprint?
1. #include
2. #include
3.
4. void ADD();
5. void DEL();
6. void SORT();
7. void EXIT();
8.
9. void (*MsgFunc[])()={ ADD ,DEL ,SORT ,EXIT };
10.
11. int menu()
12. {
13. int choice;
14. printf("1.ADD/n");
15. printf("2.DEL/n");
16. printf("3.SORT/n");
17. printf("4.EXIT/n");
18. printf("input your choice:/n");
19. scanf("%d",&choice);
20. return choice-1;
21. }
22.
23. int main()
24. {
25. while(1)
26. {
27. MsgFunc[menu()]();
28. }
29. return 0;
30. }
31.
32. void ADD()
33. {
34. NULL;
35. //
36. }
37.
38. void DEL()
39. {
40. NULL;
41. //
42. }
43.
44. void SORT()
45. {
46. NULL;
47. //
48. }
49.
50. void EXIT()
51. {
52. exit(0);
53. }
54.
55.
这样,就用指向函数的指针解决了switch-case,且代码量也变少了,程序模块化也变清晰了。在编程中要充分利用这些知识来优化程
序。