欢迎来到冰点文库! | 帮助中心 分享价值,成长自我!
冰点文库
全部分类
  • 临时分类>
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • ImageVerifierCode 换一换
    首页 冰点文库 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    C语言常见问题.docx

    • 资源ID:8916515       资源大小:27.72KB        全文页数:24页
    • 资源格式: DOCX        下载积分:3金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要3金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    C语言常见问题.docx

    1、C语言常见问题 1 C 本章主要描述C 语言一些基本要素。当你开始编写C 程序 时,你可能对C 语言的一些基本问题感到困惑,如C 语言所使 用的约定、关键字和术语等。本章将回答这方面你经常会遇到 的一些问题。 例如,switch 语句是最常用的一种C 语言构件,本章将回答 与它有关的三个常见问题。本章还涉及其它几个问题,如循环、 分支、运算符的优先级和程序块技术。在阅读本章时,请注意 有关switch 语句和运算符优先级的一些问题,这些问题常常会 使C 语言的初学者感到迷惑。 11 什么是局部程序块(local block)? 局部程序块是指一对大括号()之间的一段C 语言程序。一 个C 函数

    2、包含一对大括号,这对大括号之间的所有内容都包含 在一个局部程序块中。if 语句和swich 语句也可以包含一对大括 号,每对大括号之间的代码也属于一个局部程序块。此外,你 完全可以创建你自己的局部程序块,而不使用C 函数或基本的 C 语句。你可以在局部程序块中说明一些变量,这种变量被称 为局部变量,它们只能在局部程序块的开始部分说明,并且只 在说明它的局部程序块中有效。如果局部变量与局部程序块以 外的变量重名,则前者优先于后者。下面是一个使用局部程序 块的例子: #include void main(void); void main() / * Begin local block for fu

    3、nction main() * / int test_ var = 10; printf(Test variable before the if statement: %dn, test_var); if (test_var5) / * Begin local block for if statement * / int test_ var = 5; printf(Test variable within the if statement: %dn, test_var); / * Begin independent local block (not tied to any function o

    4、r keyword) * / int test_var = 0; printf ( Test variable within the independent local block: %dn, test_var) / * End independent local block * / printf (Test variable after the if statement: %dn, test_var); /*End local block for function main () * / 上例产生如下输出结果: Test variable before the if statement: 1

    5、0 Test variable within the if statement: 5 Test variable within the independent local block:0 Test variable after the if statement: 10 注意,在这个例子中,每次test_var 被定义时,它都要优先 于前面所定义的test_var 变量。此外还要注意,当if 语句的局部 程序块结束时,程序重新进入最初定义的test_var 变量的作用范 围,此时test_var 的值为10。 请参见: 12 可以把变量保存在局部程序块中吗? 12 可以把变量保存在局部程序块中吗

    6、? 用局部程序块来保存变量是不常见的,你应该尽量避免这样 做,但也有极少数的例外。例如,为了调试程序,你可能要说 明一个全局变量的局部实例,以便在相应的函数体内部进行测 试。为了使程序的某一部分变得更易读,你也可能要使用局部 程序块,例如,在接近变量被使用的地方说明一个变量有时就 会使程序变得更易读。然而,编写得较好的程序通常不采用这 种方式来说明变量,你应该尽量避免使用局部程序块来保存变 量。 请参见: 11 什么是局部程序块? 13 什么时候用一条switch 语句比用多条if 语句更好? 如果你有两个以上基于同一个数字(numeric)型变量的条件表 达式,那么最好使用一条switch

    7、语句。例如,与其使用下述代 码: if (x =l) printf (x is equal to one. n); else if (x =2) printf (x is equal to two. n); else if (x = =3) printf (x is equal to three. n); else printf (x is not equal to one, two, or three. n); 不如使用下述代码,它更易于阅读和维护: switch (x) case 1: printf (x is equal to one. n); break; case 2: printf

    8、 (x is equal to two. n); break case 3: printf (x is equal to three. n); break; default: printf (x is not equal to one, two, or three. n); break; 注意,使用switch 语句的前提是条件表达式必须基于同一个 数字型变量。例如,尽管下述if 语句包含两个以上的条件,但 该例不能使用switch 语句,因为该例基于字符串比较,而不是 数字比较: char *name=Lupto; if(!stricmp(name,Isaac) printf(Your na

    9、me meansLaughtern); else if(!stricmp(name,Amy) printf(Your name meansBelovedn); else if(!stricmp(name,Lloyd) printf(Your name meansMysteriousn); else printf(I havent a clue as to what your name meansn); 请参见: 14 switch 语句必须包含default 分支吗7 15 switch 语句的最后一个分支可以不要break 语句吗? 1. 4 switch 语句必须包含default 分支吗

    10、? 不,但是为了进行错误检查或逻辑检查,还是应该在switch 语句中加入default 分支。例如,下述switch 语句完全合法: switch (char_code) case tyt: case y: printf ( You answered YES ! n ) break case N: case n: printf (You answered NO!n); break 但是,如果一个未知字符被传递给这条switch 语句,会出现什 么情况呢?这时,程序将没有任何输出。因此,最好还是加入一 个default 分支,以处理这种情况: default: printf (Unknown

    11、response : %dn, char_code); break 此外,default 分支能给逻辑检查带来很多方便。例如,如果用 switch 语句来处理数目固定的条件,而且认为这些条件之外的 值都属于逻辑错误,那么可以加入一个default 分支来辨识逻辑 错误。请看下列: void move_cursor (int direction) switch (direction) case UP: cursor_up() break case DOWN: cursor_down() break case LEFT: cursor_left () break case RIGHT: curso

    12、r_ right ( ) break default: printf (Logic error on line number %ld! n, _ LINE_ ) break 请参见: 13 什么时候用一条switch 语句比用多条if 语句更好? 15 Switch 语句的最后一个分支可以不要break 语句吗? 15 switch 语句的最后一个分支可以不要break 语句吗? 尽管switch 语句的最后一个分支不一定需要break 语句,但 最好还是在switch 语句的每个分支后面加上break 语句,包括 最后一个分支。这样做的主要原因是:你的程序很可能要让另 一个人来维护,他可能要

    13、增加一些新的分支,但没有注意到最 后一个分支没有break 语句,结果使原来的最后一个分支受到其 后新增分支的干扰而失效。在每个分支后面加上break 语句将防 止发生这种错误并增强程序的安全性。此外,目前大多数优化 编译程序都会忽略最后一条break 语句,所以加入这条语句不会 影响程序的性能。 请参见: 1. 3 什么时候用一条switch 语句比用多条if 语句更好? 1. 4 switch 语句必须包含default 分支吗? 1. 6 除了在for 语句中之外,在哪些情况下还要使用逗号运算符? 逗号运算符通常用来分隔变量说明、函数参数、表达式以及 for 语句中的元素。下例给出了使用

    14、逗号的多种方式: #include #include void main(void); void main () / * Here, the comma operator is used to separate three variable declarations. * / int i, j, k; / * Notice how you can use the comma operator to perform multiple initializations on the same line. * / i=0, j=1, k=2; printf(i= %d, j=%d, k= %dn, i

    15、, j, k); / * Here, the comma operator is used to execute three expressions in one line: assign k to i, increment j, and increment k. The value that i receives is always the rigbtmost expression. * / i= ( j+, k+ ); printf(i=%d, j=%d, k=%dn, i, j, k); / * Here, the while statement uses the comma opera

    16、tor to assign the value of i as well as test it. * / while (i=(rand() % 100), i !=50) printf(i is %d, trying again n, i) printf (nGuess what? i is 50!n ) 请注意下述语句: i:(j+,k+) 这条语句一次完成了三个动作,依次为: (1)把k 值赋给i。这是因为左值(lvaule)总是等于最右边的参 数,本例的左值等于k。注意,本例的左值不等于k+,因为 k+是一个后缀自增表达式,在把k 值赋给j 之后k 才会自增。 如果所用的表达式是+k,则

    17、+k 的值会被赋给i,因为+k 是 一个前缀自增表达式,k 的自增发生在赋值操作之前。 (2)j 自增。 (3)k 自增。 此外,还要注意看上去有点奇怪的while 语句: while (i=(rand() % 100), i !=50) printf(i is %d, trying again n); 这里,逗号运算符将两个表达式隔开,while 语句的每次循环 都将计算这两个表达式的值。逗号左边是第一个表达式,它把0 至99 之间的一个随机数赋给i;第二个表达式在while 语句中更 常见,它是一个条件表达式,用来判断i 是否不等于50。while 语句每一次循环都要赋予i 一个新的随机数

    18、,并且检查其值是否 不等于50。最后,i 将被随机地赋值为50,而while 语句也将结 束循环。 请参见: 112 运算符的优先级总能保证是“自左至右”或“自右至左” 的顺序吗? 113 +var 和var+有什么区别? 17 怎样才能知道循环是否提前结束了? 循环通常依赖于一个或多个变量,你可以在循环外检查这些 变量,以确保循环被正确执行。请看下例: int x char * cpREQUESTED_BLOCKS / * Attempt (in vain, I must add )to allocate 512 10KB blocks in memory. * / for (x = 0;

    19、xREQUESTED_ BLOCKS ; x+ ) cpix= (char * ) malloc (10000,1) if (cpx= = (char * ) NULL) break / * If x is less than REQUESTED-BLOCKS, the loop has ended prematurely. * / if (xREQUESTED_BLOCKS) printf (Bummer ! My loop ended prematurely ! n ); 注意,如果上述循环执行成功,它一定会循环512 次。紧接着 循环的if 语句用来测试循环次数,从而判断循环是否提前结束

    20、。 如果变量x 的值小于512,就说明循环出错了。 18 goto,longjmp()和setjmp()之间有什么区别? goto 语句实现程序执行中的近程跳转(local jump),longjmp() 和setjmp()函数实现程序执行中的远程跳转(nonlocaljump,也叫 farjump)。通常你应该避免任何形式的执行中跳转,因为在程序 中使用goto 语句或longjmp()函数不是一种好的编程习惯。 goto 语句会跳过程序中的一段代码并转到一个预先指定的位 置。为了使用goto 语句,你要预先指定一个有标号的位置作为 跳转位置,这个位置必须与goto 语句在同一个函数内。在不

    21、同 的函数之间是无法实现goto 跳转的。下面是一个使用goto 语句 的例子: void bad_programmers_function(void) int x printf(Excuse me while I count to 5000 n) ; x-l while (1) printf( %dn, x) if (x =5000) goto all_done else x=x+1; all_done: prinft(Whew! That wasnt so bad, was it?n); 如果不使用goto 语句,是例可以编写得更好。下面就是一个改 进了实现的例子: void better

    22、_function (void) int x printf(Excuse me while I count to 5000 n); for (x=1; x=5000, x+) printf( %dn, x) printf(Whew! That wasnt so bad, was it?n) ; 前面已经提到,longjmp()和setjmp()函数实现程序执行中的远 程跳转。当你在程序中调用setjmp()时,程序当前状态将被保存 到一个jmp_buf 类型的结构中。此后,你可以通过调用longjmp() 函数恢复到调用setjmp()时的程序状态。与goto 语句不同, longjmp()和

    23、setjmp()函数实现的跳转不一定在同一个函数内。然 而,使用这两个函数有一个很大的缺陷,当程序恢复到它原来 所保存的状态时,它将失去对所有在longjmp()和setjmp()之间 动态分配的内存的控制,也就是说这将浪费所有在longjmp()和 setjmp()之间用malloc()和calloc()分配所得的内存,从而使程序 的效率大大降低。因此,你应该尽量避免使用longjmp()和setjmp() 函数,它们和goto 语句一样,都是不良编程习惯的表现。 下面是使用longjmp()函数和setjmp()函数的一个例子: #include #include jmp_buf save

    24、d_state; void main(void); void call_ longjmp (void); void main(void) int ret_code; printf(The current state of the program is being saved n); ret_code = setjmp (saved_state) if (ret_code =1) printf(The longjmp function has been called. n ) printf(The programs previous state has been restored. n); ex

    25、it(0) printf(I am about to call longjmp andn); printf(return to the previous program state n ) call_ longjmp ( ) void call_longjmp (void) longjmp (saved_state, 1 ) 19 什么是左值(lvaule)? 左值是指可以被赋值的表达式。左值位于赋值语句的左侧, 与其相对的右值(rvaule,见 111)则位于赋值语句的右侧。每 条赋值语句都必须有一个左值和一个右值。左值必须是内存中 一个可存储的变量,而不能是一个常量。下面给出了一些左值 的

    26、例子: int x; int *p_int; x=1; p_int=5; 变量x 是一个整数,它对应于内存中的一个可存储位置,因此, 在语句“x1”中,x 就是一个左值。注意,在第二个赋值语句 “*p_int5中,通过“*”修饰符访问p_int 所指向的内存区域; 因此,p_int 是一个左值。相反,下面的几个例子就不是左值: #define CONST_VAL 10 int x /* example 1 * / l=x; / * example 2 * / CONST_VAL = 5; 在上述两条语句中,语句的左侧都是一个常量,其值不能改变, 因为常量不表示内存中可 存储的位置。因此,这两条

    27、赋值语句中没有左值,编译程序会 指出它们是错误的。 请参见: 1. 10 数组(array)可以是左值吗? 1. 11 什么是右值(rvaule)? 110 数组(array)可以是左值吗? 在19 中,左值被定义为可被赋值的表达式。那么,数组是 可被赋值的表达式吗?不是,因为数组是由若干独立的数组元素 组成的,这些元素不能作为一个整体被赋值。下述语句是非法 的: int x5,y5; x=y; 不过,你可以通过for 循环来遍历数组中的每个元素,并分 别对它们赋值,例如: int i; int x5; int y5; for(i=0; i5,i+) xiyi; 此外,你可能想一次拷贝整个数组

    28、,这可以通过象memcpy() 这样的函数来实现,例如: memcpy(x,y,sizeof(y); 与数组不同,结构(structure)可以作为左值。你可以把一个结 构变量赋给另一个同类型的结构变量,例如: typedef struct t_name charlast_name25; char first_name15; char middle-init 2; NAME NAME my_name, your_name; your_name = my_name; 在上例中,结构变量my_name 的全部内容被拷贝到结构变量 your_name 中,其作用和下述语句是相同的: memcpy(your_name,my_name,sizeof(your_name); 请参见: 19 什么是左值(lvaule)? 111 什么是右值(rvaule)? 111 什么是右值(rvaule)? 在19 中,左值被定义为可被赋值的表达式,你也可以认为 左值是出现在赋值语句左边的表达式。这样,右值就可以被定 义为能赋值的表达式,它出现在赋值语句的右边。与左值不同,


    注意事项

    本文(C语言常见问题.docx)为本站会员主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2023 冰点文库 网站版权所有

    经营许可证编号:鄂ICP备19020893号-2


    收起
    展开