总结学习 —— 前置定义
来源:互联网 发布:lable java 编辑:程序博客网 时间:2024/06/08 08:30
当在一个很大的工程中,需要隐藏结构体中的内容,或者中间件给用户的接口,不希望用户知道结构体的内容形式,那么,请使用前置定义。先上一个小例子:
//main.c#include <stdio.h>#include "test.h"struct Test *test;void main(void){ int ret; test = Init(); Print(test); printf("the end!\n");}
//test.h#ifndef _TEST_H_#define _TEST_H_struct Test *Init(void);void Print(struct Test * test);#endif
//test.c#include <stdio.h>#include <stdlib.h>struct Test{ char num; int flag;};typedef struct Test *TEST;TEST Init(void){ TEST test; test = (TEST)malloc(sizeof(struct Test)); test->flag = 9; test->num = 4; rerurn test;}void Print(TEST test){ printf("the result is %d,%d!\n", test->num, test->flag); free(test);}
例子比较简单,就三个文件,其中main.c和test.h可以提供给别人,为了隐藏struct Test结构体中的内容,将test.c文件编译成库文件。编译过程:第一步:gcc -o libtest.so -fPIC -shared test.c第二步:gcc -o test main.c -L ./ -l test第三步:export LD_LIBRARY_PATH=./第四步:执行程序 ./test不出什么意外会打印出正确结果,以上操作不需要root权限。这时候,你将test.c文件移走,别人就不会知道struct Test中到底有什么东西了,能够在一定程度上实现结构体数据的保密。
注意点:
(1)在main.c中定义结构体的时候,要定义成指针型变量;如果定义成为非指针变量(如struct Test test),那么会报出“incomplete type”的错误。因为定义成为非指针变量的话,程序在编译的时候会给变量分配空间,但是该变量是一个“前置定义”的变量,不知道包还有什么元素,所以会报错;定义成为一个指针后,直接分配一个地址完事。
(2)既然是“incomplete type”,在main.c中是不能够使用sizeof求出结构体的大小,即sizeof(struct Test)会报错。
(3)在main函数中定义的test指向NULL,所以不能够直接使用,通过malloc分配内存后使用。
(4)切记不要这么用:
void Init(sruct Test *test);
…
void Init(struct Test *test)
{
…
test = (struct Test *)malloc(sizeof(struct Test));
…
}
这样的话,在main函数中调用Init函数,不会得到正确的结果。
敲代码的路上需要积累,共勉。
1 0
- 总结学习 —— 前置定义
- [abap] 负号前置函数——不需要定义中间变量
- 百度地图学习总结(1)—前置准备,申请key
- 物理渲染学习笔记(一) —— 前置知识
- Perl学习(十二)——数组定义操作总结
- 【C++学习与应用总结】2: 关于类型前置声明
- 类定义与前置声明
- 1.7前置声明与定义
- 【总结】C++前置声明
- 爬虫学习的前置
- Spring框架——AOP前置通知
- #include 和前置声明——2
- 大数据前置课程—Scala
- 机箱前置USB接线的定义
- 黑马程序员—C学习笔记—补充字符串总结(定义、赋值、sizeof、strlen)
- Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解
- PSring MVC 学习总结(二)——控制器定义与@RequestMapping详解
- Spring MVC 学习总结(二)——控制器定义与@RequestMapping详解
- 人生的缓冲带
- sparkSQL用jdbc访问mysql
- 从一个小例子来看setInterval的使用
- HttpUtility.UrlDecode(),HttpUtility()escape()、encodeURI()、encodeURIComponent()区别详解以及相应的前台解码和.net后台解码
- Mongodb缓存的使用
- 总结学习 —— 前置定义
- ThreadLocal源码分析
- java泛型总结学习
- python csv文件读取reader
- Mysql常用sql(函数)
- CSS清除浮动大全共8种方法
- 系统相簿界面,通讯录界面等后标题显示的英文
- redis3.0配置文件redis.conf详解
- POJ 3280 Cheapest Palindrome (区间DP)