第一项
C 强制类型转换
强制类型转换是把变量从一种类型转换为另一种数据类型。可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型
(type_name) expression
一个整数变量除以另一个整数变量,得到一个浮点数:
eg:
#include <stdio.h>
int main()
{
int sum = 17, count = 5;
double mean;
mean = (double) sum / count;
printf("Value of mean : %f\n", mean );
}
Value of mean : 3.400000
强制类型转换运算符的优先级大于除法,sum 的值首先被转换为 double 型,后除以 count,得到一个类型为 double 的值。
类型转换可以是隐式的,由编译器自动执行,可以是显式的,通过使用强制类型转换运算符来指定。
整数提升
把小于 int 或 unsigned int 的整数类型转换为 int 或 unsigned int 的过程。
eg:
#include <stdio.h>
int main()
{
int i = 17;
char c = 'c'; /* ascii 值是 99 */
int sum;
sum = i + c;
printf("Value of sum : %d\n", sum );
}
Value of sum : 116
sum 的值为 116,编译器进行了整数提升,实际加法运算时,把 'c' 的值转换为对应的ASCII值。
常用的算术转换
隐式地把值强制转换为相同的类型。编译器先执行整数提升,操作数类型不同,会被转换为下列层次中出现的最高层次的类型:
常用的算术转换不适用于赋值运算符、逻辑运算符 && 和 ||。让我们看看下面的实例来理解这个概念:
eg:
#include <stdio.h>
int main()
{
int i = 17;
char c = 'c'; /* ascii 值是 99 */
float sum;
sum = i + c;
printf("Value of sum : %f\n", sum );
}
Value of sum : 116.000000
c 首先被转换为整数,由于最后的值是 float 型的,应用常用的算术转换,编译器会把 i 和 c 转换为浮点型,并把它们相加得到一个浮点数。
第二项
C 错误处理
C 语言不提供对错误处理的直接支持,而是以返回值的形式允许您访问底层数据。在发生错误时,调用返回 1 或 NULL,同时会设置一个错误代码 errno(该错误代码是全局变量,表示在函数调用期间发生了错误)。
可以在 errno.h 头文件中找到各类错误代码。
errno、perror() 和 strerror()
perror() 和 strerror() 函数显示与 errno 相关的文本消息。
- perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。
- strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。
eg:
#include <stdio.h>
#include <errno.h>
#include <string.h>
extern int errno ;
int main ()
{
FILE * pf;
int errnum;
pf = fopen ("unexist.txt", "rb");
if (pf == NULL)
{
errnum = errno;
fprintf(stderr, "错误号: %d\n", errno);
perror("通过 perror 输出错误");
fprintf(stderr, "打开文件错误: %s\n", strerror( errnum ));
}
else
{
fclose (pf);
}
return 0;
}
错误号: 2 通过 perror 输出错误: No such file or directory 打开文件错误: No such file or directory
被零除的错误
在进行除法运算时,不检查除数是否为零,会导致一个运行时错误。
进行除法运算前会先检查除数是否为零:
eg:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dividend = 20;
int divisor = 0;
int quotient;
if( divisor == 0){
fprintf(stderr, "除数为 0 退出运行...\n");
exit(-1);
}
quotient = dividend / divisor;
fprintf(stderr, "quotient 变量的值为 : %d\n", quotient );
exit(0);
}
除数为 0 退出运行...
程序退出状态
程序成功执行完一个操作,正常退出时,会带有值 EXIT_SUCCESS。在这里,EXIT_SUCCESS 是宏,被定义为 0。
程序中存在一种错误情况,退出程序时,会带有状态值 EXIT_FAILURE,被定义为 -1。
eg:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int dividend = 20;
int divisor = 5;
int quotient;
if( divisor == 0){
fprintf(stderr, "除数为 0 退出运行...\n");
exit(EXIT_FAILURE);
}
quotient = dividend / divisor;
fprintf(stderr, "quotient 变量的值为: %d\n", quotient );
exit(EXIT_SUCCESS);
}
quotient 变量的值为 : 4
第三项
C 递归
递归指的是在函数的定义中使用函数自身的方法。
void recursion() { statements; ... ... ... recursion(); /* 函数调用自身 */ ... ... ... } int main() { recursion();
在使用递归时,需要注意定义一个从函数退出的条件,否则会进入死循环。
递归函数用于解决许多数学问题:
数的阶乘
下面的实例使用递归函数计算一个给定的数的阶乘:
eg:
#include <stdio.h>
double factorial(unsigned int i)
{
if(i <= 1)
{
return 1;
}
return i * factorial(i - 1);
}
int main()
{
int i = 15;
printf("%d 的阶乘为 %f\n", i, factorial(i));
return 0;
}
15 的阶乘为 1307674368000.000000
斐波那契数列
使用递归函数生成一个给定的数的斐波那契数列:
eg:
#include <stdio.h>
int fibonaci(int i)
{
if(i == 0)
{
return 0;
}
if(i == 1)
{
return 1;
}
return fibonaci(i-1) + fibonaci(i-2);
}
int main()
{
int i;
for (i = 0; i < 10; i++)
{
printf("%d\t\n", fibonaci(i));
}
return 0;
}
0 1 1 2 3 5 8 13 21 34
第四项
C 可变参数
您定义一个函数,能根据具体的需求接受可变数量的参数。
int func_name(int arg1, ...);
省略号 ... 表示可变参数列表。
int func
(int, ... ) { . . . } int main() { func(2, 2, 3); func(3, 2, 3, 4); }
函数 func() 最后一个参数写成省略号(...),省略号之前的那个参数是 int,代表了要传递的可变参数的总数。为了使用这个功能,您需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏。具体步骤如下:
- 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。
- 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
- 使用 int 参数和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。
- 使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。
- 使用宏 va_end() 来清理赋予 va_list 变量的内存。
常用的宏有:
-
va_start(ap, last_arg)
:初始化可变参数列表。ap
是一个va_list
类型的变量,last_arg
是最后一个固定参数的名称(也就是可变参数列表之前的参数)。该宏将ap
指向可变参数列表中的第一个参数。 -
va_arg(ap, type)
:获取可变参数列表中的下一个参数。ap
是一个va_list
类型的变量,type
是下一个参数的类型。该宏返回类型为type
的值,并将ap
指向下一个参数。 -
va_end(ap)
:结束可变参数列表的访问。ap
是一个va_list
类型的变量。该宏将ap
置为NULL
。
现在让我们按照上面的步骤,来编写一个带有可变数量参数的函数,并返回它们的平均值:
eg:
#include <stdio.h>
#include <stdarg.h>
double average(int num,...)
{
va_list valist;
double sum = 0.0;
int i;
/* 为 num 个参数初始化 valist */
va_start(valist, num);
/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* 清理为 valist 保留的内存 */
va_end(valist);
return sum/num;
}
int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}
average() 函数接受一个整数 num 和任意数量的整数参数。函数内部使用 va_list 类型的变量 va_list 来访问可变参数列表。循环中,每次使用 va_arg() 宏获取下一个整数参数,输出。函数结束时使用 va_end() 宏结束可变参数列表的访问。
Average of 2, 3, 4, 5 = 3.500000 Average of 5, 10, 15 = 10.000000
average()函数 被调用两次,每次第一个参数都是表示被传的可变参数的总数。省略号被用来传递可变数量的参数。