﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客网-嵌入式-文章分类-C/C++</title><link>http://www.cnitblog.com/zouzheng/category/4500.html</link><description>要像阿甘一直向前奔跑！</description><language>zh-cn</language><lastBuildDate>Fri, 29 Feb 2008 13:30:16 GMT</lastBuildDate><pubDate>Fri, 29 Feb 2008 13:30:16 GMT</pubDate><ttl>60</ttl><item><title>static关键字</title><link>http://www.cnitblog.com/zouzheng/articles/40309.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Fri, 29 Feb 2008 12:49:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/40309.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/40309.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/40309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/40309.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/40309.html</trackback:ping><description><![CDATA[<p><strong><font color=#02368d size=5>static关键字</font></strong><br><span><strong>1．作用于变量：</strong></span><br><span style="FONT-FAMILY: 宋体">&nbsp;&nbsp; 用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">声明局部变量-------<span style="FONT-FAMILY: 宋体">局部变量指在代码块</span><span lang=EN-US>{}</span><span style="FONT-FAMILY: 宋体">内部定义的变量，只在代码块内部有效（作用域），其缺省的存储方式是自动变量或说是动态存储的，即指令执行到变量定义处时才给变量分配存储单元，跳出代码块时释放内存单元（生命期）。用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">声明局部变量时，则改变变量的存储方式（生命期），使变量成为静态的局部变量，即编译时就为变量分配内存，直到程序退出才释放存储单元。这样，使得该局部变量有记忆功能，可以记忆上次的数据，不过由于仍是局部变量，因而只能在代码块内部使用（作用域不变）。<br></span></span><span style="FONT-FAMILY: 宋体"><br></span><span style="FONT-FAMILY: 宋体">&nbsp;&nbsp; 用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">声明外部变量-------<span style="FONT-FAMILY: 宋体">外部变量指在所有代码块</span><span lang=EN-US>{}</span><span style="FONT-FAMILY: 宋体">之外定义的变量，它缺省为静态变量，编译时分配内存，程序结束时释放内存单元。同时其作用域很广，整个文件都有效甚至别的文件也能引用它。为了限制某些外部变量的作用域，使其只在本文件中有效，而不能被其他文件引用，可以用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">关键字对其作出声明。</span></span><br><br><span style="FONT-FAMILY: 宋体">总结：用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">声明局部变量，使其变为静态存储方式，作用域不变；用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">声明外部变量，其本身就是静态变量，这只会改变其连接方式，使其只在本文件内部有效，而其他文件不可连接或引用该变量。</span></p>
<p><span><strong>2．作用于函数：</strong></span><br><span style="FONT-FAMILY: 宋体">使用</span><span lang=EN-US>static</span><span style="FONT-FAMILY: 宋体">用于函数定义时，对函数的连接方式产生影响，使得函数只在本文件内部有效，对其他文件是不可见的。这样的函数又叫作静态函数。使用静态函数的好处是，不用担心与其他文件的同名函数产生干扰，另外也是对函数本身的一种保护机制。</span></p>
<p><span style="FONT-FAMILY: 宋体">如果想要其他文件可以引用本地函数，则要在函数定义时使用关键字</span><span lang=EN-US>extern</span><span style="FONT-FAMILY: 宋体">，表示该函数是外部函数，可供其他文件调用。另外在要引用别的文件中定义的外部函数的文件中，使用</span><span lang=EN-US>extern</span><span style="FONT-FAMILY: 宋体">声明要用的外部函数即可。</span><br></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">参考资料：</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">①《</span><span lang=EN-US> C</span><span style="FONT-FAMILY: 宋体">程序设计（第二版）</span> <span style="FONT-FAMILY: 宋体">》，谭浩强</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">②《</span><span lang=EN-US> Pointers on C </span><span style="FONT-FAMILY: 宋体">》，</span><span lang=EN-US>Kenneth A.Reek</span></p>
<p><strong><font color=#02368d size=5>void和void指针</font></strong></p>
<p><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">void的含义</span><br>&nbsp;&nbsp;&nbsp; void即&#8220;无类型&#8221;，void *则为&#8220;无类型指针&#8221;，可以指向任何数据类型。<br><br><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">void指针使用规范</span><br>&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)">①void指针可以指向任意类型的数据，亦即可用任意数据类型的指针对void指针赋值。例如：<br>&nbsp;&nbsp;&nbsp; int *pint;<br>&nbsp;&nbsp;&nbsp; void *pvoid;<br>&nbsp;&nbsp;&nbsp; pvoid = pint;&nbsp;&nbsp; /* 不过不能 pint = pvoid; */<br>&nbsp;&nbsp;&nbsp; 如果要将pvoid赋给其他类型指针，则需要强制类型转换如：pint = (int *)pvoid;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; ②在ANSI C标准中，不允许对void指针进行算术运算如pvoid++或pvoid+=1等，而在GNU中则允许，因为在缺省情况下，GNU认为void *与char *一样。sizeof( *pvoid )== sizeof( char ).<br>&nbsp;&nbsp; </span></span><br><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">void的作用<br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)">①对函数返回的限定。<br>&nbsp;&nbsp;&nbsp; ②对函数参数的限定。<br>&nbsp;&nbsp;&nbsp; 当函数不需要返回值时，必须使用void限定。例如： void func(int, int);<br>&nbsp;&nbsp;&nbsp; 当函数不允许接受参数时，必须使用void限定。例如： int func(void)。<br><br>&nbsp;&nbsp;&nbsp; 由于void指针可以指向任意类型的数据，亦即可用任意数据类型的指针对void指针赋值，因此还可以用void指针来作为函数形参，这样函数就可以接受任意数据类型的指针作为参数。例如：<br>&nbsp;&nbsp;&nbsp; void * memcpy( void *dest, const void *src, size_t len );<br>&nbsp;&nbsp;&nbsp; void * memset( void * buffer, int c, size_t num );<br></span></span><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)"></span></p>
<hr style="WIDTH: 100%; HEIGHT: 2px">
<p>&nbsp; &nbsp; <br>参考资料：《 C/C++语言void及void指针深层探索 》，宋宝华<br><strong><font color=#02368d size=5><br></font></strong><strong><font color=#02368d size=5>函数指针</font></strong></p>
<p><strong><font color=#0001ff>函数指针是什么？<br></font></strong>&nbsp;&nbsp;&nbsp; 先来看函数调用是怎么回事。一个函数占用一段连续内存。当调用一个函数时，实际上是跳转到函数入口地址，执行函数体的代码，完成后返回。如何找到对应的入口地址？这是由函数名来标记的，实际上，函数名就是函数的入口地址。<br>&nbsp;&nbsp;&nbsp; 函数指针是一种特殊类型的指针，它指向一个函数的入口地址。<br><br>&nbsp;&nbsp;&nbsp; <span style="COLOR: rgb(153,1,2)"><span style="FONT-WEIGHT: bold">注意：</span><span style="COLOR: rgb(0,1,2)">除了void类型指针是无类型的指针外，其他所有指针都是有对应类型的，例如int *pint、struct studentdata *psdata等，只有指明了指针所指的数据类型，编译器才能为指针分配或预计分配相应大小的存储空间，指针的算术运算如pint++等才是有意义的。因此，定义了某种类型的指针之后，除非使用强制类型转换，那么它只能指向相应数据类型的变量或常量，不同类型的指针或数据之间不可混用。所以指针的类型实际上是一种身份标志的作用。<br><br>&nbsp;&nbsp; 函数指针如何表明自己的身份呢？为了避免混乱，必须也要作出相应规定，不同函数的函数指针不能混用。例如，int func1(int arg11, char arg12)与int func2(char arg)的函数指针就不能混用，要定义可以指向func1的函数指针应该这样：<br>&nbsp;&nbsp;&nbsp; int (*pfunc1)(int, char) = func1；<br>定义可以指向func2的函数指针则该如下：<br>&nbsp;&nbsp;&nbsp; int (*pfunc2)(char) = func2;<br>&nbsp;&nbsp;&nbsp; <span style="FONT-WEIGHT: bold">从函数指针的定义可以看出，函数指针的类型实际上是由</span><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,102)">函数签名</span><span style="FONT-WEIGHT: bold">决定的。</span>函数签名就象是函数的身份证，一个函数的函数签名是独一无二的，具有相同函数签名的函数实际上就是同一函数。<span style="TEXT-DECORATION: underline">函数签名包括函数名、函数形参类型的有序列表和函数返回值类型。</span><br><br>&nbsp;&nbsp;&nbsp; 一个函数指针的定义规定了它只能指向特定类型的函数。如果两个函数的形参列表和返回值类型相同，只有函数名和函数体不同，则可以使用相同类型的函数指针。例如，如果还有一个函数int func3(char arg)，则上面定义的可以指向函数func2的函数指针也可以用于指向func3，即：<br>&nbsp;&nbsp;&nbsp; pfunc2 = func3;<br>&nbsp;&nbsp;&nbsp; 再使用pfunc2(char ARG)就可以调用函数func3，这时指令计数器（PC）指向函数入口，从此开始执行函数体代码。<br>&nbsp;&nbsp;&nbsp; 注意：对函数指针进行算术运算也是没有意义的。<br><br style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)"><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">如何使用函数指针？</span><br>&nbsp;&nbsp;&nbsp; ①定义合适类型的函数指针变量；<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; int (*pfunc)(int, int);<br>&nbsp;&nbsp;&nbsp; ②给函数指针变量赋值，使它指向某个函数入口；<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; int example(int, int);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; pfunc = example;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; /*将函数入口地址赋给函数指针变量*/<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 或者：pfunc = &amp;example;&nbsp;&nbsp;&nbsp; /*函数名总是被编译器转换为函数指针（入口地址）来使用，因此与上面一句等价 */<br>&nbsp;&nbsp;&nbsp; ③使用函数指针来调用相应的函数；<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; retval = pfunc(10, 16);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 或者：retval = (*pfunc)(10, 16);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 上面两句都与retval = example(10, 16);等价。<br>&nbsp;&nbsp;&nbsp; 理解：一个指针变量p实际上也和普通的变量一样，要占存储空间（通常与平台的虚拟地址一样宽），也有其自身的存储地址&amp;p；不同的是，在指针变量p的值有特殊的意义，它是另外一个变量或常量的地址值，也就是说，在地址为&amp;p的存储单元上存放着另外一个数据的地址。因此，*p实际上是将p看作它指向的数据的地址来使用，*操作符是引用相应地址中的数据，也就是对地址为p的存储单元中存放的数据进行操作。<br>&nbsp;&nbsp;&nbsp; 一个函数指针变量则更为特殊。比如上面的例子，pfunc变量本身的值是函数example()的入口地址。因此pfunc可以代替其所指函数的函数名来使用。至于*pfunc，如果按照上面的理解，它实际上是地址pfunc的内容，也即函数example()的入口地址的内容，就有点含糊了。不过，从另一方面来理解，如果使用pfunc = &amp;example来初始化pfunc，则*pfunc == *(&amp;example) == example，又与pfunc等价。因此，就有了两种使用函数指针来调用相应函数的形式。<br>&nbsp;&nbsp;&nbsp; 值得注意的是，不可用*pfunc来对pfunc的值初始化。即*pfunc = example的写法是错误的。<br><br><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">为什么要使用函数指针？<br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)">前面介绍了函数指针的基本知识和使用规范。下面介绍函数指针的实际用途。不过首先要对前面的知识再做一个补充，因为下面的应用很可能用到这一特性。前面指出，除函数名之外的函数签名内容（函数返回值类型和形参列表）决定了函数指针的类型。实际上还有一种特殊的或说通用的函数指针，在定义这类函数指针时，只需要指定函数返回值类型，而留空形参列表，这样就可以指向返回值类型相同的所有函数。例如：<br>&nbsp;&nbsp;&nbsp; int (*pfunc)();<br>&nbsp;&nbsp;&nbsp; 这样定义的pfunc就可以指向前面提到的func1和func2，因为他们都返回整型值。<br>&nbsp;&nbsp;&nbsp; <span style="FONT-WEIGHT: bold; COLOR: rgb(102,1,2)">注意：</span> int (*pfunc)()与int (*pfunc)(void)不是一回事，后者不允许接受任何参数。<br><br></span></span>&nbsp;&nbsp;&nbsp; <span style="FONT-WEIGHT: bold">函数指针最常见的三个用途是：</span><br>&nbsp;&nbsp;&nbsp; ①作为参数传递给其他函数。<br>&nbsp;&nbsp;&nbsp; 这样可以把多个函数用一个函数体封装起来，得到一个具有多个函数功能的新函数，根据传递的函数指针变量值的不同，执行不同的函数功能。这是函数嵌套调用难以实现的。参数的传递可以由程序员设定，也可以由用户输入读取，因此具有较大的灵活性和交互性。<br>&nbsp;&nbsp;&nbsp; 另外还可以用于回调函数。使用void配合，还可以将对不同数据类型的数据进行相同处理的多个函数封装为一个函数，增强函数的生命力。<br><br>&nbsp;&nbsp;&nbsp; ②用于散转程序。<br>&nbsp;&nbsp;&nbsp; 这种程序首先建立一个函数表（实际上是一个函数指针数组），表中存放了各个函数的入口地址（或函数名），根据条件的设定来查表选择执行相应的函数。这样也可以将多个函数封装为一个函数或者程序，散转分支条件可以由程序员设定，也可以由用户输入读取，甚至是外设的某种特定状态（这种状态可以是不受人为控制的）。<br><br>&nbsp;&nbsp;&nbsp; ③实现C的面向对象的类的封装。<br>&nbsp;&nbsp;&nbsp; C语言中的struct与C++中的class有很大不同，除了缺省的成员属性外（struct的成员缺省为public的，可随意使用，而class成员缺省为private的），struct还很难实现类成员函数的封装。struct的成员一般都是数据成员，而非函数成员。因此，为了在C语言中，为某个struct定义一套自己的函数对结构数据成员进行操作，可以在struct结构体中增加函数指针变量成员，在初始化时使它指向特定函数即可。<br><br>&nbsp;&nbsp;&nbsp; 应用举例：<br>&nbsp;&nbsp;&nbsp; ①假设定义了四个函数：add(int, int)、sub(int, int)、mul(int, int)、div(int, int)，可以将其封装为一个四则运算计算器函数:<br>&nbsp;&nbsp;&nbsp; double calculator(int x, int y, int (*pfunc)(int, int)) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; double result;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; result = pfunc(x, y);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; return result;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; 又例如，在一个链表查询程序中，要通过比较节点的特征值来查询节点，不同类型的数据的比较方式不一样，整型等可以直接比较，字符串却要用专门的字符串操作函数，为了使代码可重用性更高，可以使用一个比较函数来代替各种不同数据类型的直接比较代码，同时，比较函数也必然是数据类型相关的，因此要使用void指针和函数指针来转换为类型无关的比较函数，根据相应的数据类型，调用相应的函数（传递相应的函数指针）。一个实例是：<br>&nbsp;&nbsp;&nbsp; int (*compare)(void const *, void const *);<br>&nbsp;&nbsp;&nbsp; 这个函数指针可以接受任意类型的数据的指针参数，同时返回int值作为比较结果标志。一个比较整型数据的比较函数是：<br>&nbsp;&nbsp;&nbsp; int compare_ints(void const *a, void const *b) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; if( *(int *)a == *(int *)b ) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; return 1;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; ②散转程序。通过一个转移表（函数指针数组）来实现。还是上面定义的四个四则运算函数，可以建立这样一个转移表（注意初始化该转移表的语句前面应有add等相应函数原型声明或定义）：<br>&nbsp;&nbsp;&nbsp; double (*calculator[])(int, int) = {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; add, sub, mul, div<br>&nbsp;&nbsp;&nbsp; };<br>&nbsp;&nbsp;&nbsp; 这样，calculator[0] == add, calculator[1] == sub, ...<br>&nbsp;&nbsp;&nbsp; 使用result = calculator[oper](x, y);就可以代替下面整个switch语句：<br>&nbsp;&nbsp;&nbsp; switch( oper ) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; case 0: result = add(x, y); break;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; case 1: result = sub(x, y); break;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; ③C的面向对象化。一个对象包括数据和对数据的操作。C语言中的struct只有数据成员，因此要增加一些&#8220;伪数据成员&#8221;即函数指针来实现对数据的操作。例如：<br>&nbsp;&nbsp;&nbsp; #ifndef C_Class<br>&nbsp;&nbsp;&nbsp; #define </span></span><span style="COLOR: rgb(153,1,2)"><span style="COLOR: rgb(0,1,2)">C_Class struct<br>&nbsp;&nbsp;&nbsp; #endif<br>&nbsp;&nbsp;&nbsp; </span></span><span style="COLOR: rgb(153,1,2)"><span style="COLOR: rgb(0,1,2)">C_Class student{<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; C_Class student *student_this<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; char name;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; int height;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; int gender;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; int classnum;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; void (*Oper)( C_Class student *student_this );<br>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; ...<br>&nbsp;&nbsp;&nbsp; }<br></span></span></p>
<hr style="WIDTH: 100%; HEIGHT: 2px">
<p>参考资料：<br>①《 Pointers on C 》，Kenneth A.Reek<br>②《 C程序设计（第二版）》，谭浩强<br>③《 C语言嵌入式系统编程修炼之道 》<br></p>
<p><strong><font color=#02368d size=5>errno与错误处理</font></strong><br><br><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)">errno是什么?<br></span><span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)">在/usr/include/errno.h中,include了&lt;sys/errno.h&gt;,在该文件中定义了不同的errno的值(错误类型编号)所对应的宏以及错误类型.<br></span></span><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)"><br>基本使用:<br><span style="FONT-WEIGHT: bold"><span style="COLOR: rgb(0,1,2)"></span></span></span><span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)"></span></span><span style="FONT-WEIGHT: bold; COLOR: rgb(0,1,255)"><span style="FONT-WEIGHT: bold"><span style="COLOR: rgb(0,1,2)"></span></span></span><span style="COLOR: rgb(0,1,255)"><span style="COLOR: rgb(0,1,2)">#include &lt;errno.h&gt;<br>extern int errno;<br><br>1.使用perror( const char *msg )函数来将错误类型所对应的错误信息以字符串形式打印到终端.<br>&nbsp; 首先输出用户自定义的字符串msg(可以为空,即""),然后打印错误信息.<br><br>2.使用stderr( int errnum )将错误信息转换为字符串.<br><br>3.注意,必须在函数表明操作失败后立刻对errno的值进行检查以找出对应错误.在使用它之前必须总是先将其值copy到另外一个变量保存起来,因为很多函数(象fprintf之类)自身就可能会改变errno的值.<br>&nbsp; func( );<br>&nbsp; errortype = errno;<br>&nbsp; printf( "%d\n", errortype );<br>或者：<br>&nbsp; if( errortype == ... ) {<br>&nbsp; &nbsp;&nbsp; do ...<br>&nbsp; }<br>&nbsp; else {<br>&nbsp; &nbsp;&nbsp; do ....<br>&nbsp; }<br></span></span></p>
<p><br>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/40309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2008-02-29 20:49 <a href="http://www.cnitblog.com/zouzheng/articles/40309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 声明与函数、函数指针</title><link>http://www.cnitblog.com/zouzheng/articles/21921.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Tue, 16 Jan 2007 07:18:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/21921.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/21921.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/21921.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/21921.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/21921.html</trackback:ping><description><![CDATA[
		<p>
				<strong>
						<span lang="ZH-CN" style="FONT-WEIGHT: normal; FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">概述 </span>
				</strong>
				<strong>
						<span style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">
								<br />
								<br />
								<span lang="ZH-CN">　　</span>
						</span>
				</strong>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">在很多情况下，尤其是读别人所写代码的时候，对</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">C<span lang="ZH-CN">语言声明的理解能力变得非常重要，而</span>C<span lang="ZH-CN">语言本身的凝练简约也使得</span>C<span lang="ZH-CN">语言的声明常常会令人感到非常困惑，因此，在这里我用一篇的内容来集中阐述一下这个问题。</span></span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">
						<br />
						<br />
						<span lang="ZH-CN">　　<strong>问题：声明与函数 </strong></span>
						<strong>
								<br />
								<br />
						</strong>
						<span lang="ZH-CN">　　有一段程序存储在起始地址为</span>
						<span>0<span lang="ZH-CN">的一段内存上，如果我们想要调用这段程序，请问该如何去做？ </span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　答案</span>
						<br />
						<br />
						<span lang="ZH-CN">　　答案是</span>
						<span>(*(void (*)( ) )0)( )<span lang="ZH-CN">。看起来确实令人头大，那好，让我们知难而上，从两个不同的途径来详细分析这个问题。 </span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　答案分析：从尾到头</span>
						<br />
						<br />
						<span lang="ZH-CN">　　首先，最基本的函数声明：</span>
						<span>void function (paramList);</span>
						<br />
						<br />
						<span lang="ZH-CN">　　最基本的函数调用：</span>
						<span>function(paramList);</span>
						<br />
						<br />
						<span lang="ZH-CN">　　鉴于问题中的函数没有参数，函数调用可简化为</span>
						<span>function();</span>
						<br />
						<br />
						<strong>
								<span lang="ZH-CN">　　</span>
						</strong>
						<span lang="ZH-CN">其次，根据问题描述，可以知道</span>
						<span>0<span lang="ZH-CN">是这个函数的入口地址，也就是说，</span>0<span lang="ZH-CN">是一个函数的指针。使用函数指针的函数声明形式是：</span>void (*pFunction)()<span lang="ZH-CN">，相应的调用形式是：</span> (*pFunction)()<span lang="ZH-CN">，则问题中的函数调用可以写作：</span>(*0)( )<span lang="ZH-CN">。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　第三，大家知道，函数指针变量不能是一个常数，因此上式中的</span>
						<span>0<span lang="ZH-CN">必须要被转化为函数指针。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　我们先来研究一下，对于使用函数指针的函数：比如</span>
						<span>void (*pFunction)( )<span lang="ZH-CN">，函数指针变量的原型是什么？这个问题很简单，</span>pFunction<span lang="ZH-CN">函数指针原型是</span>( void (*)( ) )<span lang="ZH-CN">，即去掉变量名，清晰起见，整个加上（）号。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　所以将</span>
						<span>0<span lang="ZH-CN">强制转换为一个返回值为</span>void<span lang="ZH-CN">，参数为空的函数指针如下：</span>( void (*)( ) )<span lang="ZH-CN">。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　</span>
						<span>OK<span lang="ZH-CN">，结合</span>2)<span lang="ZH-CN">和</span>3)<span lang="ZH-CN">的分析，结果出来了，那就是：</span>(*(void (*)( ) )0)( ) <span lang="ZH-CN">。 </span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　答案分析：从头到尾理解答案 </span>
						<br />
						<br />
						<span lang="ZH-CN">　　</span>
						<span>(void (*)( )) <span lang="ZH-CN">，是一个返回值为</span>void<span lang="ZH-CN">，参数为空的函数指针原型。</span></span>
						<br />
						<span lang="ZH-CN">　　</span>
						<span>(void (*)( ))0<span lang="ZH-CN">，把</span>0<span lang="ZH-CN">转变成一个返回值为</span>void<span lang="ZH-CN">，参数为空的函数指针，指针指向的地址为</span>0.</span>
						<br />
						<span lang="ZH-CN">　　</span>
						<span>*(void (*)( ))0<span lang="ZH-CN">，前面加上</span>*<span lang="ZH-CN">表示整个是一个返回值为</span>void<span lang="ZH-CN">的函数的名字</span></span>
						<br />
						<span lang="ZH-CN">　　</span>
						<span>(*(void (*)( ))0)( )<span lang="ZH-CN">，这当然就是一个函数了。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　我们可以使用</span>
						<span>typedef<span lang="ZH-CN">清晰声明如下：</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　</span>
						<span>typedef void (*pFun)( );</span>
						<br />
						<br />
						<span lang="ZH-CN">　　这样函数变为</span>
						<span>(*(pFun)0 )( );</span>
						<br />
						<br />
						<strong>
								<span lang="ZH-CN">　　问题：三个声明的分析 </span>
						</strong>
						<strong>
								<br />
						</strong>
						<br />
						<span lang="ZH-CN">　　对声明进行分析，最根本的方法还是类比替换法，从那些最基本的声明上进行类比，简化，从而进行理解，下面通过分析三个例子，来具体阐述如何使用这种方法。</span>
						<br />
						<br />
						<span lang="ZH-CN">＃</span>
						<span>1<span lang="ZH-CN">：</span>int* (*a[5])(int, char*);</span>
						<br />
						<br />
						<strong>
								<span lang="ZH-CN">　　</span>
						</strong>
						<span lang="ZH-CN">首先看到标识符名</span>
						<span>a<span lang="ZH-CN">，</span>"[]"<span lang="ZH-CN">优先级大于</span>"*"<span lang="ZH-CN">，</span>a<span lang="ZH-CN">与</span>"[5]"<span lang="ZH-CN">先结合。所以</span>a<span lang="ZH-CN">是一个数组，这个数组有</span>5<span lang="ZH-CN">个元素，每一个元素都是一个指针，指针指向</span>"(int, char*)"<span lang="ZH-CN">，很明显，指向的是一个函数，这个函数参数是</span>"int, char*"<span lang="ZH-CN">，返回值是</span>"int*"<span lang="ZH-CN">。</span>OK<span lang="ZH-CN">，结束了一个。：）</span></span>
						<br />
						<br />
						<span lang="ZH-CN">＃</span>
						<span>2<span lang="ZH-CN">：</span>void (*b[10]) (void (*)());</span>
						<br />
						<br />
						<span lang="ZH-CN">　　</span>
						<span>b<span lang="ZH-CN">是一个数组，这个数组有</span>10<span lang="ZH-CN">个元素，每一个元素都是一个指针，指针指向一个函数，函数参数是</span>"void (*)()"<span lang="ZH-CN">【注</span>10<span lang="ZH-CN">】，返回值是</span>"void"<span lang="ZH-CN">。完毕！</span></span>
						<br />
						<br />
						<span lang="ZH-CN">　　注意：这个参数又是一个指针，指向一个函数，函数参数为空，返回值是</span>
						<span>"void"<span lang="ZH-CN">。</span></span>
						<br />
						<br />
						<span lang="ZH-CN">＃</span>
						<span>3. doube(*)() (*pa)[9];</span>
						<br />
						<br />
						<span lang="ZH-CN">　　</span>
						<span>pa<span lang="ZH-CN">是一个指针，指针指向一个数组，这个数组有</span>9<span lang="ZH-CN">个元素，每一个元素都是</span>"doube(*)()"<span lang="ZH-CN">（也即一个函数指针，指向一个函数，这个函数的参数为空，返回值是</span>"double"<span lang="ZH-CN">）。</span><?xml:namespace prefix = o /?><o:p></o:p></span>
				</span>
		</p>
		<p>
				<strong>
						<span style="FONT-FAMILY: PMingLiU">
								<a href="http://dugujian.blogchina.com/422469.html">
										<span style="COLOR: windowtext; TEXT-DECORATION: none">C<span lang="ZH-CN">语言中的函数指针</span></span>
								</a>
								<o:p>
								</o:p>
						</span>
				</strong>
		</p>
		<p>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">函数在内存中有一个物理位置，而这个位置是可以赋给一个指针的。一零点函数的地址就是该函数的入口点。因此，函数指针可被用来调用一个函数。函数的地址是用不带任何括号或参数的函数名来得到的。（这很类似于数组地址的得到方法，即，在只有数组名而无下标是就得到数组地址。）</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">
						<o:p>
						</o:p>
				</span>
		</p>
		<p>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">怎样说明一个函数指针变量呢</span>
				<span style="FONT-SIZE: 10pt; FONT-FAMILY: PMingLiU">? <br /><span lang="ZH-CN">为了说明一个变量</span> fn_pointer <span lang="ZH-CN">的类型是</span>"<span lang="ZH-CN">返回值为</span> int <span lang="ZH-CN">的函数指针</span>", <span lang="ZH-CN">你可以使用下面的说明语句</span>:<br /><span style="COLOR: navy; FONT-FAMILY: PMingLiU"><font color="#000000">int (*fn_pointer) ();</font></span><br /><span lang="ZH-CN">为了让编译器能正确地解释这句语句</span>, *fn_pointer <span lang="ZH-CN">必须用括号围起来。若漏了这对括号</span>, <span lang="ZH-CN">则</span>:<br />int *fn_pointer ();<br /><span lang="ZH-CN">的意思完全不同了。</span>fn_pointer <span lang="ZH-CN">将是一个函数名</span>, <span lang="ZH-CN">其返回值为</span> int <span lang="ZH-CN">类型的指针。</span><o:p></o:p></span>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<strong>
						<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数指针变量</span>
				</strong>
				<strong>
						<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  </span>
				</strong>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">
						<br />
						<br />
				</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　在Ｃ语言中规定，一个函数总是占用一段连续的内存区，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">而函数名就是该函数所占内存区的首地址。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">我们可以把函数的这个首地址</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">或称入口地址</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">赋予一个指针变量，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">使该指针变量指向该函数。然后通过指针变量就可以找到并调用这个函数。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">我们把这种指向函数的指针变量称为</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数指针变量</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数指针变量定义的一般形式为：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">类型说明符</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> (*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针变量名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)();   <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">其中</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">类型说明符</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示被指函数的返回值的类型。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"(* </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针变量名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"*"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">后面的变量是定义的指针变量。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">最后的空括号表示指针变量所指的是一个函数。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">例如：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> int (*pf)();  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">pf</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个指向函数入口的指针变量，该函数的返回值</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数值</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是整型。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">下面通过例子来说明用指针形式实现对函数调用的方法。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br />int max(int a,int b){  <br />if(a&gt;b)return a;  <br />else return b;  <br />}  <br />main(){  <br />int max(int a,int b);  <br />int(*pmax)();  <br />int x,y,z;  <br />pmax=max;  <br />printf("input two numbers:\n");  <br />scanf("%d%d",&amp;x,&amp;y);  <br />z=(*pmax)(x,y);  <br />printf("maxmum=%d",z);  <br />}  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　从上述程序可以看出用，函数指针变量形式调用函数的步骤如下：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">
						<o:p>
						</o:p>
				</span>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">1. </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">先定义函数指针变量，如后一程序中第</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">9</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> int (*pmax)();</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">定义</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">pmax</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">为函数指针变量。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /><br />2. </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">把被调函数的入口地址</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">赋予该函数指针变量，如程序中第</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">11</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> pmax=max;  <br /><br />3. </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">用函数指针变量形式调用函数，如程序第</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">14</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> z=(*pmax)(x,y);</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　调用函数的一般形式为：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> (*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针变量名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">) (</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">实参表</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">使用函数指针变量还应注意以下两点：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /><br />a. </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数指针变量不能进行算术运算，这是与数组指针变量不同的。数组指针变量加减一个整数可使指针移动指向后面或前面的数组元素，而函数指针的移动是毫无意义的。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /><br />b. </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数调用中</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"(*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针变量名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">的两边的括号不可少，其中的</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">不应该理解为求值运算，在此处它只是一种表示符号。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /><br /></span>
				<strong>
						<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针型函数</span>
				</strong>
				<strong>
						<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  </span>
				</strong>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">
						<br />
						<br />
				</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">前面我们介绍过，所谓函数类型是指函数返回值的类型。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">在Ｃ语言中允许一个函数的返回值是一个指针</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">即地址</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">这种返回指针值的函数称为指针型函数。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">定义指针型函数的一般形式为：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">   <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">类型说明符</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> *</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">形参表</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">)   <br />{   <br />...... /*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数体</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*/  <br />}   <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">其中函数名之前加了</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"*"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">号表明这是一个指针型函数，即返回值是一个指针。类型说明符表示了返回的指针值所指向的数据类型。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">如：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br />int *ap(int x,int y)  <br />{  <br />...... /*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数体</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*/  <br />}  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">ap</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个返回指针值的指针型函数，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">它返回的指针指向一个整型变量。下例中定义了一个指针型函数</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> day_name</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">，它的返回值指向一个字符串。该函数中定义了一个静态指针数组</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">name</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">name </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">数组初始化赋值为八个字符串，分别表示各个星期名及出错提示。形参</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">n</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示与星期名所对应的整数。在主函数中，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">把输入的整数</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">作为实参，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">在</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">printf</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">语句中调用</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">day_name</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数并把</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">值传送给形参</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> n</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">day_name</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">函数中的</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">return</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">语句包含一个条件表达式，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> n </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">值若大于</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">7</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">或小于</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">1</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">则把</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">name[0] </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针返回主函数输出出错提示字符串</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">"Illegal day"</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">。否则返回主函数输出对应的星期名。主函数中的第</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">7</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行是个条件语句，其语义是，如输入为负数</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(i&lt;0)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">则中止程序运行退出程序。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">exit</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个库函数，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">exit(1)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示发生错误后退出程序，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> exit(0)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示正常退出。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /><br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　应该特别注意的是函数指针变量和指针型函数这两者在写法和意义上的区别。如</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">int(*p)()</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">和</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">int *p()</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是两个完全不同的量。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">int(*p)()</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个变量说明，说明</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">p </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个指向函数入口的指针变量，该函数的返回值是整型量，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">(*p)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">的两边的括号不能少。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">int *p() </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">则不是变量说明而是函数说明，说明</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">p</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个指针型函数，其返回值是一个指向整型量的指针，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*p</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">两边没有括号。作为函数说明，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">在括号内最好写入形式参数，这样便于与变量说明区别。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">对于指针型函数定义，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">int *p()</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">只是函数头部分，一般还应该有函数体部分。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br />main(){  <br />int i;  <br />char *day_name(int n);   <br />printf("input Day No:\n");  <br />scanf("%d",&amp;i);  <br />if(i&lt;0) exit(1);  <br />printf("Day No:%2d--&gt;%s\n",i,day_name(i));  <br />}  <br />char *day_n<o:p></o:p></span>
		</p>
		<p style="LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">ame(int n){  <br />static char *name[]={ "Illegal day",  <br />"Monday",  <br />"Tuesday",  <br />"Wednesday",  <br />"Thursday",  <br />"Friday",  <br />"Saturday",  <br />"Sunday"};  <br />return((n&lt;1||n&gt;7) ? name[0] : name[n]);  <br />}  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　本程序是通过指针函数，输入一个</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">1</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">～</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">7</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">之间的整数，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">输出对应的星期名。指针数组的说明与使用一个数组的元素值为指针则是指针数组。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针数组是一组有序的指针的集合。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　指针数组说明的一般形式为：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">类型说明符</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">数组名</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">[</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">数组长度</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">]   <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　其中类型说明符为指针值所指向的变量的类型。例如：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> int *pa[3] </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">pa</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个指针数组，它有三个数组元素，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">每个元素值都是一个指针，指向整型变量。通常可用一个指针数组来指向一个二维数组。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">指针数组中的每个元素被赋予二维数组每一行的首地址，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">因此也可理解为指向一个一维数组。图</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">6—6</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示了这种关系。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">  <br />int a[3][3]={1,2,3,4,5,6,7,8,9};  <br />int *pa[3]={a[0],a[1],a[2]};  <br />int *p=a[0];  <br />main(){  <br />int i;  <br />for(i=0;i&lt;3;i++)  <br />printf("%d,%d,%d\n",a[i][2-i],*a[i],*(*(a+i)+i));  <br />for(i=0;i&lt;3;i++)  <br />printf("%d,%d,%d\n",*pa[i],p[i],*(p+i));  <br />}  <br /></span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">　　本例程序中，</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">pa</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">是一个指针数组，三个元素分别指向二维数组</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">a</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">的各行。然后用循环语句输出指定的数组元素。其中</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*a[i]</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">0</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">列元素值；</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*(*(a+i)+i)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">列的元素值；</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*pa[i]</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">0</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">列元素值；由于</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">p</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">与</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">a[0]</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">相同，故</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">p[i]</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">0</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">列的值；</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">*(p+i)</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">表示</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">0</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">行</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana">i</span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">列的值。读者可仔细领会元素值的各种不同的表示方法。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">应该注意指针数组和二维数组指针变量的区别。</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: Verdana"> </span>
				<span lang="ZH-CN" style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%; FONT-FAMILY: PMingLiU">这两者虽然都可用来表示二维数组，但是其表示方法和意义是不同的</span>
		</p>
<img src ="http://www.cnitblog.com/zouzheng/aggbug/21921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2007-01-16 15:18 <a href="http://www.cnitblog.com/zouzheng/articles/21921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>可变参数学习笔记</title><link>http://www.cnitblog.com/zouzheng/articles/21888.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Mon, 15 Jan 2007 13:54:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/21888.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/21888.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/21888.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/21888.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/21888.html</trackback:ping><description><![CDATA[[转帖]可变参数学习笔记<br />前言：本文在很大程度上改编自网友kevintz的"C语言中可变参数的用法"一文，在行文之前先向这位前辈表示真诚的敬意和感谢。<br />一、什么是可变参数<br />我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: <br />int printf( const char* format, ...); <br />它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的（用三个点"…"做参数占位符）,实际调用时可以有以下的形式: <br />    printf("%d",i); <br />    printf("%s",s); <br />    printf("the number is %d ,string is:%s", i, s);    <br />以上这些东西已为大家所熟悉。但是究竟如何写可变参数的C函数以及这些可变参数的函数编译器是如何实现，这个问题却一直困扰了我好久。本文就这个问题进行一些探讨,希望能对大家有些帮助.<br /><br />二、写一个简单的可变参数的C函数 <br />先看例子程序。该函数至少有一个整数参数,其后占位符…，表示后面参数的个数不定. 在这个例子里，所有的输入参数必须都是整数，函数的功能只是打印所有参数的值.<br />函数代码如下：<br />//示例代码1：可变参数函数的使用<br />#include "stdio.h"<br />#include "stdarg.h"<br />void simple_va_fun(int start, ...) <br />{ <br />    va_list arg_ptr; <br />    int nArgValue =start;<br />    int nArgCout=0;     //可变参数的数目<br />    va_start(arg_ptr,start); //以固定参数的地址为起点确定变参的内存起始地址。<br />    do {<br />       ++nArgCout;<br />        printf("the %d th arg: %d\n",nArgCout,nArgValue);     //输出各参数的值<br />        nArgValue = va_arg(arg_ptr,int);                    //得到下一个可变参数的值<br />    } while(nArgValue != -1);                <br />    return; <br />}<br />int main(int argc, char* argv[])<br />{<br />    simple_va_fun(100,-1); <br />    simple_va_fun(100,200,-1); <br />    return 0;<br />}<br /><br />下面解释一下这些代码<br /><br />从这个函数的实现可以看到,我们使用可变参数应该有以下步骤: <br /><br />⑴由于在程序中将用到以下这些宏: <br />    void va_start( va_list arg_ptr, prev_param ); <br />    type va_arg( va_list arg_ptr, type ); <br />    void va_end( va_list arg_ptr ); <br />va在这里是variable-argument(可变参数)的意思. <br />这些宏定义在stdarg.h中,所以用到可变参数的程序应该包含这个头文件.<br /><br />⑵函数里首先定义一个va_list型的变量,这里是arg_ptr,这个变量是存储参数地址的指针.因为得到参数的地址之后，再结合参数的类型，才能得到参数的值。<br /><br />⑶然后用va_start宏初始化⑵中定义的变量arg_ptr,这个宏的第二个参数是可变参数列表的前一个参数,即最后一个固定参数. <br /><br />⑷然后依次用va_arg宏使arg_ptr返回可变参数的地址,得到这个地址之后，结合参数的类型，就可以得到参数的值。<br /><br />⑸设定结束条件，这里的条件就是判断参数值是否为-1。注意被调的函数在调用时是不知道可变参数的正确数目的，程序员必须自己在代码中指明结束条件。至于为什么它不会知道参数的数目，读者在看完这几个宏的内部实现机制后，自然就会明白。<br /><br />(二)可变参数在编译器中的处理 <br />我们知道va_start,va_arg,va_end是在stdarg.h中被定义成宏的, 由于1)硬件平台的不同 2)编译器的不同,所以定义的宏也有所不同,下面看一下VC++6.0中stdarg.h里的代码（文件的路径为VC安装目录下的\vc98\include\stdarg.h）<br />    typedef char *  va_list;<br />    #define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) &amp; ~(sizeof(int) - 1) )<br />    #define va_start(ap,v)  ( ap = (va_list)&amp;v + _INTSIZEOF(v) )<br />    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )<br />    #define va_end(ap)      ( ap = (va_list)0 )<br /><br />下面我们解释这些代码的含义：<br /><br />1、首先把va_list被定义成char*，这是因为在我们目前所用的PC机上，字符指针类型可以用来存储内存单元地址。而在有的机器上va_list是被定义成void*的<br /><br />2、定义_INTSIZEOF(n)主要是为了某些需要内存的对齐的系统.这个宏的目的是为了得到最后一个固定参数的实际内存大小。在我的机器上直接用sizeof运算符来代替，对程序的运行结构也没有影响。（后文将看到我自己的实现）。<br /><br />3、va_start的定义为 &amp;v+_INTSIZEOF(v) ,这里&amp;v是最后一个固定参数的起始地址，再加上其实际占用大小后，就得到了第一个可变参数的起始内存地址。所以我们运行va_start(ap, v)以后,ap指向第一个可变参数在的内存地址,有了这个地址，以后的事情就简单了。 <br /><br />这里要知道两个事情：<br />    ⑴在intel+windows的机器上，函数栈的方向是向下的，栈顶指针的内存地址低于栈底指针，所以先进栈的数据是存放在内存的高地址处。<br />    (2)在VC等绝大多数C编译器中，默认情况下，参数进栈的顺序是由右向左的，因此，参数进栈以后的内存模型如下图所示：最后一个固定参数的地址位于第一个可变参数之下，并且是连续存储的。<br />|--------------------------|<br />|  最后一个可变参数             |   -&gt;高内存地址处<br />|--------------------------|<br />|--------------------------|<br />|  第N个可变参数              |     -&gt;va_arg(arg_ptr,int)后arg_ptr所指的地方,<br />|                               |     即第N个可变参数的地址。<br />|--------------- |     <br />|--------------------------|<br />|  第一个可变参数               |     -&gt;va_start(arg_ptr,start)后arg_ptr所指的地方<br />|                               |     即第一个可变参数的地址<br />|--------------- |     <br />|------------------------ --|<br />|                               |<br />|  最后一个固定参数             |    -&gt; start的起始地址<br />|-------------- -|       .................<br />|-------------------------- |<br />|                               |  <br />|--------------- |  -&gt; 低内存地址处<br /><br />(4) va_arg():有了va_start的良好基础，我们取得了第一个可变参数的地址，在va_arg()里的任务就是根据指定的参数类型取得本参数的值，并且把指针调到下一个参数的起始地址。<br />因此，现在再来看va_arg()的实现就应该心中有数了：<br />    #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )<br />这个宏做了两个事情，<br />   ①用用户输入的类型名对参数地址进行强制类型转换，得到用户所需要的值<br />   ②计算出本参数的实际大小，将指针调到本参数的结尾，也就是下一个参数的首地址，以便后续处理。<br /><br />(5)va_end宏的解释：x86平台定义为ap=(char*)0;使ap不再 指向堆栈,而是跟NULL一样.有些直接定义为((void*)0),这样编译器不会为va_end产生代码,例如gcc在linux的x86平台就是这样定义的. 在这里大家要注意一个问题:由于参数的地址用于va_start宏,所以参数不能声明为寄存器变量或作为函数或数组类型. 关于va_start, va_arg, va_end的描述就是这些了,我们要注意的 是不同的操作系统和硬件平台的定义有些不同,但原理却是相似的.<br /><br />(三)可变参数在编程中要注意的问题 <br />因为va_start, va_arg, va_end等定义成宏,所以它显得很愚蠢, 可变参数的类型和个数完全在该函数中由程序代码控制,它并不能智能 地识别不同参数的个数和类型. 有人会问:那么printf中不是实现了智能识别参数吗?那是因为函数 printf是从固定参数format字符串来分析出参数的类型,再调用va_arg 的来获取可变参数的.也就是说,你想实现智能识别可变参数的话是要通过在自己的程序里作判断来实现的. 例如，在C的经典教材《the c programming language》的7.3节中就给出了一个printf的可能实现方式，由于篇幅原因这里不再叙述。<br /><br />（四）小结: <br />1、标准C库的中的三个宏的作用只是用来确定可变参数列表中每个参数的内存地址，编译器是不知道参数的实际数目的。<br />2、在实际应用的代码中，程序员必须自己考虑确定参数数目的办法，如<br />⑴在固定参数中设标志-- printf函数就是用这个办法。后面也有例子。<br />⑵在预先设定一个特殊的结束标记，就是说多输入一个可变参数，调用时要将最后一个可变参数的值设置成这个特殊的值，在函数体中根据这个值判断是否达到参数的结尾。本文前面的代码就是采用这个办法.<br />无论采用哪种办法，程序员都应该在文档中告诉调用者自己的约定。<br />3、实现可变参数的要点就是想办法取得每个参数的地址，取得地址的办法由以下几个因素决定：<br />①函数栈的生长方向<br />②参数的入栈顺序<br />③CPU的对齐方式<br />④内存地址的表达方式<br />结合源代码，我们可以看出va_list的实现是由④决定的，_INTSIZEOF(n)的引入则是由③决定的，他和①②又一起决定了va_start的实现，最后va_end的存在则是良好编程风格的体现，将不再使用的指针设为NULL,这样可以防止以后的误操作。<br />4、取得地址后，再结合参数的类型，程序员就可以正确的处理参数了。理解了以上要点，相信稍有经验的读者就可以写出适合于自己机器的实现来。下面就是一个例子<br /><br />（五）扩展--自己实现简单的可变参数的函数。<br />下面是一个简单的printf函数的实现，参考了&lt;The C Programming Language&gt;中的156页的例子，读者可以结合书上的代码与本文参照。<br />#include "stdio.h"<br />#include "stdlib.h"<br />void myprintf(char* fmt, ...)        //一个简单的类似于printf的实现，//参数必须都是int 类型<br />{ <br />    char* pArg=NULL;               //等价于原来的va_list <br />    char c;<br />    pArg = (char*) &amp;fmt;    //注意不要写成p = fmt !!因为这里要对//参数取址，而不是取值<br />    pArg += sizeof(fmt);         //等价于原来的va_start          <br />   do<br />    {<br />        c =*fmt;<br />        if (c != '%')<br />        {<br />            putchar(c);            //照原样输出字符<br />        }<br />        else<br />{<br />//按格式字符输出数据<br />            switch(*++fmt) <br />{<br />            case 'd':<br />                printf("%d",*((int*)pArg));           <br />                break;<br />            case 'x':<br />                printf("%#x",*((int*)pArg));<br />                break;<br />            default:<br />                break;<br />            } <br />            pArg += sizeof(int);               //等价于原来的va_arg<br />        }<br />        ++fmt;<br />    }while (*fmt != '\0'); <br />    pArg = NULL;                               //等价于va_end<br />    return; }<br />int main(int argc, char* argv[])<br />{<br />    int i = 1234;<br />    int j = 5678;<br />    myprintf("the first test:i=%d\n",i,j); <br />    myprintf("the secend test:i=%d; %x;j=%d;\n",i,0xabcd,j); <br />    system("pause");<br />    return 0;<br />}<br />在intel+win2k+vc6的机器执行结果如下：<br />the first test:i=1234<br />the secend test:i=1234; 0xabcd;j=5678;<br /><img src ="http://www.cnitblog.com/zouzheng/aggbug/21888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2007-01-15 21:54 <a href="http://www.cnitblog.com/zouzheng/articles/21888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>雅虎笔试题</title><link>http://www.cnitblog.com/zouzheng/articles/21759.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 11 Jan 2007 03:16:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/21759.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/21759.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/21759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/21759.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/21759.html</trackback:ping><description><![CDATA[辛辛苦苦把题做完，系统提示说“由于长时间未操作，系统失去联系”，艾...<font style="FONT-SIZE: 0px; COLOR: #ffffff">1C&#x1;E(` ? `&#x1B;M</font><br />可能每个人的题是随机的吧<font style="FONT-SIZE: 0px; COLOR: #ffffff">*j&#x7;_ w1U*z)J</font><p>Question 1. (单选)<br />在顺序表(3,6,8,10,12,15,16,18,21,25,30)中,用二分法查找关键码值11,所需的关键码比<br />较次数为(3)</p><p> 1. 2<br />2. 3<br />3. 4<br />4. 5</p><p>Question 2. (单选)<br />设散列表的存储空间大小为19,所用散列函数为h(key)=key mod 19,用开地址线性探查法解<br />决碰撞。散列表的当前</p><p>状态如下:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 190 194 768 559 582 39<br />3 208.现要将关键码</p><p>值75插入到该散列表中,其地址应为 (1)</p><p> 1. 1<br />2. 11<br />3. 5<br />4. 15</p><p>Question 3. (单选)<br />作业管理的主要任务包括作业输入、作业处理和作业输出。其中作业处理的工作是Ⅰ.作业<br />调度 Ⅱ.作业控制 Ⅲ.</p><p>作业后备 (3)</p><p> 1. 只有Ⅰ<br />2. 只有Ⅱ<br />3. Ⅰ和Ⅱ<br />4. 都是</p><p>Question 4. (单选)<br />系统为了管理文件,设置了专门的数据结构----文件控制块(FC。FCB是在执行下列哪一个系<br />统调用时建立的? (1)</p><p> 1. create<br />2. open<br />3. read<br />4. write</p><p>Question 5. (单选)<br />下面关于通道的叙述中,正确的是Ⅰ.通道相当于一个功能简单的处理机Ⅱ.通道完成数据输<br />入输出工作Ⅲ.通道与</p><p>CPU共用一个内存 (4)</p><p> 1. Ⅰ和Ⅱ<br />2. Ⅰ和Ⅲ<br />3. Ⅱ和Ⅲ<br />4. 都是</p><p>Question 6. (单选)<br />互操作性是指在不同环境下的应用程序可以相互操作,交换信息。要使采用不同数据格式的<br />各种计算机之间能够相</p><p>互理解,这一功能是由下面哪一层来实现的? (2)</p><p> 1. 应用层<br />2. 表示层<br />3. 会话层<br />4. 传输层</p><p>Question 7. (单选)<br />在UNIX的Shell程序中,可以使用位置变量。若要指明Shell引用的最近后台进程的号码,可<br />以使用位置变量 (2)</p><p> 1. $$<br />2. $!<br />3. $#<br />4. $-</p><p>Question 8. (单选)<br />设二叉树根结点的层次为0，一棵深度(高度)为k的满二叉树和同样深度的完全二叉树各有<br />f个结点和c个结点，下列</p><p>关系式不正确的是： (2)</p><p> 1. f&gt;＝c<br />2. c&gt;f<br />3. f=2k+1-1<br />4. C&gt;2k-1</p><p>Question 9. (单选)<br />单链表的每个结点中包括一个指针link，它指向该结点的后继结点。现要将指针q指向的新<br />结点插入到指针p指向的</p><p>单链表结点之后，下面的操作序列中哪一个是正确的？ (3)</p><p> 1. q:=p^.link; p^.link:=q^.link<br />2. p^.link:=q^.link; q:=P^.link<br />3. q^.link:=p^.link; p^.link:=q;<br />4. p^.link:=q; q^.link:=p^,link</p><p>Question 10. (单选)<br />某二叉树结点的对称序序列为A、B、C、D、E、F、G，后序序列为B、D、C、A、F、G、E。<br />该二叉树结点的前序序</p><p>列为  (2)</p><p> 1. E、G、F、A、C、D、B<br />2. E、A、C、B、D、G、F<br />3. E、A、G、C、F、B、D<br />4. E、G、A、C、D、F、B</p><p>Question 11. (单选)<br />某二叉树结点的对称序序列为A、B、C、D、E、F、G，后序序列为B、D、C、A、F、G、E。<br />该二叉树对应的树林包</p><p>括多少棵树？ (2)</p><p> 1. 1<br />2. 2<br />3. 3<br />4. 4</p><p>Question 12. (单选)<br />某二叉树结点的对称序序列为A、B、C、D、E、F、G，后序序列为B、D、C、A、F、G、E。<br />该二叉树对应的树林结</p><p>点的层次次序序列为  (1)</p><p> 1. E、G、F、A、C、D、B<br />2. E、A、C、B、D、G、F<br />3. E、A、G、C、F、B、D<br />4. E、G、A、C、D、F、B</p><p>Question 13. (单选)<br />假设就绪队列中有10个进程，系统将时间片设为200ms， CPU进行进程切换要花费10ms。则<br />系统开销所占的比率约</p><p>为  (2)</p><p> 1. 1%<br />2. 5%<br />3. 10%<br />4. 20%</p><p>Question 14. (单选)<br />长度相同但格式不同的2种浮点数，假设前者阶码长、尾数短，后者阶码短、尾数长，其它<br />规定均相同，则它们可</p><p>表示的数的范围和精度为： (2)</p><p> 1. 两者可表示的数的范围和精度相同<br />2. 前者可表示的数的范围大但精度低<br />3. 后者可表示的数的范围大且精度高<br />4. 前者可表示的数的范围大且精度高</p><p>Question 15. (单选)<br />所谓“变号操作”是指将一个整数变成绝对值相同但符号相反的另一个整数。假设使用补<br />码表示的8位整数</p><p>X=10010101，则经过变号操作后结果为：(4)</p><p> 1. 1101010<br />2. 10101<br />3. 11101010<br />4. 1101011</p><p>Question 16. (单选)<br />设有一个用数组Q[1..m」表示的环形队列，约定f为当前队头元素在数组中的位置，r为队<br />尾元素的后一位置(按顺</p><p>时针方向)，若队列非空，则计算队列中元素个数的公式应为：(2)</p><p> 1. r-f<br />2. (m+r-f) mod m<br />3. (m-r+f)mod m<br />4. (m-r-f) mod m</p><p>Question 17. (单选)<br />计算机最主要的工作特点是(2)</p><p> 1. 存储程序与自动控制<br />2. 高速度与高精度<br />3. 可靠性与可用性<br />4. 有记忆能力</p><p>Question 18. (单选)<br />计算机中数据的表示形式是(3)</p><p> 1. 八进制<br />2. 十进制<br />3. 二进制<br />4. 十六进制</p><p>Question 19. (单选)<br />下面列出的四种存储器中，易失性存储器是(1)</p><p> 1. RAM<br />2. ROM<br />3. PROM<br />4. CD-ROM</p><p>Question 20. (单选)<br />I/O接口位于 (2)</p><p> 1. 总线和设备之间<br />2. CPU和I/O设备之间<br />3. 主机和总线之间<br />4. CPU和主存储器之间</p><p>Question 21. (单选)<br />计算机硬件能直接识别和执行的只有(4)</p><p> 1. 高级语言<br />2. 符号语言<br />3. 汇编语言<br />4. 机器语言</p><p>Question 22. (单选)<br />具有多媒体功能的微型计算机系统中，常用的CD-ROM是(2)</p><p> 1. 只读型大容量软盘<br />2. 只读型光盘<br />3. 只读型硬盘<br />4. 半导体只读存储器</p><p>Question 23. (单选)<br />微机中1K字节表示的二进制位数是(4)</p><p> 1. 1000<br />2. 8x1000<br />3. 1024<br />4. 8x1024</p><p>Question 24. (单选)<br />下列字符中，ASCII码值最小的是(2)</p><p> 1. a<br />2. A<br />3. x<br />4. Y</p><p>Question 25. (单选)<br />OSI(开放系统互联)参考模型的最低层是(3)</p><p> 1. 传输层<br />2. 网络层<br />3. 物理层<br />4. 应用层</p><p>Question 26. (单选)<br />在面向对象的系统中，系统责任的良好分配原则是(3)</p><p> 1. 在类之间均匀分配<br />2. 集中分配在少数控制类中<br />3. 根据交互图的消息进行分配<br />4. 根据个人喜好进行分配</p><p>Question 27. (单选)<br />在CMM模型中，对软件成熟度有以下5个级别，请从低到高排序<br />a 初始级:<br />软件过程的特点是无秩序的，偶尔甚至是混乱的。几乎没有什么过程是经过定义的,成功依<br />赖于个人的努力。</p><p>b 优化级:<br />利用来自过程和来自新思想、新技术的先导性试验的定量反馈信息，使持续过程改进成为<br />可能。</p><p>c 已定义级:<br />管理活动和工程活动两方面的软件过程均已文档化、标准化、并集成到组织的标准软件过<br />程。</p><p>d 已管理级:<br />已采集详细的有关软件过程和产品质量的度量,无论软件过程还是产品均得到定量了解和控<br />制。</p><p>e 可重复级:<br />已建立基本的项目管理过程去跟踪成本、进度和功能性。必要的过程纪律已经就位，使具<br />有类似应用的项目。能重</p><p>复以前的成功。<br />(3)</p><p> 1. acdbe<br />2. adceb<br />3. aecdb<br />4. abcde</p><p>Question 28. (单选)<br />在下面所列举的逻辑测试覆盖中，测试覆盖最强的是(3)</p><p> 1. 条件覆盖<br />2. 条件组合覆盖<br />3. 语句覆盖<br />4. 条件及判定覆盖</p><p>Question 29. (单选)<br />一般来说，在软件维护过程中，大部分工作是由什么引起的(3)</p><p> 1. 适应新的软件环境<br />2. 适应新的硬件环境<br />3. 用户的需求改变<br />4. 程序的可靠性</p><p>Question 30. (单选)(2)<br />PSP是？</p><p> 1. 团队软件过程<br />2. 个体软件过程<br />3. 过程改进过程<br />4. 质量管理过程</p><p>Question 31. (单选)<br />假定a和b为int型变量,则执行以下语句后b的值为   (4)<br />a=1; b=10;<br />do { b-=a; a++; } while (b--&lt;0);</p><p> 1. 9<br />2. -2<br />3. -1<br />4. 8</p><p>Question 32. (单选)<br />设有以下宏定义:<br />#define N 3<br />#define Y(n) ( (N+1)*n)<br />则执行语句:z=2 * (N+Y(5+1));后,z的值为 (3)</p><p> 1. 出错<br />2. 42<br />3. 48<br />4. 54</p><p>Question 33. (单选)<br />执行以下程序段后,m的值为  (1)<br />int a[2][3]={ {1,2,3},{4,5,6} };<br />int m,*p;<br />p=&amp;a[0][0];<br />m=(*p)*(*(p+2))*(*(p+4));</p><p> 1. 15<br />2. 14<br />3. 13<br />4. 12</p><p>Question 34. (单选)<br />有以下程序<br />main()<br />{ char a[]="programming", b[]="language";<br />char *p1,*p2;<br />int i;<br />p1=a; p2=b;<br />for(i=0;i&lt;7;i++)<br />if(*(p1+i)==*(p2+i)) printf("％c",*(p1+i));<br />}<br />输出结果是 (4)</p><p> 1. gm<br />2. rg<br />3. or<br />4. ga</p><p>Question 35. (单选)<br />有以下程序<br />int fun(int x,int y,int *cp,int *dp)<br />{ *cp=x+y; *dp=x-y; }<br />main()<br />{ int a, b, c, d;<br />a=30; b=50;<br />fun(a,b,&amp;c,&amp;d);<br />printf("%d,%d<br />", c, d);<br />}<br />输出结果是 (3)</p><p> 1. 50,30<br />2. 30,50<br />3. 80,-20<br />4. 80,20</p><p>Question 36. (单选)<br />下述标识符中, 合法的用户标识符是(4)</p><p> 1. A#C<br />2. getch<br />3. void<br />4. sizeOf</p><p>Question 37. (单选)<br />以下选项中合法的字符常量是(3)</p><p> 1. A<br />2. '10'<br />3. 68<br />4. D</p><p>Question 38. (单选)<br />以下叙述正确的是 (3)</p><p> 1. 在C程序中，main函数必须位于程序的最前面<br />2. C程序的每行中只能写一条语句<br />3. C语言本身没有输入输出语句<br />4. 在对一个C程序进行编译的过程中，可发现注释中的拼写错误</p><p>Question 39. (单选)<br />以下叙述中不正确的是 (4)</p><p> 1. 在不同的函数中可以使用相同名字的变量<br />2. 函数中的形式参数是局部变量<br />3. 在一个函数内定义的变量只在本函数范围内有效<br />4. 在一个函数内的复合语句中定义的变量在本函数范围内有效</p><p>Question 40. (单选)<br />设int类型的数据长度为2个字节，则 unsigned int 类型数据的取值范围是 (2)</p><p> 1. 0~255<br />2. 0~65535<br />3. -32768~32767<br />4. -256~255</p><p>Question 41. (单选)<br />某文件中定义的静态全局变量(或称静态外部变量)其作用域是 (2)</p><p> 1. 只限某个函数<br />2. 本文件<br />3. 跨文件<br />4. 不限制作用域</p><p>Question 42. (单选)<br />语句:printf("%d<br />"，12 &amp; 012)；的输出结果是 (3)</p><p> 1. 12<br />2. 012<br />3. 8<br />4. 6</p><p>Question 43. (单选)<br />设int x=4; 则执行以下语句: x+=x-=x-x;后,x的值为 (3)</p><p> 1. 0<br />2. 4<br />3. 8<br />4. 12</p><p>Question 44. (单选)<br />while(!x)中的(!x)与下面条件等价。 (4)</p><p> 1. x==1<br />2. x!=1<br />3. x!=0<br />4. x==0</p><p>Question 45. (单选)<br />已知int i,a;执行语句: i=(a=2*3,a*5),a+6;后,变量i的值是 (3)</p><p> 1. 6<br />2. 12<br />3. 30<br />4. 36</p><p>Question 46. (单选)<br />整型变量x和y的值相等、且为非0值，则以下选项中，结果为零的表达式是 (4)</p><p> 1. x || y<br />2. x | y<br />3. x &amp; y<br />4. x ^ y</p><p>Question 47. (单选)<br />x、y、z被定义为int型变量，若从键盘给x、y、z输入数据，正确的输入语句是  (2)</p><p> 1. INPUT x、y、z;<br />2. scanf("%d%d%d",&amp;x,&amp;y,&amp;z);<br />3. scanf("%d%d%d",x,y,z);<br />4. read("%d%d%d",x,y,z);</p><p>Question 48. (单选)<br />以下各选项企图说明一种新的类型名，其中正确的是 (2)</p><p> 1. typedef v1 int;<br />2. typedef int v3;<br />3. typedef v4: int;<br />4. typedef v2=int;</p><p>Question 49. (单选)<br />char x=3,y=6,z;<br />z=x^y&lt;&lt;2;<br />则z的二进制值是 (2)</p><p> 1. 10100<br />2. 11011<br />3. 11100<br />4. 11000</p><p>Question 50. (单选)<br />若有说明：int i, j=2，*p=&amp;i;，则能完成i=j赋值功能的语句是 (2)</p><p> 1. i=*p;<br />2. *p=*&amp;j;<br />3. i=&amp;j;<br />4. i=**p;</p><p>Question 51. (问答)<br />给定一个整型变量a，写两段代码，第一个设置a的bit 3，第二个清除a的bit 3。在以上两<br />个操作中，要保持其它</p><p>位不变。</p><p> a|=0x4;</p><p>int b=a&amp;0x7;<br />a&gt;&gt;=4;<br />a=(a&lt;&lt;4)|b;</p><p>Question 52. (问答)<br />有双向循环链表结点定义为：<br />struct node<br />{ int data;<br />struct node *front,*next;<br />};<br />有两个双向循环链表A，B，知道其头指针为：pHeadA,pHeadB，请写一函数将两链表中dat<br />a值相同的结点删除</p><p> struct node<br />{ int data;<br />struct node *front,*next;<br />};<br />node* del(node *pHead){<br />    if(pHead==pHead-&gt;next){<br />                  free(pHead);<br />        return NULL;<br />         }<br />         node *p=pHead;<br />    pHead-&gt;next-&gt;front=pHead-&gt;front;<br />    pHead-&gt;front-&gt;next=pHead-&gt;next;<br />    pHead=pHead-&gt;next;<br />         free(p);<br />    return pHead;<br />}<br />void delequ(node*pHeadA,node *pHeadB){<br />    node *pA=pHeadA;<br />    node *pB;<br />    int flag;<br />    do{<br />        flag=0;<br />        pB=pHeadB;<br />        do{<br />            if(pB-&gt;data==pA-&gt;data){<br />                if(pA==pHeadA){<br />                    pHeadA=pA=del(pHeadA);<br />                    flag=1;<br />                }<br />                else{<br />                    pA=del(pA);<br />                }<br />                pB=del(pB);<br />                break;<br />            }<br />            pB=pB-&gt;next;<br />        }while(pB!=pHeadB);<br />        if(flag==0){<br />            pA=pA-&gt;next;<br />        }<br />    }while(!pA &amp;&amp; !pB &amp;&amp; (flag||(pA!=pHeadA)));<br />}</p><p>Question 53. (问答)<br />编程实现：找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"c<br />ad"</p><p> char* constr(char *A,char *B){<br />    int lenA=strlen(A),lenB=strlen(B);<br />    int itmp,conlen=0;<br />    char *pequ,*pH=NULL;<br />    char *pA,*pB,*pA2,*pB2;<br />    for(pA=A;pA-A<lena-conlen;pa++){><br />        for(pB=B;pB-B<lenb-conlen;){><br />            if(*pB==*pA){<br />                pA2=pA+1;<br />                pB2=pB+1;<br />                for(itmp=1;*pA2==*pB2 &amp;&amp; pA2++-A<lena &&="" pb2++-b<lenb;itmp++);<br="" />                if(itmp&gt;conlen){<br />                    conlen=itmp;<br />                    pH=pA;<br />                }<br />            }<br />            pB++;<br />        }<br />    }<br />    pequ=(char*)malloc(conlen+1);<br />    memcpy(pequ,pH,conlen);<br />    *(pequ+conlen)='\0';<br />    return pequ;<br />}</lenb-conlen;){></lena-conlen;pa++){></p><p>Question 54. (问答)<br />说明关键字static和volatile的含义</p><p> static用于外部变量或者函数时，限制了它们的作用域为文件内部；static也可以用于内<br />部变量，这样，内部变</p><p>量在每次函数调用时都为同一存储，值具有连续性。</p><p>volatile说明了一个变量的值是会随机变化的，即使程序没有对它进行任何赋值操作。它<br />告诉编译器的优化处理器</p><p>，这些变量是实实在在存在的，在优化过程中不能无故消除，这样就保证了编译后的代码<br />在每次操作是从变量地址</p><p>处取数。</p><p>Question 55. (问答)<br />编程实现：把十进制数(long型)分别以二进制和十六进制形式输出，不能使用printf系列<br />库函数</p><p> void put(long data){<br />    long mask=0x1&lt;&lt;(8*sizeof(long)-1);<br />    int i;<br />    char c;<br />    if(data&amp;mask)<br />    putchar('1');<br />    else<br />    putchar('0');<br />    mask=0x1&lt;&lt;(8*sizeof(long)-2);<br />    for(i=1;i&lt;8*sizeof(long);i++){<br />        if(data&amp;mask)<br />            putchar('1');<br />        else<br />            putchar('0');<br />        mask&gt;&gt;=1;<br />    }<br />    putchar('\n');<br />    mask=0xf&lt;&lt;(8*sizeof(long)-4);<br />    c=(data&amp;mask)&gt;&gt;(8*sizeof(long)-4);<br />    if(c&lt;10)<br />    putchar(c+'0');<br />    else<br />    putchar(c+'a');<br />    mask=0xf&lt;&lt;(8*sizeof(long)-8);<br />    for(i=1;i&lt;2*sizeof(long);i++){<br />        c=(data&amp;mask)&gt;&gt;(8*sizeof(long)-4*i-4);<br />        if(c&lt;10)<br />            putchar(c+'0');<br />        else<br />            putchar(c+'a');<br />        mask&gt;&gt;=4;<br />    }<br />}</p><p> </p><p>////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////<br />在这里公布选择题的答案没有意义的，选择题是随机从题库中提取的，每个人只有很少几<br />个是一样的，大部分都不一样。</p><p>最后的5个问答题是一样的。这里提供第54，55题的答案，仅供参考！<br />＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝<br />54题：<br />在C中，static变量的含义。<br />A:static 声明的变量在C语言中有两方面的特征：<br />　　1)、变量会被放在程序的全局存储区中，这样可以在下一次调用的时候还可以保持原<br />来的赋值。这一点是它与堆栈变量和堆变量的区别。<br />　　2)、变量用static告知编译器，自己仅仅在变量的作用范围内可见。这一点是它与全<br />局变量的区别。<br />Tips:<br />　　A.若全局变量仅在单个C文件中访问，则可以将这个变量修改为静态全局变量，以降低<br />模块间的耦合度；<br />　　B.若全局变量仅由单个函数访问，则可以将这个变量改为该函数的静态局部变量，以<br />降低模块间的耦合度；<br />　　C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时，需要考虑<br />重入问题；<br />    D.如果我们需要一个可重入的函数，那么，我们一定要避免函数中使用static变量(这<br />样的函数被称为：带“内部存储器”功能的的函数)<br />     E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时，则必须<br />是static的局部变量的地址作为返回值，若为auto类型，则返回为错指针。</p><p>=====================================</p><p>volatile总是与优化有关，编译器有一种技术叫做数据流分析，分析程序中的变量在哪里<br />赋值、在哪里使用、在哪里失效，分析结果可以用于常量合并，常量传播等优化，进一步<br />可以死代码消除。但有时这些优化不是程序所需要的，这时可以用volatile关键字禁止做<br />这些优化，volatile的字面含义是易变的，它有下面的作用：</p><p>1 不会在两个操作之间把volatile变量缓存在寄存器中。在多任务、中断、甚至setjmp环<br />境下，变量可能被其他的程序改变，编译器 自己无法知道，volatile就是告诉编译器这种<br />情况。</p><p>2 不做常量合并、常量传播等优化，所以像下面的代码：<br />volatile int i = 1;<br />if (i &gt; 0) ...</p><p>if的条件不会当作无条件真。</p><p>3 对volatile变量的读写不会被优化掉。如果你对一个变量赋值但后面没用到，编译器常<br />常可以省略那个赋值操作，然而对Memory Mapped IO的处理是不能这样优化的。</p><p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p><p>55题，递归算法：<br />/*长整型转变成二进制*/<br />void binary(long n)<br />{<br />    char c;<br />    if(n/2!=0)<br />        binary(n/2);<br />        c=n%2+48;<br />        putch(c);<br />}</p><p><br />/*长整型转变成十六进制*/</p><p>void hex(long n)<br />{<br />    if(n/16!=0)<br />        hex(n/16);<br />        if(n%16&gt;=0&amp;&amp;n%16&lt;=9)<br />            {c=n%16+48;<br />             putch(c);<br />            }<br />        else<br />            {c=n%16-10+97;<br />            putch(c);<br />            }</p><p>}  </p><img src ="http://www.cnitblog.com/zouzheng/aggbug/21759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/zouzheng/" target="_blank">zz</a> 2007-01-11 11:16 <a href="http://www.cnitblog.com/zouzheng/articles/21759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C语言题库</title><link>http://www.cnitblog.com/zouzheng/articles/21758.html</link><dc:creator>zz</dc:creator><author>zz</author><pubDate>Thu, 11 Jan 2007 02:07:00 GMT</pubDate><guid>http://www.cnitblog.com/zouzheng/articles/21758.html</guid><wfw:comment>http://www.cnitblog.com/zouzheng/comments/21758.html</wfw:comment><comments>http://www.cnitblog.com/zouzheng/articles/21758.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/zouzheng/comments/commentRss/21758.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/zouzheng/services/trackbacks/21758.html</trackback:ping><description><![CDATA[*1 <br />A <br />一个C程序的执行是从_____。 <br /> A)本程序的main函数开始,到main函数结束 <br /> B)本程序文件的第一个函数开始,到本程序文件的最后一个函数结束 <br /> C)本程序的main函数开始,到本程序文件的最后一个函数结束 <br /> D)本程序文件的第一个函数开始,到本程序main函数结束 <br />*2 <br />C <br />以下叙述正确的是: <br />A)在C程序中,main函数必须位于程序的最前面 <br />B)C程序的每行中只能写一条语句 <br />C)C语言本身没有输入输出语句 <br />D)在对一个C程序进行编译的过程中,可发现注释中的拼写错误 <br />*3 <br />D <br />以下叙述不正确的是。 <br />A)一个C源程序可由一个或多个函数组成 <br />B)一个C源程序必须包含一个main函数 <br />C)C程序的基本组成单位是函数 <br />D)在C程序中,注释说明只能位于一条语句的后面 <br />*4 <br />C <br />C语言规定:在一个源程序中,main函数的位置 。 <br />A)必须在最开始 <br />B)必须在系统调用的库函数的后面 <br />C)可以任意 <br />D)必须在最后 <br />*5 <br />B <br />一个C语言程序是由 <br />A)一个主程序和若干子程序组成    B)函数组成 <br />C)若干过程组成                  D)若干子程序组成 <br />*6 <br />A <br />在C语言中(以16位PC机为例),5种基本数据类型的存储空间长度的排列顺序为 <br />A)char<int&nbsp;&nbsp;><1ong&nbsp;&nbsp;int>&lt;=FLOAT<double><br />B)char=int&lt;1ong  int&lt;=float<double><br />C)char&lt;  int  &lt;1ong  int=float=double <br />D)char=int  =1ong  int&lt;=float<double><br />*7 <br />C <br />若x,i,j和k都是int型变量,则执行下面表达式后x的值为 <br /> x=(i=4,j=16,k=32) <br /> A)4   B)16  C)32     D)52 <br />*8 <br />B <br />假设所有变量均为整型,则表达式(a=2,b=5,b++,a+b)的值是: <br /> A)7    B)8   C)6   D)2 <br />*9 <br />A <br />下列四组选项中,均不是C语言关键字的选项是 <br />A)define    B)getc    C)include   D)while <br /> IF           char       scanf        go <br />type          printf       case        pow <br />*10 <br />B <br />下面四个选项中,均是C语言关键字的选项是 <br />A)auto      B)switch    C)signed    D)if <br /> enum       typedef       union      struct <br /> include     continue      scanf      type <br />*11 <br />C <br />下面四个选项中,均是不合法的用户标识符的选项是。 <br /> A)  A            B)float       C)b-a       D)一123 <br />    P_0            1a0          goto          temp <br />    do             一A          int           INT <br />*12 <br />C <br />C语言中的标识符只能由字母、数字和下划线三种字符组成,且第一个字符 <br /> A)必须为字母            B)必须为下划线 <br /> C)必须为字母或下划线   D)可以是字母,数字和下划线中任一种字符 <br />*13 <br />A <br />下面四个选项中,均是合法整型常量的选项是: <br />A)160      B)一0xcdf    C)一01    D)一0x48a <br /> 一0xffff      01a       986, 012      2e5 <br />     011        0xe        0668         0x <br />*14 <br />D <br />下面四个选项中,均是不合法的整型常量的选项是: <br />A)一一0f1    B)一0Xcdf  C)一018    D)一0x48eg <br />一0xffff          017        999        一068 <br />   <br />      0011        12,456      5e2         03f <br />*15 <br />B <br />下面四个选项中,均是不合法的浮点数的选项是 <br />A)  160.    B)  123     C)一.18    D)一e3 <br />   0.12        2e4.2     123e4          .234 <br />     e3        .e5        0.0           1e3       <br />*16  <br />b <br />下面四个选项中,均是合法浮点数的选项是 <br />  A)  +le+1    B)-.60    C)  123e      D)一e3 <br />      5e一9.4    12e-4     1.2e-.4     .8e4 <br />      03e2     一8e5        +2e一1     5.e一0 <br />*17 <br />A <br />下面四个选项中,均是合法转义字符的选项是 <br /> A)'\''        B)'\'    C)'\018'   D)'\\0' <br />    '\\'     '\017'    '\f'       '101' <br />    '\n'     '\"'       'xab'       'xlf' <br />*18 <br />B <br />下面四个选项中,均是不合法的转义字符的选项是 <br />  A)'\''     B)'\1011'    C)'\011'    D)'\abc' <br />    '\\'         '\'        '\f'         '\101' <br />    '\xf'       '\a'         '\}'        'xlf' <br />*19 <br />C <br />下面正确的字符常量是: <br />A)"a"    B)'\\''    C)'W'    D)'' <br />*20 <br />d <br />   <br />下面四个选项中,均是不正确的八进制数或十六进制数的选项是。 <br />    A)  016      B)oabc       C)010      D)  0a12 <br />0x8f  017 -0x11   7ff <br />018   0x8  0x16   -123 <br />*21 <br />C <br />下面四个选项中,均是正确的八进制数或十六进制数的选项是。 <br /> A)一10 B)0abc      C)0010   0)  0al2 <br />   0x8f    一017       一0x11-0xl23 <br />  一011     0xc 0xf1      一0x8 <br />*22 <br />d <br />下面四个选项中、均是正确的数值常量或字符常量的选项是: <br />   A)0.0       日)"a"     C)'3'D)十001 <br />      0f  3.9E-2.5       011     0xabcd <br />     8.9e   lel0xFFOO  2e2 <br />      '&amp;' '\'''       0a       50. <br />*23 <br />A <br />下面不正确的字符串常量是。 <br />  A)'abc'  B)"12'12"     C)"0"     D)"" <br />*24 <br />c <br />若有代数式3ae/bc,则不正确的C语言表达式是: <br /> A) a/b/c*e*3      B)3*a*e/b/c <br /> C)3*a*e/b*c       D)a*e/c/b*3 <br />*25 <br />A <br />已知各变量的类型说明如下: <br />   int   k,a,b; <br />   unsigned  long  w= 5; <br />  double    x=1.42; <br />则以下不符合C语言语法的表达式是: <br />A)  x%(一3)   B)  w+=-2 <br />C)k=(a=2,b=3,a十b)      D)a十= a一=(b=4)*(a=3) <br />*26 <br />A <br />已知各变量的类型说明如下: <br /> int i=8,k,a,b; <br />unsigned  long  w=5; <br /> double  x=1.42,y=5.2; <br />则以下符合C语言语法的表达式是: <br />A)  a十=a一=(b= 4)*(a=3)  B)a=a*3=2 <br />C)  x%(一3)  D)y=f1oat(i) <br />*27 <br />D <br />以下不正确的叙述是 <br />A)在C程序中,逗号运算符的优先级最低 <br />B)在C程序中,APH和aph是两个不同的变量 <br />C)若a和b类型相同,在执行了赋值表达式a=b后b中的值将放人a中,而b中的值不变。 <br />D)当从键盘输入数据时,对于整型变量只能输入整型数值,对于实型变量只能输入实型数值。 <br />*28 <br />D <br />以下正确的叙述是: <br />A)在C程序中,每行中只能写一条语句 <br />B)若a是实型变量,C程序中允许赋值a=10,因此实型变量中允许存放整型数 <br />C)在C程序中,无论是整数还是实数,都能被准确无误地表示 <br />D)在C程序中,%是只能用于整数运算的运算符 <br />*29 <br />B <br />以下符合C语言语法的赋值表达式是 <br />A)d=9+e+f=d+9B)  d=9+e,f=d+9 <br />C)d=9十e,e++,d十9     D)d=9十e++=d十7 <br />*30 <br />A <br />已知字母A的ASCII码为十进制数65,且c2为字符型,则执行语句c2='A'十'6'一'3';后,c2中的值为 <br />A)D     B)68   C)不确定的值     D)C <br />*31 <br />D <br />在C语言中,要求运算数必须是整型的运算符是。 <br />A) /   B) ++  c) !=   D)% <br />*32 <br />B <br />若以下变量均是整型,且num=sum=7;则执行表达式sUM=num++,sUM++,++num后sum的值为 <br /> A)  7    B)  8  C)  9  D)  10 <br />*33 <br />D <br />在C语言中,int、char和short种类型数据在内存中所占用的字节数 <br />A)由用户自己定义     B)均为2个字节 <br />C)是任意的   D)由所用机器的机器字长决定 <br />*34 <br />A <br />若有说明语句:char c='\72'则变量c <br />A)包含1个字符   B)包含2个字符 <br />C)包含3个字符   D)说明不合法,c的值不确定 <br />*35 <br />A <br />若有定义:int a=7;float x=2.5,y=4.7;则表达式x+a%3*(int)(x+y)%2/4的值是 <br />A)2•500000  B)2.7500OO  c)  3.500000  D)  0.000000。 <br />*36 <br />B <br />sizeof(float)是: <br />A)一个双精度型表达式  B)一个整型表达式 <br />C)一种函数调用D)一个不合法的表达式 <br />*37 <br />C <br />设变量a是整型,f是实型,i是双精度型,则表达式10+'a'+i*f值的数据类型为 <br /> A)int     B)  float  C)  double  D)不确定 <br />*38 <br />A <br />下面四个选项中,均是非法常量的选项是。 <br />A)'as'    B)'\\'  c)-0xl8    D)0xabc <br />  -0fff '\01'    01177     '\0' <br />'\0xa'     12,456     0xf"a" <br />*39 <br />D <br />在C语言中,  char型数据在内存中的存储形式是: <br />A)补码 B)反码 C)原码     D)ASCII码 <br />*40 <br />B <br />设变量n为f1oat类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是一一一。 <br />A) n=(n*100+0.5)/100.0     B)m=n*100+0.5 ,n= m/100.0 <br />C) n=n*100+0.5/100.0   D)n=(n/100+0.5)*100.0 <br />*41 <br />C <br />表达式18/4*sqrt(4.0)/8值的数据类型为: <br />A)  int    B)float   C)double  D)不确定 <br />*42 <br />C <br />设C语言中,一个int型数据在内存中占2个字节,则unsigned  int型数据的取值范围为: <br />   <br />A)  0～255   B) 0～32767     C) 0～65535  D)  0～2147483647 <br />*43 <br />D <br />设有说明:  char w; int  x;  f1oat  y;  double  z;则表达式w* x+z一y值的数据类型为: <br />A)float    B)char   C)int     D)double <br />*44 <br />D <br />若有以下定义,则能使值为3的表达式是: <br />int  k= 7,x =12; <br />A)  x%=(k%= 5)B)  x%=(k一k%5) <br />C)  x%=k- k%5   D)  (x%=k)一(k%=5) <br />*45 <br />C <br />设以下变量均为int类型,则值不等于7的表达式是 <br />A)  (x= y= 6,  x+y,x+1)   B)(x= y= 6,x+y,y+1) <br />C)  (x= 6,x+1,y= 6,x+y)   D)  (y=6,y+l,x = y,x+1) <br />*46 <br />D <br />putchar函数可以向终端输出一个: <br />A)整型变量表达式值 <br />B)实型变量值 <br />C)字符串 <br />D)字符或字符型变量值 <br />*47 <br />B <br />printf函数中用到格式符%5s ,其中数字5表示输出的字符串占用5列。如果字符串长度大于5,则输出按方式 <br />A)从左起输出该字串,右补空格 <br />B)按原字符长从左向右全部输出 <br />C)右对齐输出该字串,左补空格 <br />D)输出错误信息 <br />*48 <br />C <br />printf函数中用到格式符%5s ,其中数字5表示输出的字符串占用5列。如果字符串长度小于5,则输出按方式。 <br />A)从左起输出该字串,右补空格 <br />B)按原字符长从左向右全部输出 <br />C)右对齐输出该字串,左补空格 <br />D)输出错误信息 <br />*49 <br />D <br />已有定义 int a=-2;和输出语句:printf("%8lx",a);以下正确的叙述是: <br />A)整型变量的输出格式符只有%d一种 <br />B)%x 是格式符的一种,它可以适用于任何一种类型的数据 <br />C)%x 是格式符的一种,其变量的值按十六进制输出,但%8lx 是错误的 <br />D)%8lx 不是错误的格式符,其中数字8规定了输出字段的宽度 <br />*50 <br />D <br />若x ,y均定义为int型,z定义为double型,以下不合法的scanf函数调用语句是: <br />A)  scanf(" %d%lx,%le",&amp;x,&amp;y,&amp;z); <br />B)  scanf("%2d * %d%lf"&amp;x,&amp;y,&amp;z );   <br />C)  scanf("%x %* d%o",&amp;x,&amp;y); <br />D)  scanf("%x%o%6.2f",&amp;x,&amp;y,&amp;z);    <br />*51 <br />A <br />已有如下定义和输入语句 ,若要求a1,a2,c1,c2值分别为10,20,A和B,当从第一列开始输入数据时,正确的数据输入方式是 <br />int  a1,a2;  char  c1,c2; <br />scanf("%d%c%d%c",&amp;a1,&amp;c1,&amp;a2,&amp;c2); <br />A)10A 20B&lt; CR&gt;     B)10 A 20 B<cr /><br />C)10A20<cr />   D)10A20 B<cr />。 <br />*52 <br />B <br />已有定义int  x;  f1oat  y;且执行scanf("%3d%f",&amp;x,&amp;y);语句,若从第一列开始输入数据12345  678(回车),则x 的值为 <br />A)12345  B)123   。  C)  45       D)  345 <br />*53 <br />B <br />已有定义int  x;  f1oat  y;且执行scanf("%3d%f",&amp;x,&amp;y);语句,若从第一列开始输入数据12345  678(回车),则y 的值为: <br />A)无定值B)45.0000  C)  678.000000  D)  123.00000 <br />*54 <br />D <br />已有如下定义和输入语句,若要求a1,a2,c1,c2的值分别为10,20,A,B,当从第一列开始输入数据时,正确的数据输入方式是: <br />int  a1,a2;  char  c1,c2; <br />scanf("%d%d",&amp;a1,&amp;a2); <br />scanf("%c%c",&amp;c1,&amp;c2); <br /> A)  1020AB<cr />    B)10  20<cr />AB<cr /><br /> C)10  20   AB<cr />   D)10 20AB<cr /><br />*55 <br />D <br />已有程序段和输入数据的形式如下,程序中输入语句的正确形式应当为 <br /> main() <br />{int  a;float f; <br />    printf("\nInput number:"); <br />  输入语句 <br />    printf("\nf=%f,a= %d\n ,f,a); <br />} <br />Input  number:  4.5   2<cr /><br />A )scanf("%d,%f",&amp;a,&amp;f);  B)scanf("%f,%d",&amp;f,&amp;a) <br />C)scanf("%d%f",&amp;a,&amp;f);   D)scanf("%f%d",&amp;f,&amp;a); <br />*56 <br />B <br />根据定义和数据的输入方式,输入语句的正确形式为: <br />已有定义:  float  fl,f2; <br />数据的输入方式:4.52 <br />3. 5 <br />A)scanf("%f,%f",&amp;f1,&amp;f2);  B)scanf("%f%f",&amp;f1,&amp;f2 ); <br />C)scanf("%3.2f%2.1f",&amp;f1,&amp;f); D)scanf("%3.2f%2.1f",&amp;f1,&amp;f2); <br />*57 <br />D <br />阅读以下程序,当输入数据的形式为25,13,10<cr />正确的输出结果为: <br /> main() <br />{int  x,y,z <br /> scanf("%d%d%d",&amp;x,&amp;y,&amp;z ); <br /> printf("x+y+z=%d\n ,x+y+z);。 <br /> } <br /> A)x +y+z=48      B)x +y+z=35 <br /> C)x +z=35D)不确定值 <br />*58 <br />B <br />阅读 下程序,若运行结果为如下形式  ,输入输出语句的正确内容是: <br />main() <br />{int  x;  float  y;printf("enter  x,y  :") <br />输入语句    输出语句 <br />} <br />输入形式    enter  x,y:  2  3.4 <br />输出形式    x+y=5.40 <br />A)scanf("%d,%f",&amp;x,&amp;y);printf("\nx+y= %4.2f",x+y); <br />B)scanf("%d%f",&amp;x,&amp;y );printf("\nx+y=%4.2f",x+y); <br />C)scanf("%d%f",&amp;x,&amp;y); printf("\nx+y=%6.lf",x+y); <br />D)scanf("%d%3.1f",&amp;x,&amp;y );printf("\nx十y=%4.2f",x+y); <br />*59 <br />D <br />以下说法正确的是: <br />A)输入项可以为一实型常量,如scanf("%f",3.5); <br />B)只有格式控制,没有输入项,也能进行正确输入,如scanf("a=%d,b=%d"); <br />C)当输入一个实型数据时,格式控制部分应规定小数点后的位数, <br />如scanf("%4.2f",&amp;f); <br />D)当输入数据时,必须指明变量的地址,如scanf("%f",&amp;f); <br />*60 <br />A <br />根据下面的程序及数据的输入方式和输出形式,程序中输入语句的正确形式应该为: <br /> main() <br />{char  ch1  ,ch2  ,ch3; <br /> 输入语句 <br />printf("%c%c%c",ch1,ch2,ch3);} <br /> 输入形式:  A B C <br /> 输出形式:  A B <br /> A)  scanf("%c%c%c",&amp;ch1,&amp;ch2,&amp;ch3); <br /> B)  scanf("%c,%c,%c", &amp;ch1,&amp;ch2, &amp;ch3); <br /> C)  scanf("%c %c %c",&amp;ch1,&amp;ch2,&amp;ch3); <br /> D)  scanf("%c%c",&amp;ch1,&amp;ch2,&amp;ch3); <br />*61 <br />D <br />有输入语句:  scanf("a= %d,b= %d,c=%d",&amp;a,&amp;b,&amp;c);为使变量a的值为1,b为3,c为2,从键盘输入数据的正确形式应当是 <br />A)132(回车) <br />B)1,3,2(回车) <br />C)a=1b=3c=2(回车) <br />D)a=1,b =3,c =2(回车) <br />*62 <br />A <br />以下能正确地定义整型变量a,b和c 并为其赋初值5的语句是 <br /> A)int a=b= c= 5;       B) int a,b, c= 5; <br /> C)a= 5,b=5,c=5;     D)  a= b= c=5; <br />*63 <br />A <br />已知ch是字符型变量,下面不正确的赋值语句是 <br />A)ch='a+b';  B)ch='\0';  C)ch='7'+'9';  D)  ch=5+9; <br />*64 <br />B <br />已知ch是字符型变量,下面正确的赋值语句是  <br />A)  ch= '123';  B)  ch= '\xff';  C)  ch= '\08';  D)  ch="\"; <br />*65 <br />B <br />若有以下定义,则正确的赋值语句是: <br /> int  a,b;float  x; <br />  A)  a=1,b=2,    B)b++;  C)  a= b= 5     D)  b= int(x); <br />*66 <br />B <br />设x 、y均为f1oat型变量,则以下不合法的赋值语句是 <br />A)++x;   B)y=(x%2)/10; C)  x*=y+8;  D)x=y=0; <br />*67 <br />A <br />x,y,z均为int型变量,则执行语句x=(y=(z=10)+5)一5;后,x 、y 和之的值是: <br />  A)  x=10    B)  x=10  C)  x=10  D)  x=10 <br />       y=15 y=10       y=10       y=5 <br />       z=10 z=10       z=15       z=10 <br />       <br />*68   <br />D   <br />逻辑运算符两侧运算对象的数据类型一一一。 <br />  A)只能是0或1 <br />  B)只能是0或非0正数 <br />  C)只能是整型或字符型数据 <br />  D)可以是任何类型的数据 <br />*69 <br />C <br />下关于运算符优先顺序的描述中正确的是一一一。 <br />A)关系运算符&lt; 算术运算符&lt; 赋值运算符&lt; 逻辑与运算符 <br />B)逻辑 运算符&lt; 关系运算符&lt; 算术运算符&lt; 赋值运算符 <br />C)赋值运算符&lt; 逻辑与运算符&lt; 关系运算符&lt; 算术运算符 <br />D)算术运算符&lt; 关系运算符&lt; 赋值运算符&lt; 逻辑与运算符 <br />*70 <br />B <br />下列运算符中优先级最高的是一一一。 <br />  A)&lt;   B)十   C)&amp;&amp;     D)!= <br />*71 <br />C <br />能正确表示"当x 的取值在[1,10]和[200,210]范围内为真,否则为假"的表达式是一一一。 <br />  A)  (x&gt;=1)  &amp;&amp;(x&lt;=10)  &amp;&amp;(x&gt; = 200)  &amp;&amp;(x&lt;=210) <br />  B)  (x&gt;=1)  || (x&lt;=10)  ||(x&gt;=200)  ||(x&lt;=210) <br />  c)  (x&gt;=1)  &amp;&amp;(x&lt;=10)||(x&gt;= 200)  &amp;&amp;(x&lt;=210) <br />  D) (x &gt; =1)||(x&lt; =10)  &amp;&amp;  (x&gt; = 200)||(x&lt;=210) <br />*72 <br />C <br />表示图中坐标轴上阴影部分的正确表达式是: <br />      /////||//////| <br />      /////||//////| <br />   -----------------------------&gt;   X <br />  a  b      c      <br />  A)(X&lt;=A)&amp;&amp;(X&gt;=B)&amp;&amp;(X&lt;=C) <br />  B) (x&lt; =a)||(b&lt;=x&lt;=c) <br />  C)(x&lt;=a)|| (x&gt; =b)  &amp;&amp;  (x&lt;=c) <br />  D)(x &lt; =a)&amp;&amp;(b&lt; = x &lt; = c) <br />*73 <br />C <br />判断char型变量ch是否为大写字母的正确表达式是一一一。 <br />  A)' A' &lt;=ch&lt;='z'     B)(ch&gt; = 'A')&amp;(ch&lt;=' z' ) <br />  C)(ch&gt;=' A' )&amp;&amp;(ch&lt;='z') D)(' A' &lt; = ch)AND('z'&gt; = ch) <br />*74 <br />D <br />设x,y 和z是int型变量,且x = 3,y= 4,z= 5,则下面表达式中值为0的是 <br />  A)'y'&amp;&amp;'y' <br />  B)x &lt; =y <br />  C) x||y+z&amp;&amp;y-z <br />  D) !(x<y)&&!z||1)><br />*75 <br />C <br />已知x =43,ch='A',y=0则表达式(x &gt; = y &amp;&amp; ch&lt;'B'&amp;&amp;!Y) 的值是 <br />   A)0   B)语法错   C)1   D)"假"   <br />*76 <br />C <br />若希望当A的值为奇数时,表达式的值为"真",A的值为偶数 表达式的值 <br />   <br />为"假"。则以下不能满足要求的表达式是: <br />A)  A%2= =1    B)!(A%2 = =0)   C)!(A%2)    D)  A%2 <br />*77 <br />B <br />设有 int a = 1,b=2,c =3, d =4, m=2, n=2; <br />       执行(m= a&gt;b)&amp;&amp;(n=c&gt;d)后n的值为: <br />    A)1B )2       C)3      D)4 <br /> *78 <br /> D      <br />判断char型变量c1是否为小写字母 正确表达式为: <br />    A)' a' &lt;=cl&lt;=' z'    B)  (cl&gt; = a)&amp;&amp;(cl&lt;=z) <br />    C)(' a' &gt;=cl)||(' z' &lt; = cl)  D)(c1&gt;='a')&amp;&amp;(cl&lt;='z') <br />*79 <br />B <br />以下程序的运行结果是: <br />   #include  "stdio.h" <br />    main()      ,,  \ <br />    {int  a,b,d= 241; <br />      a=d/100 % 9 <br />      b= (一1)&amp;&amp;(一1); <br />    printf("%d,%d",a  ,b); <br />  }  <br />  A)6,1     B)2,1     C) 6,0     D)2,0 <br />*80 <br />C <br />执行以下语句后a的值为: <br />int a,b,c; <br />a= b= c= 1; <br />++a||++b&amp;&amp;++c     <br />  A)错误    B)  0      C)  2  D)  1 <br />*81 <br />A <br /> 执行以下语句后b 的值为: <br />    int  a=5,b=6,w=1,x=2,y=3,z=4; <br />    (a=w&gt;x)&amp;&amp;(b=y&gt;z); <br />  A)  6     B)  0     C)  1      D)  4 <br />*82 <br />C <br />以下不正确的if语句形式是:    <br />  A)if(x&gt;y &amp;&amp; x!=y); <br />  B)if(x= =y)  x+=y     <br />  C)if(x != y)scanf("%d",&amp;x )else scanf("%d",&amp;y); <br />  D)if(X<y)&nbsp;{x++;y++;}><br />*83 <br />A <br />下列运算符中优先级最低的是: <br />  A)?:   B)&amp;&amp;     c)+     D)  != <br />*84 <br />B <br />以下if语句语法正确的是一一一。 <br />    A)if(x&gt;0) <br />printf("%f",x) <br />else  printf("%f",- -x); <br />    B) if (x&gt;0) <br />       {x=x+y;printf("%f",x);} <br />       else  printf("f",-x); <br />    C) if(x&gt;0) <br />       {x=x+y;  prinrf("%f",x);}; <br />       else  printf("%f",-x); <br />    D) if(x &gt; 0) <br />       { x = x +y;printf("%f",x)} <br />else  printf("%f",-x); <br />*85 <br />D <br />   <br />请阅读以下程序: <br />    main() <br />    {int  a=5,b=0,c=0;  <br />    if(a=b+c)  printf("***\n  "); <br />    e1se   printf("$$$\n"); <br />   以上程序 : <br />      A)有语法错不能通过编译   B)可以通过编译但不能通过连接 <br />      C)输出***D)输出$$$ <br />*86 <br />C <br />以下程序的运行结果是 : <br />     main()     <br />    {int m=5; <br />    if(m++&gt; 5)  printf(" %d\n",m); <br />    e1se     printf("%d\n",m- - ); <br />  } <br />  A)4    B)5   C)6    D)7 <br />*87 <br />B <br />当a=1,b=3,c=5,d=4 ,执行完下面一段程序后x 的值是 : <br />       if(a<b)><br />       if(c<d)x><br />       else <br />       if(a<c)><br />       if(b<d)x><br />       else x= 3; <br />       else x=6; <br />       else x=7; <br />      A)18)2      C)3      D)6 <br />*88 <br />C <br />以下程序的输出结果是: <br />   main() <br />  {int  a=100,x =10,y=20,okl=5,ok2=0; <br />    if  (x<y)><br />    if(y ! =10) <br />    if(!okl)  a=1; <br />   else <br />     if(ok2)  a=10; <br />      a=-1: <br />    printf( "%d\n",a ) <br />  } <br />  A)  1      B)  0    C)一1    D)值不确定 <br />*89 <br />B <br />以下程序的输出结果是: <br />      main() <br />      {int  x= 2,y= 一1,z=2; <br />if (x<y)&nbsp;><br /> if(y&lt;0)