张德长

导航

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段的结束。

#if 常数表达式

代码段

#endif

 

#if 表达式 代码段

#else  表达式 代码段

#endif

#if 表达式 代码段

#elif 表达式 代码段

#elif 表达式 代码段

#else 表达式 代码段

#endif

如果常数表达式为真, 则该段程序被编译, 否则跳过不编译。

 

#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
%hX、%X、%lX

以十六进制、不带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字也小写;如果 X 大写,那么输出的十六进制数字也大写。

%#hx、%#x、%#lx
%#hX、%#X、%#lX

以十六进制、带前缀、无符号的形式输出 short、int、long 类型的整数。如果 x 小写,那么输出的十六进制数字和前缀都小写;如果 X 大写,那么输出的十六进制数字和前缀都大写。

%f、%lf

以十进制的形式输出 float、double 类型的小数

%e、%le
%E、%lE

以指数的形式输出 float、double 类型的小数。如果 e 小写,那么输出结果中的 e 也小写;如果 E 大写,那么输出结果中的 E 也大写。

%g、%lg
%G、%lG

以十进制和指数中较短的形式输出 float、double 类型的小数,并且小数部分的最后不会添加多余的 0。如果 g 小写,那么当以指数形式输出时 e 也小写;如果 G 大写,那么当以指数形式输出时 E 也大写。

%s

输出一个字符串

 

...

 

posted on 2022-09-02 18:49  张德长  阅读(41)  评论(0编辑  收藏  举报