课程3——程序结构关键字
声明:本系列随笔主要用于记录c语言的常备知识点,不能保证所有知识正确性,欢迎大家阅读、学习、批评、指正!!你们的鼓励是我前进的动力。严禁用于私人目的。转载请注明出处:http://www.cnblogs.com/myblesh/
c语言中常用的控制关键字主要有if、switch、do、 while、for,extern,goto,const等;
1.if
基本概念: if语句用于根据条件选择执行语句,else不能独立存在且总是与它距离最近的if相匹配,else语句可以连接其他if语句。

注意点:if语句中与零值比较
(1) bool类型变量应该直接出现于条件中,不要进行比较(因为在c语言中是没有bool型的,bool往往是是编译器用枚举变量定义的;此外 0表示fasle,非0表示true);参看示例代码1
(2) 普通变量与0值(常量数值)比较时,0值(常量数值)出现在比较符号左(工程经验,编程习惯)
(3) float类型变量不能直接和0值比较,需要定义精度;参看示例代码2

示例代码1:

 
#include <stdio.h> typedef enum _bool
{
FALSE = 0,
TRUE = -1
}BOOL; int main()
{
BOOL b = TRUE;
if (b == true) //if (b == 1)
{
printf("Ok\n");
}
else
{
printf("ERROR\n");
}
return 0;
}
示例代码2:

 
#include <stdio.h> #define E 0.00000001 int main()
{
float f = 5.0;
if (((5-E) <= f) && (f <= (5 + E)))
{
printf("ok\n");
}
else
{
printf("error\n");
}
return 0;
}
2.switch
switch对应单个条件,多个分支的情形,每个case语句分支必须要有break,否则导致分支重叠,default语句有必要加上以处理特殊情况。

Note:case语句中的值只能是整型或字符型
3.If 和 Switch 分支语句比较
if实用于 需要“按片”或范围进行判断的情形
switch实用于 需要对各个离散值进行分别判断的情形
if从功能上可以取代switch,但switch不能代替if,switch对于多分支情形判断的情况更简洁。
4.循环语句
工作方式:通过条件表达式判定是否执行循环体;条件表达式遵循if语句表达式的原则。
do while for区别:
do语句先执行后判断,循环体至少执行一次;
while语句先判定后执行,循环体可能不执行;
for语句先判定后执行,相比while更简洁些;
示例代码3:

 
// 三种循环语句使用对比 // 累加自然数
#include <stdio.h> int f1(int n)
{
int ret = 0;
int i = 0; for(i=1; i<=n; i++)
{
ret += i;
} return ret;
} int f2(int n)
{
int ret = 0; while( (n > 0) && (ret += n--) ); return ret;
} int f3(int n)
{
int ret = 0; if( n > 0 )
{
do
{
ret += n--;
}while( n );
} return ret;
} int main()
{
printf("%d\n", f1(10));
printf("%d\n", f2(10));
printf("%d\n", f3(10));
}
5. break 和continue的区别
break表示终止循环(可以是0次或1次以上)的执行;可以理解为跳出一个程序“块”。
continue 表示终止本次循环体,进入下一次循环执行。
问题:switch能否中使用continue?
答案:不能。在程序设计中,存在三种语句执行顺序。顺序结构,分支结构,循环结构。switch不是循环控制语句,而是属于程序的分支结构。continue可以跳出循环结构进入下一次循环,break可以跳出分支、循环结构(一个程序“块”)。
6. do 和 break妙用体现函数设计思想
关于函数设计的思想可以参考函数专题一节,这里的代码示例最主要的思想:一个入口,一个出口原则。防止内存泄露。
示例代码4:

 
#include <stdio.h>
#include <malloc.h> int func(int n)
{
int i = 0;
int ret = 0;
// 从堆空间分配一片内存
int* p = (int*)malloc(sizeof(int) * n); do
{
if( NULL == p ) break; // 跳出本次循环,而不是返回 if( n < 0 ) break; // 跳出本次循环,而不是返回 for(i=0; i<n; i++)
{
p[i] = i;
printf("%d\n", p[i]);
} ret = 1;
}while(0); // 从堆空间释放已分配的内存空间
free(p); return ret;
} int main()
{
if( func(10) )
{
printf("OK");
}
else
{
printf("ERROR");
}
}
7. goto使用
在实际项目开发经验中,我们一般是不用goto语句跳转,因为goto会打乱我们的程序结构化设计思想。不过,在linux的源码中常见goto是个例外。
8.void的意义
修饰函数返回值和参数,仅仅表示无
不存在void类型变量,即c语言中没有定义究竟void是多大内存的别名;
没有void的标尺,无法在内存中裁剪出void对应的变量;
void 指针的意义:
1.void * 作为左值接受任意类型的指针;
2.void * 作为右值赋值给其它指针需要做类型强制转换
9.extern的使用
1.extern用于声明外部定义的函数和变量;
2.“告诉”编译器用c语言方式实现;
  
10.sizeof是什么?
1.是编译器的内置指示符,不是函数;
2.“计算”相应实体所占内存的大小
3.sizeof的值在编译期间就已经确定
示例代码5
#include <stdio.h> int main()
{
int a; printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);
printf("%d\n", sizeof(int)); return 0;
}
11.const
const修饰变量
1.const修饰的变量是只读的,其本质还是变量
2.const只对编译器有用,在运行时无用
const修饰数组
1.const修饰的数组是只读的
2.const修饰的数组空间不可被改变
const修饰指针

const修饰函数参数和返回值
1.修饰函数参数表示在函数体内不改变参数的值
2.修饰函数返回值表示返回值不可被改变,多用于返回指针的情形
12. volatile 总结
1.可以理解为“编译器警告指示字”;
2.告诉编译器每次去内存中取变量值
3.修饰可能被多个线程访问或可能被未知因素更改的变量
具体关于volatile的分析参考http://www.cnblogs.com/myblesh/articles/2890901.html
13.结构体struct和union
思考:空结构体占据多大内存????下面程序的输出结果?

柔性数组
1.由结构体产生的,即数组大小待定的数组
2.c语言中规定结构体中的最后一个元素可以是大小未知的数组
3.由结构体产生的柔性数组定义如下:
struct SoftArray
{
int len;
int arr[];
};
使用柔性数组实现婓波拉次数列
#include <stdio.h>
#include <malloc.h> typedef struct _soft_array
{
int len;
int array[];
}SoftArray; SoftArray* create_soft_array(int size)
{
SoftArray* ret = NULL; if( size > 0 )
{
ret = (SoftArray*)malloc(sizeof(*ret) + sizeof(*(ret->array)) * size); ret->len = size;
} return ret;
} void fac(SoftArray* sa)
{
int i = 0; if( NULL != sa )
{
if( 1 == sa->len )
{
sa->array[0] = 1;
}
else
{
sa->array[0] = 1;
sa->array[1] = 1; for(i=2; i<sa->len; i++)
{
sa->array[i] = sa->array[i-1] + sa->array[i-2];
}
}
}
} void delete_soft_array(SoftArray* sa)
{
free(sa);
} int main()
{
int i = 0;
SoftArray* sa = create_soft_array(10); fac(sa); for(i=0; i<sa->len; i++)
{
printf("%d\n", sa->array[i]);
} delete_soft_array(sa); return 0;
}
  struct 和union的区别
    1.struct中的每个域在内存中都独立分配空间
2.union只分配最大域的空间,其他域共享该空间
思考:如何判断系统大小端模式????
小端:较高的有效字节存放在较高的的存储器地址,较低的有效字节存放在较低的存储器地址。
    大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址

14.enum枚举类型
1.enum是一种自定义类型;
2.enum默认常量在前一个值的基础上依次加1;
3.enum类型的变量只能取定义时的离散值,变量类型是int;
4.枚举常量是真正意义上的常量,这与const修饰的变量不同(只读),枚举常量是一种特定类型的常量
15.typedef的意义
思考:typedef的具体意义?
1.用于给已存在的数据类型重命名,而不是定义一种新的数据类型
2.并没有产生新的类型
3.重定义的数据类型不能进行unsigned和sighed的扩展
16.typedef和#define的区别
typedef是给已存在类型取别名;
#define是替换,无别名概念;

答案:p1 和p2 p3 是指向字符串类型的指针,p4是字符类型的变量
课程3——程序结构关键字的更多相关文章
- Go语言基础之1--标识符、关键字、变量和常量、数据类型、Go的基本程序结构、Golang的特性
		一.前言 当我们项目较为简单时,我们在src目录下新建一个该项目目录,里面存放源码文件即可,见下图: 当我们一个项目较为复杂时,我们可以在src目录下新建一个该项目目录,在针对该项目不同模块创建不同目 ... 
