外观
03.C语言查缺补漏
约 1851 字大约 6 分钟
C个人随笔记录
2020-10-25
1、关键字 typedef
C语言中可以对类型赋予新名字
语法:typedef Type NewTypeName;
注意:typedef并没有创建新类型,只是创建了类型别名
2、深入typedef应用
typedef可在函数中定义"局部类型名"
typedef常用于简化类型名(如: unsigned long long)
typedef定义类型名,能够以统一的方式创建变量(Type var; )
#include <stdio.h>
#include <string.h>
typedef float(FArr5)[5]; // 定义数组类型名
typedef int(IFuncII)(int, int); // 定义函数类型名
typedef FArr5* PFArr5;
typedef IFuncII* PIFuncII;
float g_arr[5] = { 0.1, 0.2, 0.3 };
int add(int a, int b)
{
return a + b;
}
int main()
{
FArr5* pa = &g_arr; // float(*)[5]
IFuncII* pf = add; // int(*)(int,int)
PFArr5 npa = pa;
PIFuncII npf = pf;
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%f\n", (*pa)[i]);
printf("%f\n", (*npa)[i]);
}
printf("%d\n", pf(2, 3));
printf("%d\n", npf(2, 3));
return 0;
}
3、struct 结构体类型
struct 结构体变量的本质是变量的集合
struct结构体变量中的成员占用独立的内存
struct结构体类型可用typedef赋予新类型名
可定义struct结构体类型的指针,并指向对应类型的变景
struct结构体类型可先前置声明,再具体定义
前置类型声明只能用于指针定义
类型完整定义之后才能进行变量定义
struct结构体类型可以省略类型名
类型名省略时,每次创建变量必须给出完整结构体定义
struct结构体类型可以省略类型名(无名结构体类型)
类型名省略时,每次创建变量必须给出完整结构体定义
无名结构体类型总是互不相同的类型(互不兼容)
3、位域
现代程序设计中,内存使用的最小单位为字节(约定俗成)
在一些特定场合,可将比特位作为最小单位使用内存
结构体类型能够指定成员变量占用内存的比特位宽度(位域)
位域示例:
深入位域
位域成员必须是整型,默认情况下成员依次排列
位域成员占用的位数不能超过类型宽度(错误示例:char c : 9;)
当存储位不足时,自动启用新存储单元
可以舍弃当前未使用的位,重新启用存储单元
struct 结构体变量中的成员占用独立的内存
struct结构体类型可用typedef 赋予新类型名
结构体类型能够指定成员变量占用内存的比特位宽度
位域成员必须是整型,占用的位数不能超过类型宽度
当存储位不足时,自动启用新存储单元
4、联合体
union是C语言中的自定义类型关键字
union是struct的兄弟关键字,用法上非常相似
- 语法
Union TpyeName
{
Type1 var1;
Type2 var2;
.....................
};
(1)union struct的不同
union类型所有成员共享同一段内存(所有成员起始地址相同)
union类型的大小取决于成员的最大类型
union类型的变量只能以第一个成员类型的有效值进行初始化
(2)union类型的应用 - 判断系统大小端
小端系统:低位数据存储在低地址内存中
大端系统:低位数据存储在高地址内存中
例:对于unsigned ui = 1;

int isLittleEndian()
{
union
{
int i;
char a\[4\];
} test = { 0 };
test.i = 1;
return (test.a\[0\] == 1);
}5、枚举
enum是C语言中的自定义类型关键字
enum能够定义整型常量的集合类型
语法:
enum TypeName
{
lntConst1,
IntConst2,
.....
IntConstN
}
枚举类型(enum)注意事项
第一个枚举常量的默认值为0
后续常量的值在前一个常量值的基础上加1
可以任意对枚举常量指定整型值(只能指定整型值)
enum Day { MON = 1,TUE,WED,THU,FRI,SAT, SUN };
enum Season { Spring, Summer = 3, Autumn, Winter = -1 };
6、小结
union是struct的兄弟关键字,用法上非常相似
union类型所有成员共享同一段内存
enum能够定义整型常量的集合类型
enum的本质是int类型,常用于整型常量定义
三十四、多文件程序设计
1、多文件与编译链接

2、多文件之间的相互访问
头文件中只做函数声明和变量声明(不做具体定义)
头文件中可定义数据类型(typedef, struct, union, enum)
根据具体实现,一个头文件可对应多个源文件(多数情况一对一)
不要使用#include语句包含源文件
2、再论全局变量
普通全局变量
源文件中定义的全局变量可在所有其它源文件中使用
可使用extern关键字在头文件中进行声明,并在其它文件使用
静态全局变量
static修饰的全局变量只能在当前源文件中使用
无法通过extern关键字声明,在其它文件使用
3、注意
函数声明语句默认自带extern关键字修饰
类型定义必须在头文件中,仅类型声明无法创建变量
静态全局变量
生命期为程序运行期
作用域仅在定义的文件中
无法直接在其它文件中使用
static关键字可使函数具备文件作用域(静态函数)
静态函数无法在其它文件中被调用
函数设计时需要考虑是否在其它文件中使用
4、小结
实际工程开发中,多文件程序设计是常态
源文件实现具体功能,头文件声明接口
#include 用于声明需要使用其它文件中定义的功能
extern关键字用于函数和全局变量的声明
static关键字修饰的全局变量不能在其它文件中使用
三十五、其他
1、int a =1,b=2;float c;c=a/b;为什么c等于0?
#include <stdio.h>
int main() {
int a = 1, b = 2;
float c = 0;
c = a / b;
printf("= 两个int相除:=%f==\n", c);
c = (float)a / b;
printf("=利用强制转换,可获得浮点数:%f==\n", c);
c = a / (float)b;
printf("=利用强制转换,可获得浮点数:%f==\n", c);
return 0;
}
2、int c=a==b;对的吗?c等于?
#include <stdio.h>
int main() {
int a = 1, b = 2;
int c = a == b;
printf("==%d==\n", c);
printf("程序先判断 a 与 b 是否相等,再将值赋值给c \n");
return 0;
}
3、int a = -1;int b = 2; a&&b等于1?
#include <stdio.h>
int main()
{
int a = -1;
int b = 2;
int c = 0;
c = a && b;
printf("c=%d\n", c);
c = !(a - b) || (c < b);
printf("!优先级大于|| c=%d\n", c);
c = -5;
c = !c;
printf("c=%d\n", c);
c = -5;
c = !!c;
printf("c=%d\n", c);
return 0;
}
- 结论:
C语言中的真值对应非零值,假值对应零值。
如:1,1.6,-1,0.28,均为真值
如:0,0.0,-0,-0.0,均为假值


