life02

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  197 随笔 :: 3 文章 :: 37 评论 :: 0 Trackbacks

http://blog.csdn.net/yysdsyl/archive/2007/12/30/2005232.aspx
另一个笔试版本

1,题:请定义一个宏,比较两个数a,b的大小,不能使用大于、小于、if语句。

     答案:#define Max(a,b)  (a/b)?a:b

相关:

(1)在C语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。

(2)宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。

(3)在C语言中,“宏”分为有参数和无参数两种。

(4)无参数宏定义

          一般形式:   #define  标识符 字符串

          其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。比如说符号常量的定义就是一种无参宏定义。此外,常对程序中反复使用的表达式进行宏定义。例如:# define M   (y*y+3*y),定义M为表达式(y*y+3*y),在编写源程序时,所有的(y*y+3*y)都可由M代替,而对源程序做编译时,将先有预处理程序进行宏代换,即用(y*y+3*y)表达式去置换所有的宏名M,然后再进行编译。

            例子:

                             #   define M (y*y+3*y)

                             main(){

                                  int s,y;

                                  printf ("input a number:")

                                  scanf("%d",&y);

                                  s=3*M+4*M+5*M;

                                  printf("s=%d\n",s);

                             }

             注意:上例程序中。宏定义表达式(y*y+3*y)两边的括号不能少,否则会发生错误。当做以下定义后:# define M y*y+3*y在宏展开时将得到下述语句:

s=3*y*y+3*y+4*y*y+3*y+5*y*y+3*y,显然与题意不符。因此,在作宏定义时必须十分注意,应保证在宏代换之后不发生错误。

(5)带参数宏定义

        C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。

        一般定义形式:    # define  宏名 (形参表) 字符串 

        在字符串中含有各个形参。

        一般调用形式:     宏名(实参表)

        例如:  

                          #   define  MAX(a,b)      (a>b)?a:b

                          main () {

                                int x,y,max;

                                printf("input two numbers:");

                                scanf("%d%d",&x,&y);

                                max=MAX(x,y);

                                printf("max=%d\n",max);

                          }

(6) 对于宏定义语句,预处理程序对它不作任何检查,如果有错误,只能在编译已被宏展开后的源程序时发现。

(7)宏定义在行末不必加分号,如加上分号则连分号也一起置换。

(8)宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如要终止其作用域可使用#underf命令。

                        例如:

                                  #  define  PI 3.14159

                                  main()

                                  {

                                  ......

                                  }

                                  # underf  PI

                                  f1()    

             在这段程序中,PI只在main函数中有效,在f1()中无效。

(9)宏名在源程序中若用引号括起来,则预处理程序不对其做宏代换。

                          例如:

                                #   define   Ok  100

                                main()

                                {

                                      printf("OK");

                                      printf("\n");

                                 }

               在这段程序中,宏名OK表示100,但在printf语句中OK被引号括起来,因此不做宏代换,把“OK”当字符串处理。程序的运行结果为:OK

 (10)宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开时由预处理程序层层代换。

                           例如:

                                 #define   PI   3.14159

                                 #define   S     PI*y*y

(11)习惯上宏名用大写字母表示,以便与变量区别。但也允许用小写字母。

(12)可用宏定义表示数据类型,使书写方便。

                           例如:

                                 # define  STU  struct stu

                       这样一来,可以在程序中使用STU做变量说明,例如:

                                 STU  body[5],*p;

(14)对“输出格式”做宏定义,可以减少书写麻烦。

                            例如:

                                  # define  P printf

                                  #define   D "%d\n"

                                  #define  F "%f\n"

                                  main(){

                                  int a=5, c=8, e=11;

                                  float b=3.8,  d=9.7,   f=21.08;

                                  P(D F,a,b);

                                  P(D F,c,d);

                                  P(D F,e,f);

                                  }

(15)带参宏定义中,宏名和形参表之间不能有空格出现。

                         例如:  #define  MAX(a,b)  (a>b)?a:b

                  不能写成     #define  MAX  (a,b)  (a>b)?a:b  这样一来,宏调用语句:

max=MAX(x,y)  将变为:  max=MAX(a,b)(a>b)?a:b(x,y)   ,这显然是错误的。

(16)再带参宏定义中,形式参数不分配内存单元,因此不必做类型定义。而宏调用中的实参有具体值。要用他们去代换形参,因此必须做类型说明。这是与函数中的情况不同的。在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。

(17)在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。

                        例如:

                                #define SQ(y)  (y)*(y)

                                main(){

                                int a,sq;

                                printf("input a number:");

                                scanf("%d",&a);

                                sq=SQ(a+1);

                                printf("sq=%d\n",sq);

                                } 

                                

(18)在宏定义中,字符串内的形参通常要用括号括起来以避免出错,例如把上面的例子改成:

                                #define SQ(y)  y*y

                                main(){

                                int a,sq;

                                printf("input a number:")

                                scanf("%d",&a);

                                sq=SQ(a+1)

                                }

              当给a赋值为3时运行的结果是sq=7。

(19)为避免错误,对于宏定义不仅应在参数两侧加括号,也应在整个字符串外加括号。

(20)宏定义也可以用来定义多个语句,在宏调用时,把这些语句又代换到源程序内。

                      例如:

                                  #define SSSV(s1,s2,s3,v)    s1=l*w;s2=l*h,s3=w*h,v=w*l*h;

                                  main(){

                                         int l=3,w=4,h=5,sa,sb,sc,vv;

                                         SSSV(sa,sb,sc,vv);

                                         printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv);

                                  }

                 上述程序第一行为宏定义,用宏名SSSV表示4个赋值语句,4个形参分别为4个赋值符左边的变量。在宏调用时,把4个语句展开并用实参代替形参。使计算结果送入实参中。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/omaigaode/archive/2008/12/04/3441834.aspx

posted on 2009-10-23 15:00 life02 阅读(926) 评论(1)  编辑 收藏 引用 所属分类: 笔试

评论

# re: 09腾讯笔试题(转) 2009-10-24 09:17 tiny
第一题答案对吗?#define Max(a,b) (a/b)?a:b
a = -2, b = -1
这个问题不是这么简单的吧。
考虑到正负数,考虑到无符号情况  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理