C语言学习笔记
C语言学习笔记
预处理
#include |
#include指令可以将另一个源文件的全部内容包含进来 #include "stdio.h" #include <stdio.h> 用尖括号时, C库函数头文件所在的目录中寻找, 这为标准方式; 用双引号时, 用户当前目录中寻找, 若找不到, 再到存放C库函数头文件所在的目录中寻找。 <>先找系统目录,用于系统文件; ””先找用户目录,再找系统目录,用于自定义文件;可以给出路径信息; 被包含的文件称为“标题文件” 或“头部文件” , 一般以.h为后缀 头文件内容:宏定义;结构、 联合和枚举声明;typedef声明;外部函数声明;全局变量声明; 使用文件包含为实现程序修改提供了方便。 当需要修改某些参数时, 不必逐个修改程序, 只需修改一个文件 即可。 一个#include命令只能指定一个被包含的文件。 文件包含是可以嵌套的, 即在一个被包含文件中还可以包含另一个被包含文件。 预编译后就成为一个文件, 而不是两个文件。 这时如果file2.h中有全局静态变量, 则该全局变量在file1.c文件中也有效, 这时不需要再用extern声明。 |
|||
#if #ifdef #undef |
如果#if命令后的参数表达式为真, 则编译#if到#endif之间的程序段, 否则跳过。 #endif命令用来表示#if段的结束。
如果常数表达式为真, 则该段程序被编译, 否则跳过不编译。
#ifdef与#ifndef命令, 分别表示“如果有定义” 及“如果无定义” #ifdef 宏替换名 语句段 #endif #ifdef 宏替换名 语句段1 #else 语句段2 #endif #ifndef 宏替换名 语句段 #endif #ifndef 宏替换名 语句段1 #else 语句段2 #endif #undef 宏替换名 #define MAX_SIZE 100 char array[MAX_SIZE] #undef MAX_SIZE #undef的主要目的是将宏名局限在仅需要它们的代码段中。 |
|||
#line #pragma |
#line命令用于显示_LINE_与_FILE_的内容。 _LINE_存放当前编译行的行号,_FILE_存放当前编译的文件名。 #line命令的一般形式如下:#line 行号["文件名"] #line命令主要用于调试及其他特殊应用
#pragma命令的作用是设定编译器的状态, 或者指示编译器完成一些特定的动作 #pragma 参数,参数可分为以下几种: message参数: 在编译信息窗口中输出相应的信息。 code_seg参数: 设置程序中函数代码存放的代码段。 once参数: 保证头文件被编译一次
|
|||
预定义宏名 |
ANSI标准说明了以下5个预定义宏替换名。 __LINE__: 当前被编译代码的行号。 __FILE__: 当前源程序的文件名称。 __DATE__: 当前源程序的创建日期。 __TIME__: 当前源程序的创建时间。 __STDC__: 用来判断当前编译器是否为标准C。值为1,则表示是标准C,否则不是。 宏名的书写比较特别, 书写时两边都要由下画线构成 |
宏 |
宏定义是预处理命令的一种 ; 宏提供了一种可以替换源代码中字符串的机制。 宏定义分为不带参数的宏定义和带参数的宏定义两种 #define命令出现在程序中函数的外面; 宏名的有效范围为定义命令之后到此源文件结束; 可以用#undef命令终止宏定义的作用域 宏名要简单且意义明确, 一般习惯用大写字母表示, 以便与变量名相区别 宏定义不是C语句, 不需要在行末加分号 |
无参宏 |
无参宏相当于给指定的字符串起一个别名 #define 宏名 字符串 #define PI 3.14 #表示这是一条预处理命令。 宏名是一个标识符, 必须符合C语言标识符的规定。 无参宏字符串可以是常数、 表达式、 格式字符串等。 要改变一个常量时只需改变#define命令行。 宏名定义后, 即可成为其他宏名定义中的一部分 (宏嵌套) #define SIDE 4 #define AREA SIDE*SIDE 如果在字符串中含有宏名, 则不进行替换。 如果串长于一行, 可以在该行末尾用反斜杠“\” 续行 |
有参宏 |
有参数的宏定义不是简单的字符串替换,还要进行参数替换 #define 宏名(参数表)字符串 #define DOUBLE(x) (x*2) #define MIX(a,b) ((a)*(b)+(b)) 宏优点:提升代码的速度,因为不再存在函数调用。 宏缺点:由于重复编码, 而增加了程序长度。 有参宏定义时, 参数要加括号; 有参宏的展开,只是实参字符串代替形参。 有参宏定义时, 宏名与带参数的括号之间不可以加空格, 否则会将空格以后的字符都作为替代字符串的一部分。 有参宏定义中, 形式参数不分配内存单元, 因此不必做类型定义。 |
函数的指针
函数指针 |
int sum(int,int);函数声明/函数原型的声明; int (*pfunc)(int,int);函数指针声明,多了(*); pfunc=sum;函数名相当于函数地址,可以直接赋值给函数指针; 函数名→函数地址→赋值→函数指针; int res=sum(10,20);函数调用; res=pfunc(10,20);通过函数指针调用函数,函数指针和函数名使用方法完全一致; 函数指针→相当于函数名→调用函数; int sum(int a,int b){return a+b;}函数的实现;
|
函数指针数组 |
int sum(int,int);int diff(int,int);int mul(int,int);int div(int,int); int (*pfunc[4])(int,int);函数指针数组的声明;在函数指针变量名后加[len]即可; pfunc[0]=sum;pfunc[1]=diff;pfunc[2]=mul;pfunc[3]=div; int (*pfunc[4])(int,int)={sum,diff,mul,div};手动指定数组长度; int (*pfunc[])(int,int)={sum,diff,mul,div};用元素个数自动指定数组长度; int res = pfunc[0](10,20);通过函数指针数组元素,也就是函数指针调用函数; 数组→下标→元素→函数指针→相当于函数名→调用函数; res=pfunc[0](pfunc[1](1,2),pfunc[2](2,3)); for(int i=0;i<4;i++){res=pfunc[i](10,20);} 函数指针数组的每个元素,都是一个函数指针; 函数指针数组的每个元素,都可以像使用函数名那样,调用这个函数; |
printf输出格式控制符
格式控制符 |
输出控制符 说明 |
%c |
输出一个单一的字符 |
%hd、%d、%ld |
以十进制、有符号的形式输出 short、int、long 类型的整数 |
%hu、%u、%lu |
以十进制、无符号的形式输出 short、int、long 类型的整数 |
%ho、%o、%lo |
以八进制、不带前缀、无符号的形式输出 short、int、long 类型的整数 |
%#ho、%#o、%#lo |
以八进制、带前缀、无符号的形式输出 short、int、long 类型的整数 |
%hx、%x、%lx |
以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。 |
%#hx、%#x、%#lx |
以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。 |
%f、%lf |
以十进制的形式输出 float、double 类型的小数 |
%e、%le |
以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。 |
%g、%lg |
以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。 |
%s |
输出一个字符串 |
...