c语言联合体指针指向元素,C语言基础及指针⑨联合体与枚举

在上篇中 , 我们初步了解了C语言的IO操作 , 编写IO操作的大致流程:

文件IO编写步骤:

1.使用fopen函数 , 得到文件指针

2.指定fopen的操作模式r,w (指定输入输出流)

3.创建缓冲区 , 缓存读写数据(将流数据读入到内存或写入到磁盘)

3.关闭流 (关闭文件流)

接着介绍了文件的加密解密 , 文件的存储都是以二进制保存在磁盘上的 , 所以我们可以通过二进制运算来进行文件的加密解密操作 。在C语言的IO函数中 , 没有直接获取文件大小的函数 , 所以我们需要自己通过文件指针来获取文件的大小:

/*获取文件大小*/

void getFileSize() {

char* path = "E:\\android_pdf\\研磨设计模式.pdf";

// 打开文件

FILE* fp = fopen(path, "r");

if (fp == NULL) {

printf("打开文件失败\n");

return;

}

// 重新定位文件指针 , SEEK_END文件末尾,0是文件指针的偏移量

fseek(fp, 0l, SEEK_END);

// 返回当前的文件指针,相对于文件开头的位移量

long fileSize = ftell(fp);

printf("文件大小:%ld M\n", fileSize / 1024 / 1024);

}

在jni.h中 , 我们可以看到这样一段代码:

typedef union jvalue {

jboolean z;

jbyte b;

jchar c;

jshort s;

jint i;

jlong j;

jfloat f;

jdouble d;

jobject l;

} jvalue;

这样C语言中的联合体 , 那么什么是联合体呢 ?

联合体:不同类型的变量共用一段内存(相互覆盖) , 始终只有一个成员存在 , 最后赋值的那个 , 有利于节省内存。

联合体大小:成员中最大的成员所占的字节数

联合体 , 将不同的类型联合起来 , 组成一个新的聚合类型 , 这个类型可以是联合体中的任意类型 。

/*联合体*/

/*

不同类型的变量共用一段内存(相互覆盖) , 始终只有一个成员存在 , 最后赋值的那个 , 有利于节省内存

联合体大小:成员中最大的成员所占的字节数

*/

union mValue

{

int i;

short s;

long l;

float f;

};

/*联合体示例*/

void useUnion() {

union mValue m;

m.f = 23.4f;

m.i = 100; // 最后一次赋值有效

printf("联合体:\n%f - %d\n", m.f, m.i);

}

在java中 , 当我们需要一个类列举几个状态时 , 因为状态是固定的 , 所以我们通常的做法是使用枚举 , 将状态列举出来 , 在C语言也有枚举这个类型:

/*

枚举(列举所有的情况)

限定值,保证取值的安全性

*/

enum NetStatus {

NET_SUCEESS,

NET_ERROR,

NOT_NET,

NET_FAILURE

};

下面我们来看一个示例 , 来大致了解一下枚举的使用场景:

/*枚举*/

/*

枚举(列举所有的情况)

限定值,保证取值的安全性

*/

enum NetStatus {

NET_SUCEESS,

NET_ERROR,

NOT_NET,

NET_FAILURE

};

/*模拟网络请求*/

void requestHttp(char* url, void(*callBack)(enum NetStatus status,char* res)) {

printf("请求地址:%s\n", url);

printf("请求网络....\n");

Sleep(2000);

enum NetStatus status = NET_SUCEESS;

char* res = "如果 爱情是一场花火 ,一闪即逝的花火,我也要去追求\n";

callBack(status, res);

}

/*网络回调函数*/

void callBackHttp(enum NetStatus status, char* res) {

switch (status)

{

case NET_SUCEESS:

printf("网络数据:\n%s", res);

break;

case NET_ERROR:

printf("请求网络错误\n");

break;

case NOT_NET:

printf("没有网络\n");

break;

case NET_FAILURE:

printf("请求网络失败\n");

break;

default:

printf("未知错误\n");

break;

}

}

/*枚举示例*/

void useEnum() {

enum NetStatus status = NET_FAILURE;

printf("枚举中元素的值:%d\n", status);

char* url = "http://www.zhuyongit.com";

requestHttp(url, callBackHttp);

}

我们模拟了网络请求的几种情况 , 成功 , 失败 , 错误等等 , 通过枚举将这些情况列举出来 ,然后通过网络回调函数传递到网络处理函数 , 通过switch分支语句来进行不同网络状态的判断 。

在jni.h头文件中 , 我们也可以见到类似的应用:

typedef enum jobjectRefType {

JNIInvalidRefType = 0,

JNILocalRefType = 1,

JNIGlobalRefType = 2,

JNIWeakGlobalRefType = 3

} jobjectRefType;

使用枚举来标识对象引用的类型 , 本地引用,全局引用,弱引用,等等 ,因为我们在使用jni调取java对象的时候 , java虚拟机并没有将引用数加1 , 所以我们需要用过加强引用类型 , 来保证jni引用的java对象,不被虚拟机回收掉 。

在IT的路上 , 山路崎岖 , 山崖陡峭 , 自学如在荆棘满布的丛林中 , 披荆斩棘 , 在浑浊的河流中 , 摸着石头过河 。何以保证我们走的是正确的方向 , 长沙动脑学院 , 老司机众多 , 功力深厚 , 开车稳当 , 都是互联网老兵 , 他们是IT路上的探头灯 , 帮你指明方向 , 带你超神 , 他们的宗旨是:做一家受人尊敬的企业,做一位受人尊敬的老师【动脑学院】。 --- 特约赞助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值