C语言学习 — 自定义数据类型
最近重新学习了一下C语言教学视频看了看,把一些知识点细节记录一下。
一、自定义数据类型
typedef关键字
typedef 关键字,常用做法 typedef unsigned int uint,所以以前我还认为使用起来就是 typedef 旧名字 新名字,实际上是错误的。
语法是: typedef Type NewTypeName
使用的步骤是 : 在传统的变量声明表达式里,用 新的 类型名替换变量名 ,然后把关键字 typedef 加在该语句的开头。
下面的例子演示 typedef 的用法步骤,便于记忆 typedef 的用法(其实还是有点不太明白):
1、int a; //第一步,正常的定义某类型的变量
2、int my_int; //第二步,用新的类型名字 my_int 替换 变量名a;
3、 typedef int my_int;//第三步,在第二步的前面加上 typedef ;//实际上使用只有第三步
上面这个例子很常用,但是用于函数指针
1、void (*p)(int a); //第一步,定义一个函数指针变量 p
2、void (*PF)(int a); //第二步,用新的类型名字 *PF 变量名p;
3、 typedef void (*PF)(int a);//第三步,在第二步的前面加上 typedef ;//
typedef 的用途:
- 使用 typedef 为现有的类型创建别名。常用的:typedef unsigned long int uint32;
- 定义机器无关的类型。 typedef float REAL; /typedef double REAL; 我的理解这里怎么和第一点一样,不是太明白??????
- 简化一些比较复杂的声明, 用的相对不多这点有点不是太明白??下面的例子:
/*不使用typedef 简化复杂的声明,Callback函数声明如下*/
Callback(u8 *begin, void (*pFunCallback)(u8* pchar, u8 Len), bool state);
/*使用typedef ,Callback函数声明如下*/
typedef void (*PFunCallBack)(u8* pchar, u8 Len);
Callback(u8 *begin,PFunCallBack pFun, bool state);//等价于上面
示例
#include "stdio.h"
typedef float(FArr5)[5]; // 为 float[5] 数组类型取新名字 FArr5代表 float[5]
typedef int(IFuncII)(int, int); // 为 int (int, int) 函数类型取新名字 IFunII 表示函数类型
typedef FArr5* PFarr; //为FArr5 (float[5])这个数组类型的指针取新名字
typedef IFuncII* PIFuncII; // 为 指向这个类型的函数 的 指针 取新名字
float g_arr[5] = {0.1, 0.2 ,0.3}; //这个数组类型就是 FArr5 类型
int add(int a, int b) // add 函数类型就是 IFunII
{
return a + b;
}
int main()
{
FArr5* pa = &g_arr; // pa是指针,指针指向 FArr5 这个类型的东西,这个类型是float[5]数组类型
IFuncII* pf = add; // pf是指针,指针指向 IFuncII 这个类型的东西,是int (int, int) 类型的函数
PFarr npa = pa;
PIFuncII npf =pf;
int i =0;
for(i=0; i<5; i++){
printf("%0.2f\n",(*pa)[i]); //小数点保留2位,对其后的数据进行四舍五入
printf("%f\n",(*pa)[i]); //默认输出,小数点保留6位
printf("%10.2f\n",(*pa)[i]); //输出宽度为10个字符,右对齐,前补空格,小数点保留2位
}
printf("%d\n",pf(2, 3));
printf("%d\n",npf(2, 3));
return 0;
}
typedef 和 #define
典型案例分析
typedef char* pStr1;
#define pStr2 char*
pStr1 s1, s2;
pStr2 s3, s4; //char *s3,s4;
通过上面的定义, s1,s2,为char* 类型,s3 为char* 类型, 但是s4 为char 类型, 因为#define 只是进行了字符串的替换,在定义 s3 s4 的时候,看注释,会变成s3 是指针,s4 是char
结构体和联合体
结构体使用我就直接贴图了,我看的视频教程是 唐佐林老师的C语言基础视频教程,因为是免费的,所以想看原视频的网上就能直接找到
struct:
union:
union demo:
#include <stdio.h>
union data{
int n;
char ch;
short m;
};
int main(){
union data a;
printf("%d, %d\n", sizeof(a), sizeof(union data) );
a.n = 0x40;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.ch = 'd';
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.m = 0x2059;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
a.n = 0x3E25AD54;
printf("%X, %c, %hX\n", a.n, a.ch, a.m);
return 0;
}
union的典型应用 – 判断系统大小端
#include <stdio.h>
/*
小端系统: 低位数据存储在地地址内存中
大端系统: 低位数据存储在高地址内存中
0 x 00 00 00 01
小端系统: [0X01][ 0 ][ 0 ][ 0 ]
低 ---------> 高
大端系统: [0][ 0 ][ 0 ][ 0X01 ]
低 ---------> 高
*/
int isLittleEnd()
{
union
{
int i;
char a[4];
}test ={0};
test.i = 1;
return (test.a[0] == 1); //返回1,小端系统
}
int main(){
printf("System Endian:%d\n",isLittleEnd());
return 0;
}
注意:无名结构体类型总是互不相同的类型(互不兼容)下面看例子:
int main()
{
struct
{
int a;
int b;
} v1;
struct
{
int a;
int b;
} v2;
struct
{
int a;
int b;
} *pv;
v1.a = 1;
v1.b = 2;
v2 = v1; //错误的!!!!
pv = &v2; //错误的!!!!
}
柔性数组
结构体中有素组变量,但是却没有指定长度
#include<stdio.h>
struct softArray
{
int len;
int array[]; //不占用存储空间,所以sizeof softArray 为 4个字节
};
int main()
{
printf ("len = %d\n",sizeof(struct softArray)); //len = 4
return 0;
}
柔性数组的使用:
#include<stdio.h>
#include<malloc.h>
struct softArray
{
int len;
int array[]; //不占用存储空间,所以sizeof softArray 为 4个字节
};
struct softArray* create_soft_array(int size)
{
struct softArray* ret = NULL;
if( size > 0){
ret = (struct softArray*)malloc(sizeof(struct softArray) + sizeof(int) * size);
ret->len = size;
}
return ret;
}
void delete_soft_array(struct softArray* sa)
{
free(sa);
}
void func(struct softArray* sa)
{
int i = 0;
if( NULL != sa ){
for(i=0; i<sa->len; i++){
sa->array[i] = i + 1;
}
}
}
int main()
{
int i = 0;
struct softArray* sa = create_soft_array(10);
func(sa);
for(i=0; i<sa->len; i++){
printf("%d\n",sa->array[i]); //输出 1 23456789 10
}
delete_soft_array(sa);
return 0;
}
位域
现在用得不多,位域成员必须是整形,占用的位数不能超过类型宽度,当存储位不足时,自动启用新的存储单元,可以舍弃当前未使用的位,重新启动新的单元
struct Bits1
{
int a: 16; //正确
short b: 8; //正确
char c: 8; //正确
float f: 32; //错误
}
struct Bits2
{
unsigned char a: 6; //正确
unsigned char b: 6; //正确
unsigned char c: 4; //正确
unsigned char d: 9; //错误
}
struct Bits3
{
unsigned char a: 4; //正确
unsigned char : 0; //正确
unsigned char b: 4; //正确 [ a(4bits) | 4bits(空) ] [ b(4bits) | ]
}
枚举类型(enum)
- enum 是C语言中的 自定义类型 关键字
- enum能够定义 整形常量 的 集合类型
- 第一个常量值默认为 0,后续常量在前一个值的基础上加 1
- 可以任意对美剧常量指定整形值(只能是整形 )
- enum 枚举类型变量就是 整形 sizeof() 等于 4 ,就是int 类型
- enum定义的值是真正意义上的常量
二、头文件相关
- 头文件中只做函数声明和变量声明(不做具体定义)
- 头文件中可定义数据类型(typedef,struct,union,enum)
- 类型定义必须在头文件中,仅类型声明无法创建变量
- 点赞
- 收藏
- 关注作者
评论(0)