- C++程序结构---1
		C++ 基础教程Beta 版 原作:Juan Soulié 翻译:Jing Xu (aqua) 英文原版 本教程根据Juan Soulie的英文版C++教程翻译并改编. 本版为最新校对版,尚未定稿.如 ... 
- ecshop在线手册前言及程序结构
		该在线手册是有模版堂转载而来:仅供参考 一.前言 为什么我们ecshop模板堂要重制ecshop在线手册呢?因为目前网上的一些教程有些是比较老的,有些是不全面的,官方的手册也已经很久没有更 新,很多刚 ... 
- C#学习笔记二:C#程序结构
		从最简单的HelloWorld开始入手,这是一个最低限度的C#程序结构. C# Hello World 示例 一个C#程序主要由以下几部分组成: 命名空间声明 一个类 类方法 类属性 一个Main方法 ... 
- Verilog HDL的程序结构及其描述
		这篇博文是写给要入门Verilog HDL及其初学者的,也算是我对Verilog HDL学习的一个总结,主要是Verilog HDL的程序结构及其描述,如果有错,欢迎评论指出. 一.Verilog ... 
- c# 程序结构
		最近工作中需要用到c#,所以从今天开始博客不定期更新c#学习笔记 c#程序结构大体分为, 命名空间 类 Main 方法 命名空间 相当于一个仓库 通过 using 引入命名空间 比如 using ... 
- C/C++语言简介之程序结构
		C语言的模块化程序结构用函数来实现,即将复杂的C程序分为若干模块,每个模块都编写成一个C函数,然后通过主函数调用函数及函数调用函数来实现一大型问题的C程序编写,因此常说:C程序=主函数+子函数.因此, ... 
- Python学习笔记(Ⅰ)——Python程序结构与基础语法
		作为微软的粉丝,最后终于向Python低头了,拖了两三个月终于下定决心学习Python了.不过由于之前受到C/C#等语言影响的思维定式,前期有些东西理解起来还是很费了些功夫的. 零.先抄书: 1.Py ... 
- GO语言的进阶之路-go的程序结构以及包简介
		GO语言的进阶之路-go的程序结构以及包简介 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.编辑,编译和运行 A,编辑 Go程序使用UTF-8编码的纯Unicode文本编写.大 ... 
随机推荐
- Android代码混淆官方实现方法
			首先查看一下 “project.properties” 这个文件: # This file is automatically generated by Android Tools.# Do not m ... 
- Spring概述
			layout: post title: Spring概述 tags: [Java,Spring,IOC,AOP] --- Spring是一个开源的轻量级Java SE(Java 标准版本)/Java ... 
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄
			前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传. 在实际开发中,输入输出流用的比较少,但 ... 
- Cocos2d-x 基础元素
			看过本章,然后实践之后,应该会掌握以下的认识: 1.Cocos2d-x引擎的基本运转过程 2.Cocos2d-x引擎的一些初始设置 3.对导演及图层及现实对象的认识 4.如何定义自己的显示对象 *:f ... 
- C++中static用法总结
			1用于局部变量 C++中局部变量有三种: (1)auto:此关键词常常省略.auto type a 常常简写为type a. 如: int a=auto int a 存储在内存的栈中,只在此局部区域有 ... 
- 我眼中的自己ps:自我介绍
			我是一个理科生,学的是计算机科学与技术专业,目前在桂林理工大学信息科学与工程学院就读.我心里不是很喜欢这个专业,但是因为当初的某种原因就入了这个门.自从学习了计算机以后,我发现这个专业可谓“博大精深, ... 
- "ORA-12154: TNS:could not resolve the connect identifier specified"的解决办法
			添加环境变量解决: 变量名:TNS_ADMIN 变量值:D:\Ocl\product\11.2.0\dbhome_1\NETWORK\ADMIN tnsnames.ora所在的路径 
- 为 Virtual Box 中的 CentOS 6.6 配置本地DVD光盘做yum软件源
			因为virtual box 中的centos配置host-only共享win7上网,配置失败,所以只能使用Centos的 DVD 光盘来配置yum软件源.不然就没得完了. 1. 首先要在virtual ... 
- poj 3237 Tree [LCA] (树链剖分)
			poj 3237 tree inline : 1. inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高. 2. 很明显,类 ... 
- C++STL之迭代器2
			在学习c++ STL的时候,整天碰到迭代器,也整天用,但是,到底它是个什么东西,很多人没有一个认识.这里我通过几个小的DEMO,来看看迭代器.首先我实现了一个十分简陋的vector类: templat ... 
