Clearndemo
所属分类:其他
开发工具:C/C++
文件大小:71KB
下载次数:0
上传日期:2020-02-09 20:57:45
上 传 者:
wrmtl
说明: demo to learn C programing with readme file
文件列表:
Clearndemo (0, 2020-02-04)
Clearndemo\TestFunPara.c (582, 2020-02-04)
Clearndemo\TestFunPara.exe (43721, 2020-02-04)
Clearndemo\TestFunPtr.c (683, 2020-02-03)
Clearndemo\TestFunPtr.exe (44568, 2020-02-03)
Clearndemo\TestStructBit.c (257, 2020-02-03)
Clearndemo\TestStructBit.exe (43725, 2020-02-03)
Clearndemo\TestUnion.c (417, 2020-02-03)
Clearndemo\TestUnion.exe (43773, 2020-02-03)
1、函数指针
函数指针是指向函数的指针变量
通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数
函数指针可以像一般函数一样,用于调用函数、传递参数
函数指针变量的声明:
typedef int (*fun_ptr)(int,int);
声明一个指向同样参数、返回值的函数指针类型
回调函数
函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数
简单讲:回调函数是由别人的函数执行时调用你实现的函数
见测试文件TestFunPtr.c
函数名和数组名一样
函数名默认为函数入口地址,可以指针化
数组名默认为数组起始地址,可以指针化
2、
由于C++是C的超集
故可以用g++编译.c文件
配置好编译参数,也可以使用gcc编译.cpp文件
3、位域
有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位
为了节省存储空间,并使处理简便,C 语言又提供了一种数据结构,称为"位域"或"位段"
所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数
每个域有一个域名,允许在程序中按域名进行操作
这样就可以把几个不同的对象用一个字节的二进制位域来表示
位域定义与结构定义相仿,其形式为:
struct 位域结构名
{
位域列表
};
其中位域列表的形式为:
类型说明符 位域名: 位域长度
*****给位域赋值(应注意赋值不能超过该位域的允许范围) a:1,最大为1 a:3最大为7
一个位域存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放该位域,也可以有意使某位域从下一单元开始
位域可以是无名位域,这时它只用来作填充或调整位置,无名的位域是不能使用的
例如:
struct bs{
unsigned a:4;
unsigned :4; /* 空域 */
unsigned b:4; /* 从下一单元开始存放 */
unsigned c:4
}
位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位
如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中
从以上分析可以看出,位域在本质上就是一种结构类型,不过其成员是按二进位分配的
4、共用体
共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型
您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值
共用体提供了一种使用相同的内存位置的有效方式
定义共用体
为了定义共用体,您必须使用 union 语句,方式与定义结构类似
union 语句定义了一个新的数据类型,带有多个成员
格式如下:
union [union tag]
{
member definition;
member definition;
...
member definition;
} [one or more union variables];
union tag 是可选的
每个 member definition 是标准的变量定义,比如 int i; 或者 float f;或者其他有效的变量定义
union Data
{
int i;
float f;
char str[20];
} data;
共用体占用的内存应足够存储共用体中最大的成员
例如,在上面的实例中,Data 将占用 20 个字节的内存空间
访问共用体成员
类似结构体
5、内存管理
C 语言为内存的分配和管理提供了几个函数
这些函数可以在 头文件中找到
void *calloc(int num, int size);
在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0,所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0
void free(void *address);
该函数释放 address 所指向的内存块,释放的是动态分配的内存空间
void *malloc(int num);
在堆区分配一块指定大小的内存空间,用来存放数据,这块内存空间在函数执行完成后不会被初始化,它们的值是未知的
void *realloc(void *address, int newsize);
该函数重新分配内存,把内存扩展到 newsize
***** void * 类型表示未确定类型的指针
***** C、C++ 规定 void * 类型可以通过类型转换强制转换为任何其它类型的指针
6、强制类型转换
a、强制类型转换是把变量从一种类型转换为另一种数据类型
可以使用强制类型转换运算符来把值显式地从一种类型转换为另一种类型
如下所示:
(type_name) expression
b、隐式转化
整数提升
整数提升是指把小于 int 或 unsigned int 的整数类型转换为 int 或 unsigned int 的过程
常用的算术转换是隐式地把值强制转换为相同的类型
编译器首先执行整数提升,如果操作数类型不同,则它们会被转换为下列层次中出现的最高层次的类型
char,short ->int ->unsigned int ->long ->unsigned log ->unsigned long long ->float ->double ->long double
float ->double
常用的算术转换不适用于赋值运算符、逻辑运算符 && 和 ||
赋值语句会将右值数类型强制转化为左值数类型
C 语言中 printf 输出 double 和 float 都可以用 %f 占位符 可以混用,而 double 可以额外用 %lf
而 scanf 输入情况下 double 必须用 %lf,float 必须用 %f 不能混用
7、可变参数
函数带有可变数量的参数,而不是预定义数量的参数
C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数
形如:
int func(int, ... )
{
.
.
.
}
int main()
{
func(2, 2, 3);
func(3, 2, 3, 4);
}
函数 func() 最后一个参数写成省略号,即三个点号(...),省略号之前的那个参数是 int,代表了要传递的可变参数的总数
为了使用这个功能,您需要使用 stdarg.h 头文件,该文件提供了实现可变参数功能的函数和宏
具体步骤如下:
a、定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数
b、在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的
c、使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表
宏 va_start 是在 stdarg.h 头文件中定义的
d、使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项
e、使用宏 va_end 来清理赋予 va_list 变量的内存
见测试代码TestFunPara.c
近期下载者:
相关文件:
收藏者: