C语言复习第二天
分支语句分析
if 语句
if语法
1、if 语句按条件选择执行语句。
2、else 总是和最近的if进行匹配。
if中的零值匹配
1、bool类型应直接出现于条件中,不用进行比较。
2、if 中与常量的比较最好常量都放在左边。
3、if中 float不能直接和0值比较,需要定义精度。
switch 语句
switch 语法
1、switch 语句用于单个条件多个分支的情况。
2、每个case后面需要加上break,不然会导致分支重叠。
3、语句中default很有必要加上,以应对特殊情况。
case 的注意点
1、case 后面匹配的只能是整形常量或者字符常量。
2、case 语句的排列顺序
--按字母或数字顺序依次排列
--正常情况放在前面,异常放在后面
--deafult只用来处理真正的默认情况。
代码示列:if 和 switch基本的使用:
#include <stdio.h>
void f1(int i)
{
if( i < 6 )
{
printf("Failed!\n");
}
else if( (6 <= i) && (i <= 8) )
{
printf("Good!\n");
}
else
{
printf("Perfect!\n");
}
}
void f2(char i)
{
switch(i)
{
case 'c':
printf("Compile\n");
break;
case 'd':
printf("Debug\n");
break;
case 'o':
printf("Object\n");
break;
case 'r':
printf("Run\n");
break;
default:
printf("Unknown\n");
break;
}
}
int main()
{
f1(5);
f1(9);
f1(7);
f2('o');
f2('d');
f2('e');
return 0;
}
代码示列:if 和switch 互换使用
#include <stdio.h>
void f1(int i)
{
switch( i < 6 )
{
case 1:
printf("Failed!\n");
break;
default:
switch( (6 <= i) && (i <= 8) )
{
case 1:
printf("Good!\n");
break;
default:
printf("Perfect!\n");
break;
}
break;
}
}
void f2(char i)
{
if( 'c' == i )
{
printf("Compile\n");
}
else if( 'd' == i )
{
printf("Debug\n");
}
else if( 'o' == i )
{
printf("Object\n");
}
else if( 'r' == i )
{
printf("Run\n");
}
else
{
printf("Unknown\n");
}
int main()
{
f1(5);
f1(9);
f1(7);
f2('o');
f2('d');
f2('e');
return 0;
}
循环语句分析
do,while for区别
1、do 语句先执行,后判断,循环最少执行一次。
2、while语句先判断再执行,循环体可能一次都不执行。
3、for语句先判断后执行。
编程示列:
#include <stdio.h>
int f1(int n)
{
int ret = 0;
if( n > 0 )
{
do
{
ret += n;
n--;
}
while( n > 0 );
}
return ret;
}
int f2(int n)
{
int ret = 0;
while( n > 0 )
{
ret += n;
n--;
}
return ret;
}
int f3(int n)
{
int ret = 0;
int i = 0;
for(i=1; i<=n; i++)
{
ret += i;
}
return ret;
}
int main()
{
printf("%d\n", f1(100));
printf("%d\n", f2(100));
printf("%d\n", f3(100));
return 0;
}
break和continue的区别
1、break退出整个循环(跳转到循环体大括号之外)。
2、continue退出本次循环。(跳转到循环体大括号之前,只有循环体能使用)
tips:continue 不能代替break,continue只能用在循环体中,否则会出现
代码示列:
结果编译错误:
goto 和void 分析
goto 分析
1、goto为从一个程序段跳到转到另外一个程序段。
2、一般禁用goto.
goto的副作用
1、跳转,破坏程序的顺序话执行。
void 分析
1、void 修饰返回值和参数
2、函数没有返回值,应将其声明为void
3、函数没有参数,应该将其声明为void,如果不写,则示意为任意参数。
4、不存在void 变量
void 指针的含义
1、C语言规定只用相同类型的指针才可以互相赋值
2、void *指针作为左值用于接收"接收"任意类型的指针。
3、void * 指针作为右值使用需要进行强制类型转换。
示列分析:
#include <stdio.h>
void MemSet(void* src, int length, unsigned char n)
{
unsigned char* p = (unsigned char*)src;
int i = 0;
for(i=0; i<length; i++)
{
p[i] = n;
}
}
int main()
{
int a[5];
int i = 0;
MemSet(a, sizeof(a), 0);
for(i=0; i<5; i++)
{
printf("%d\n", a[i]);
}
return 0;
}
const 和 volatile分析
const只读变量
1、const修饰的变量是只读,但本质还是变量。
2、const修饰的局部变量在栈上分配内存空间。
3、const修饰的全局变量在全局数据区分配空间。
4、const只在编译期有用,在运行期无用。
tips:
const修饰的变量不是真的常量,只是告诉编译器该变量不能出现赋值符号的左边。
const全局变量的分歧
1、在现在C语言编译器中,修改const全局变量将导致程序崩溃(存入只读存储区,不能修改。)------------gcc
2、标准C语言编译器不会将其存入只读存储区,其值使用一个指向它内存地址的指针仍然可以修改------------bcc。
示列程序:
#include <stdio.h>
const int g_cc = 2;
int main()
{
const int cc = 1;
int* p = (int*)&cc;
printf("cc = %d\n", cc);
*p = 3;
printf("cc = %d\n", cc);
p = (int*)&g_cc;
printf("g_cc = %d\n", g_cc);
*p = 4;
printf("g_cc = %d\n", g_cc);
return 0;
}
结果:修改全局const变量时发生段错误(使用的gcc编译器)。
const 本质分析
注意:static变量 和 全局变量 都存储在全局数据区,加以const修饰之后就就能修改其值了。
代码示列:
#include <stdio.h>
const int g_array[5] = {0};
void modify(int* p, int v)
{
*p = v;
}
int main()
{
int const i = 0;
const static int j = 0;
int const array[5] = {0};
modify((int*)&i, 1); // ok
modify((int*)&j, 2); // error:因为加入static修饰,
//其生命周期是全局,存储在全局 //区。所以修改失败。
modify((int*)&array[0], 3); // ok
modify((int*)&g_array[0], 4); // error
printf("i = %d\n", i);
printf("j = %d\n", j);
printf("array[0] = %d\n", array[0]);
printf("g_array[0] = %d\n", g_array[0]);
return 0;
}
struct 和 union分析
struct 分析
struct 在C语言中可以看作变量的集合
struct的问题
空结构体占用多大的内存?
strcut Ts
{
};
sizeof(struct Ts)=?
这个问题取绝于编译器。
1、gcc编译器编译出来的结果。
2、vc编译器会报错提示至少应该拥有一个成员。
结构体和柔性数组
1、柔性数组即数组大小待定的数组。
2、C语言可以由结构体产生柔性数组。
3、C语言中结构体的最后一个元素可以是大小未知的数组。
struct SoftArray
{
int len;
int array[];
};
sizeof(struct SoftArray)=?
tips
结果是4字节,SoftArray中的array仅是一个标识符,不占用内存空间。
柔性数组的用法
#include <stdio.h>
#include <stdlib.h>
struct SoftArray
{
int len;
int array[];
};
//create a SoftArray
struct SoftArray * create_soft_array(int size)
{
struct SoftArray *ret =NULL;
if(size>0)
{
ret=(struct SoftArray *)malloc(sizeof(struct SoftArray)+sizeof(int)*size);
ret->len=size;
}
return ret;
}
union分析
1、C语言中的union在语法上与struct相似
2、union只分配最大成员的内存空间,所有成员共享这个空间。
tips
union的使用受系统大小端的影响:
union实现的方法是内存截断,当使用内存较小的变量时,是直接将高内存地址往后的内存空间截断,所以它的使用受系统大小端的影响。
小端:小地址存放低位
大端:大地址存放地位。
判断系统大小端的做法:两种基本方法:
#include <stdio.h>
//利用union的高位地址截断的特性
int system_mode()
{
union system
{
int i;
char c;
};
union system mode;
mode.i=1;
return mode.c;
}
//定义一个char*类型的指针指向int 的低地址空间查看内存的值即可判断。
int check_cpu()
{
int i=1;
char *c =&i;
return c[0]==1;
}
int main()
{
printf(" check_cpu is %d\n",check_cpu());
printf("system mode is %d\n",system_mode());
return 0;
}
说明是小端序