Hello World 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> int main () { printf ("hello world" ); return 0 ; } gcc hello.c ./a.out
C语言数据类型
字符型(char):描述单个字符(一个字节),用半角的单引号包含起来,如’a’、’A’、’1’、’$’等,键盘能输入的英文和半角的符号都是字符。中文的汉字和标点符号是两个字节(GBK编码),不能算一个字符。
整型(int):描述整数。
浮点型(float):描述实数。
字符串:描述多个字符,用半角的双引号包含起来,可以是英文、数字、中文、标点符号,半角全角的都可以。
结构体(struct):由基本类型通过一定的构造方法构造出来的类型,包括数组和结构体。
指针类型:指针可以存放内存变量和常量地址。
其他类型:如复数类型(_Complex)、虚数类型(_Imaginary)、布尔型(_bool)等。
变量 变量的命名 变量名属于标识符,需要符合标识符的命名规范,具体如下:
变量名的第一个字符必须是字母或下划线,不能是数字和其它字符。
变量名中的字母是区分大小写的。比如a和A是不同的变量名,num和Num也是不同的变量名。
变量名绝对不可以是C语言的关键字。
变量的定义和初始化 变量在定义后,操作系统为它分配了一块内存,但并不会把这块内存打扫干静,也就是说内存中可能有垃圾数据,建议在使用之间对其初始化(打扫干静)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 int ii; char cc; double money; char name[21 ]; int ii=0 ; char cc=0 ; double money=0 ; int ii; char cc; double money; ii=0 ; cc=0 ; money=0 ; char name[21 ]; memset (name,0 ,sizeof (name)); const double pi = 3.1415926 ;
C语言中的关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 auto :声明自动变量break :跳出当前循环case :开关语句分支char :声明字符型变量或函数返回值类型const :声明只读变量continue :结束当前循环,开始下一轮循环default :开关语句中的“默认”分支do :循环语句的循环体double :声明双精度浮点型变量或函数返回值类型else :条件语句否定分支(与if 连用)enum :声明枚举类型extern :声明变量或函数是在其它文件或本文件的其他位置定义float :声明浮点型变量或函数返回值类型for :一种循环语句goto :无条件跳转语句if :条件语句int :声明整型变量或函数long :声明长整型变量或函数返回值类型register :声明寄存器变量return :子程序返回语句(可以带参数,也可不带参数)short :声明短整型变量或函数signed :声明有符号类型变量或函数sizeof :计算数据类型或变量长度(即所占字节数)static :声明静态变量struct :声明结构体类型switch :用于开关语句typedef :用以给数据类型取别名unsigned :声明无符号类型变量或函数union :声明共用体类型void :声明函数无返回值或无参数,声明无类型指针volatile :说明变量在程序执行中可被隐含地改变while :循环语句的循环条件
输入和输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 getchar:输入单个字符,保存到字符变量中。 gets:输入一行数据,保存到字符串变量中。 scanf :格式化输入函数,一次可以输入多个数据,保存到多个变量中。putchar :输出单个字符。puts :输出字符串。printf :格式化输出函数,可输出常量、变量等。int age=18 ;char xb='x' ;double weight=62.5 ;char name[21 ];memset (name,0 ,sizeof (name));strcpy (name, "西施" );printf ("我的姓名是:%s,姓别:%c,年龄:%d岁,体重%lf公斤。\n" ,name,xb,age,weight);int age=0 ;char xb=0 ;double weight=0 ;char name[21 ];memset (name,0 ,sizeof (name));printf ("请输入您的姓名、姓别(x-男;y-女),年龄和体重,中间用空格分隔:" );scanf ("%s %c %d %lf" ,name,&xb,&age,&weight); printf ("您的姓名是:%s,姓别:%c,年龄:%d岁,体重%lf公斤。\n" ,name,xb,age,weight);
运算符
算术运算符;
赋值运算符;
sizeof运算符;
关系运算符;
逻辑运算符;
位运算符。
算术运算符
运算符
描述
实例
+
两个数相加
A+B 将得到 23
-
一个数减另一个数
A-B 将得到 13
*
两个数相乘
A*B 将得到 90
/
分子除以分母
A/B 将得到 3.6
%
余数运算符,整除后的余数
B%A 将得到 3
++
自增运算符,整数值增加 1
A++ 将得到 19
–
自减运算符,整数值减少 1
A– 将得到 17
赋值运算符
运算符
描述
实例
=
简单的赋值运算符,把右边操作数的值赋给左边操作数
C = A + B 将把 A + B 的值赋给 C
+=
加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数
C += A 相当于 C = C + A
-=
减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数
C -= A 相当于 C = C - A
*=
乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数
C *= A 相当于 C = C * A
/=
除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数
C /= A 相当于 C = C / A
%=
求余数且赋值运算符,求两个操作数的模赋值给左边操作数,浮点数不适用取余数。
C %= A 相当于 C = C % A
sizeof运算符 用来计算变量(或数据类型)在当前系统中占用内存的字节数。sizeof不是函数,产生这样的疑问是因为sizeof的书写确实有点像函数,sizeof有两种写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 sizeof (数据类型);printf ("字符型变量占用的内存是=%d\n" ,sizeof (char )); printf ("整型变量占用的内存是=%d\n" ,sizeof (int )); sizeof (变量名);sizeof 变量名;int ii;printf ("ii占用的内存是=%d\n" ,sizeof (ii)); printf ("ii占用的内存是=%d\n" ,sizeof ii);
关系运算符
关系
数学中的表示
C语言的表示
小于
<
<
小于等于
≤
<=
大于
>
>
大于等于
≥
>=
等于
=
==
不等于
≠
!=
逻辑运算符
运算符
描述
实例
&&
逻辑与
true && false 等于false
||
逻辑或
true && false 等于true
!
逻辑非
true的逻辑非为真
三目运算符
表达式1?表达式2:表达式3;
先执行表达式1,如果表达式1的结果如果为真,那么执行表达式2,并且这个整体的运算式的结果是表达式2的结果;如果表达式1的结果如果为假,执行表达式3,运算式的结果是表达式3的结果。
1 2 int year;year=(year%100 ==0 )?(year%400 ==0 ?1 :0 ):(year%4 ==0 ?1 :0 );
if、switch语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 if (表达式){} else { } switch (表达式){ case 整型数值1 : 语句1 ;case 整型数值2 : 语句2 ;...... case 整型数值n: 语句n;default : 语句n+1 ;}
程序结构 while循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 while (表达式){ if (表达式)语句块; if (表达式)break ; if (表达式)continue ; } do { 语句块 } while (表达式) int times=0 ; int value=0 ; int sum=0 ; while (sum<5000 ) { printf ("请输入数字:" ); scanf ("%d" ,&value); times++; sum=sum+value; } printf ("您一共输入了%d个数据,和为%d。\n" ,times,sum);
for循环 1 2 3 4 5 for (语句1 ;表达式;语句2 ) { 语句块 }
for循环开始时,会先执行语句1,而且在整个循环过程中只执行一次语句1。
接着判断表达式的条件,如果条件成立,就执行一次循环体中的语句块。
语句块执行完后,接下来会执行语句2。
重复第2)步和第3),直到表达式的条件不成立才结束for循环。
注意:
在for循环中,语句1、表达式和语句2都可以为空,for (;;)等同于while (1)。
continue和break两个关键字也可以用在for循环体中。
1 2 3 4 5 6 7 8 9 int ii=1 ; int sum=0 ; for (ii=1 ;ii<=100 ;ii++) { sum=sum+ii; } printf ("1到100的累积值为%d。\n" ,sum);
数组 数组(array)是一组数据类型相同的变量,可以存放一组数据,它定义的语法是:
数据类型 数组名[数组长度];
定义数组的时候,数组的长度必须是整数,可以是常量,也可以是变量。数据的下标也必须是整数,可以是常量,也可以是变量。
1 2 3 4 5 6 7 int ii[10 ]; printf ("sizeof(ii)=%d\n" ,sizeof (ii)); int no[10 ];memset (no,0 ,sizeof (no));
二维数组
数据类型 数组名[第一维的长度][第二维的长度];
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 int ii=0 ; int jj=0 ; int class =3 ; int total=5 ; double weight[class ][total ]; double sum[class ]; memset (weight,0 ,sizeof (weight)); memset (sum,0 ,sizeof (sum)); for (ii=0 ;ii<class;ii++){ for (jj=0 ;jj<total;jj++){ printf ("请输入第%d组第%d名超女的体重:" ,ii+1 ,jj+1 ); scanf ("%lf" ,&weight[ii][jj]); sum[ii]=sum[ii]+weight[ii][jj]; } }
字符串 字符串就是一个以空字符’\0’结束的字符数组,是一个特别的字符数组,这是约定,是规则。空字符’\0’也可以直接写成0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 char name[21 ]; memset (strname,0 ,sizeof (strname));strcpy (strword,"hello" );char strword[21 ];memset (strword,0 ,sizeof (strword));strword[0 ]='h' ; strword[1 ]='e' ; strword[2 ]='l' ; strword[3 ]='l' ; strword[4 ]='o' ; strword[5 ]='\0' ;
函数 函数声明
return_type function_name( parameter list );
返回值的数据类型return_type:函数执行完任务后的返回值,可以是int、char、double或其它自定义的数据类型。如果函数只执行任务而不返回值,return_type用关键字 void表示,如下:
1 void function_name( parameter list );
函数名function_name:函数名是标识符,命名规则与变量相同。
参数列表parameter list:当函数被调用时,调用者需要向函数传递参数。参数列表包括参数的数据类型和书写顺序。参数列表是可选的,也就是说,函数可以没有参数,如下:
1 return_type function_name();
函数定义 1 2 3 4 5 return_type function_name ( parameter list ) { }
注意:
#include <> 用于包含系统提供的头文件,编译的时候,gcc在系统的头文件目录中寻找头文件。
#include “” 用于包含程序员自定义的头文件,编译的时候,gcc先在当前目录中寻找头文件,如果找不到,再到系统的头文件目录中寻找。
库函数 C语言标准库函数的声明的头文件存放在/usr/include目录中,如下:
1 2 3 <asset.h> <ctype.h> <errno.h> <float.h> <limits.h> <locale.h> <math.h> <setjmp.h> <signal.h> <stdarg.h> <stddef.h> <stdlib.h> <stdio.h> <string.h> <time.h>
变量的作用域 作用域是程序中定义的变量存在(或生效)的区域,超过该区域变量就不能被访问。C 语言中有四种地方可以定义变量。
在所有函数外部定义的是全局变量。
在头文件中定义的是全局变量。
在函数或语句块内部定义的是局部变量。它们只能在该函数或语句块内部的语句使用。
函数的参数是该函数的局部变量。
注意
局部变量和全局变量的名称可以相同,在某函数或语句块内部,如果局部变量名与全局变量名相同,就会屏蔽全局变量而使用局部变量。
指针 变量
内存变量简称变量,在C语言中,每定义一个变量,系统就会给变量分配一块内存,而内存是有地址的。如果把计算机的内存区域比喻成一个大宾馆,每块内存的地址就像宾馆房间的编号。
1 2 3 4 5 6 7 8 int ii=10 ; char cc='A' ; double dd=100.56 ; printf ("变量ii的地址是:%p\n" ,&ii); printf ("变量cc的地址是:%p\n" ,&cc); printf ("变量dd的地址是:%p\n" ,&dd);
指针
指针是一种特别变量,全称是指针变量,专用于存放其它变量在内存中的地址编号,指针在使用之前要先声明,语法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 datatype *varname; datatype 是指针的基类型,它必须是一个有效的C数据类型(int 、char 、double 或其它自定义的数据类型),varname 是指针的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。 int *ip; char *cp; double *dp; int ii = 10 ;int *pii = 0 ; pii = ⅈ *pii = 20 ; printf ("pii的值是:%p\n" , pii);printf ("*pii的值是:%d\n" , *pii);printf ("ii的值是:%d\n" , ii);int *pi=0 ; *pi=10 ; char cc[4 ]; int ii[4 ]; double dd[4 ]; printf ("%p %p %p %p\n" ,cc,cc+1 ,cc+2 ,cc+3 );printf ("%p %p %p %p\n" ,ii,ii+1 ,ii+2 ,ii+3 );printf ("%p %p %p %p\n" ,dd,dd+1 ,dd+2 ,dd+3 );printf ("sizeof(int *) is %d.\n" ,sizeof (int *)); printf ("sizeof(char *) is %d.\n" ,sizeof (char *)); printf ("sizeof(double *) is %d.\n" ,sizeof (double *));
整数 在定义整型变量的时候,可以在int关键字之前加signed、unsigned、short和long四种修饰符。
signed:有符号的,可以表示正数和负数。
unsigned:无符号的,只能表示正数,例如数组的下标、人的身高等。
short:短的,现在主流的64位操作系统下,整数占用内存4个字节。
long:长的,更长的整数。
整数的取值范围 整数的取值范围与计算机操作系统和C语言编译器有关,没有一个固定的数值,我们可以根据它占用的内存大小来推断它的取值范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 一个字节有8 个位,表示的数据的取值范围是28 -1 ,即255 。 如果占用的内存是两个字节,无符号型取值范围是2 **8 ⅹ2 **8 -1 。 如果占用的内存是四个字节,无符号型取值范围是2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 -1 。 如果占用的内存是八个字节,无符号型取值范围是2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 ⅹ2 **8 -1 。 如果是有符号,取值范围减半,因为符号占一个位。 short si; int ii; long li; printf ("sizeof short is %d\n" ,sizeof (short ));printf ("sizeof int is %d\n" ,sizeof (int ));printf ("sizeof long is %d\n" ,sizeof (long ));
类型简写
类型全称
长度
取值范围
short
[signed] short [int]
2字节
-32768~32767
unsigned short
unsigned short [int]
2字节
0~65535
int
[signed] int
4字节
-2147483648~2147483647
unsigned int
unsigned [int]
4字节
0~4294967295
long
[signed] long [int]
8字节
-9223372036854775808~9223372036854775807
unsigned long
unsigned long [int]
8字节
0~18446744073709551615
注意:
计算机用最高位1位来表达符号(0-正数,1-负数),unsigned修饰过的正整数不需要符号位,在表达正整数的时候比signed修饰的正整数取值大一倍。
在写程序的时候,上表中括号[]的单词可以省略不书写。
在写程序的时候,给整数变量赋值不能超出变量的取值范围,编译的时候会出现类似以下的错误,程序运行也可能产生不可预后的后果。
常用的库函数
1 2 3 4 int atoi (const char *nptr) ; long atol (const char *nptr) ; int abs (const int j) ; long labs (const long int j) ;
数据类型的别名
1 2 typedef unsigned int size_t ;size_t ii; 等同于 unsigned int ii;
类型转换 自动类型转换 整型类型级别从低到高依次为:
signed char->unsigned char->short->unsigned short->int->unsigned int->long->unsigned long
浮点型级别从低到高依次为:
float->double
操作数中没有浮点型数据时
当 char、unsigned char、short 或 unsigned short 出现在表达式中参与运算时,一般将其自动转换为 int 类型。 int 与 unsigned int混合运算时,int自动转换为unsigned int型。 int、unsigned int 与 long 混合运算时,均转换为 long 类型。
操作数中有浮点型数据时
当操作数中含有浮点型数据时,所有操作数都将转换为 double 型。
赋值运算符两侧的类型不一致时
当赋值运算符的右值(可能为常量、变量或表达式)类型与左值类型不一致时,将右值类型提升/降低为左值类型。
右值超出左值类型范围时
赋值运算符右值的范围超出了左值类型的表示范围,将把该右值截断后,赋给左值。所得结果可能毫无意义。
强制类型转换
(目标类型) 表达式;
结构体 结构体(struct)来存放一组不同类型的数据。语法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 struct 结构体名{ 结构体成员变量一的声明; 结构体成员变量二的声明; 结构体成员变量三的声明; ...... 结构体成员变量四的声明; }; struct st_girl { char name[51 ]; int age; int height; int weight; char sc[31 ]; char yz[31 ]; }; struct st_girl queen , princess , waiting , workers ;struct st_girl queen ;printf ("sizeof(struct st_girl) %d\n" ,sizeof (struct st_girl));printf ("sizeof(queen) %d\n" ,sizeof (queen)); #pragma pack(1) struct st_girl stgirl ;printf ("%d\n" ,stgirl); printf ("%p\n" ,stgirl); printf ("%p\n" ,&stgirl); memset (&queen,0 ,sizeof (struct st_girl));memset (&queen,0 ,sizeof (queen));memset (pst,0 ,sizeof (struct st_girl));struct st_girl queen ;struct st_girl *pst = &queen; (*pointer).memberName pointer->memberName struct st_girl girl1 ,girl2 ;strcpy (girl1.name,"西施" ); girl1.age=18 ; memcpy (&girl2,&girl1,sizeof (struct st_girl));void setvalue (struct st_girl *pst) ;struct st_girl queen ; memset (&queen,0 ,sizeof (struct st_girl));
格式化输出 1 2 3 4 5 6 7 int printf (const char *format, ...) ;int sprintf (char *str, const char *format, ...) ;int snprintf (char *str, size_t size, const char *format, ...) ;
格式说明符
%[flags][width][.prec]type
类型符type :表示输出数据的类型
%hd、%d、%ld 以十进制、有符号的形式输出 short、int、long 类型的整数。
%hu、%u、%lu 以十进制、无符号的形式输出 short、int、long 类型的整数
%c 输出字符。
%lf 以普通方式输出double(float弃用,long doube无用)。
%e 以科学计数法输出double。
%s 输出字符串。
%p 输出内存的地址。
宽度width :用于控制输出内容的宽度
1 2 3 printf ("=%12s=\n" ,"abc" ); printf ("=%12d=\n" ,123 ); printf ("=%12lf=\n" ,123.5 );
对其标志flags :用于控制输出内容的对齐方式
不填或+:输出的内容右对齐,这是缺省的方式
-:输出的内容左对齐。
1 2 3 4 5 6 7 8 printf ("=%-12s=\n" ,"abc" ); printf ("=%-12d=\n" ,123 ); printf ("=%-12f=\n" ,123.5 ); printf ("=%012s=\n" ,"abc" ); printf ("=%012d=\n" ,123 ); printf ("=%012f=\n" ,123.5 );
精度prec :如果输出的内容是浮点数,它用于控制输出内容的精度,也就是说小数点后面保留多少位,后面的数四舍五入。
1 2 3 4 printf ("=%12.2lf=\n" ,123.5 ); printf ("=%.2lf=\n" ,123.5 ); printf ("=%12.2e=\n" ,123500000000.0 ); printf ("=%.2e=\n" ,123500000000.0 );
main函数 1 2 3 4 5 6 7 8 9 10 int main (int argc,char *argv[],char *envp[])
动态内存管理 1 2 3 4 5 6 7 void *malloc (unsigned int size) ;malloc (100 ) ; void free (void *p) ;
野指针
内存指针变量未初始化
内存释放后之后指针未置空
1 2 3 4 5 6 7 int *pi=0 ;int i;int *pi=&i;free (pi);pi=0 ;
文件操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 FILE *fopen ( const char * filename, const char * mode ) ; int fclose (FILE *fp) ;int fprintf (FILE *fp, const char *format, ...) ;char *fgets (char *buf, int size, FILE *fp) ;
二进制文件处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 size_t fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream) ;size_t fread (void *ptr, size_t size, size_t nmemb, FILE *fp) ;
文件定位 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 long ftell (FILE *fp) ;void rewind ( FILE *fp ) ;int fseek ( FILE *fp, long offset, int origin ) ;fseek(fp,100 ,0 ); fseek(fp,100 ,1 ); fseek(fp,-100 ,2 );
文件缓冲区 在操作系统中,存在一个内存缓冲区,当调用fprintf、fwrite等函数往文件写入数据的时候,数据并不会立即写入磁盘文件,而是先写入缓冲区,等缓冲区的数据满了之后才写入文件。还有一种情况就是程序调用了fclose时也会把缓冲区的数据写入文件。
标准输入、标准输出、标准错误 Linux操作系统为每个程序默认打开三个文件,即标准输入stdin、标准输出stdout和标准错误输出stderr,其中0就是stdin,表示输入流,指从键盘输入,1代表stdout,2代表stderr,1,2默认是显示器。
目录操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 char strpwd[301 ];memset (strpwd,0 ,sizeof (strpwd));getcwd(strpwd,300 ); printf ("当前目录是:%s\n" ,strpwd);int chdir (const char *path) ;int mkdir (const char *pathname, mode_t mode) ;int rmdir (const char *pathname) ;#include <dirent.h> DIR *opendir (const char *pathname) ; struct dirent *readdir (DIR *dirp) ;int closedir (DIR *dirp) ;DIR *目录指针名; struct dirent { long d_ino; off_t d_off; unsigned short d_reclen; unsigned char d_type; char d_name [NAME_MAX+1 ]; };
时间操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 typedef long time_t ;time_t tnow;tnow =time(0 ); time(&tnow); struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; }; struct tm * localtime (const time_t *) ;time_t mktime (struct tm *tm) ;unsigned int sleep (unsigned int seconds) ;int usleep (useconds_t usec) ;struct timeval { long tv_sec; long tv_usec; }; struct timezone { int tz_minuteswest; int tz_dsttime; }; int gettimeofday (struct timeval *tv, struct timezone *tz )
编译预处理
C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件
预处理指令
包含文件:将源文件中以#include格式包含的文件复制到编译的源文件中,可以是头文件,也可以是其它的程序文件。
宏定义指令:#define指令定义一个宏,#undef指令删除一个宏定义。
条件编译:根据#ifdef和#ifndef后面的条件决定需要编译的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include <文件名> #include "文件名" #define 宏名 字符串 #define PI 3.141592 #define 宏名(形参表) 字符串 #define MAX(x,y) ((x)>(y) ? (x) : (y))
条件编译 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #ifdef 标识符 程序段 1 #else 程序段 2 #endif #ifndef 标识符 程序段 1 #else 程序段 2 #endif #undef
系统错误 我们在写程序的时候需要调用C语言提供的库函数,并通过函数的返回值判断调用是否成功。其实在C语言中,还有一个全局变量errno,存放了函数调用过程中产生的错误码。
为防止和正常的返回值混淆,库函数的调用一般并不直接返回错误码,而是将错误码(是一个整数值,不同的值代表不同的含义)存入一个名为 errno 的全局变量中,errno 不同数值所代表的错误消息定义在 <errno.h> 文件中。如果库函数调用失败,可以通过读出 errno 的值来确定问题所在,推测程序出错的原因,这也是调试程序的一个重要方法。
配合 strerror和perror两个库函数,可以很方便地查看出错的详细信息。
strerror 在 <string.h> 中声明,用于获取错误码对应的消息描述。
perror 在 <stdio.h> 中声明,用于在屏幕上最近一次系统错误码消息描述,在实际开发中,我们写的程序运行于后台,在屏幕上显示错误信息没有意义。
1 2 3 4 char *strerror (int errno) ;
参考