1.Bionic
Bionic是android平台为使用C和C++进行原生应用程序开发所提供的的POSIX标准C库。
Bionic提供C标准库宏、类型定义、函数、android特有的特性。
特性:
- 内存管理
- 文件输入输出
- 字符串操作
- 数学
- 日期和时间
- 进程控制
- 信号处理
- 网络套接字
- 多线程
- 用户和组
- 系统配置
- 命名服务切换
2.C语言的动态内存管理
#include <stdlib.h>//需要此库
void * malloc(int size)
//申请内存
int *a = (int *) malloc(sizeof(int) * 16);
//释放内存
void free(void* memory);
//为了避免意外使用无效指针,最好在释放后置NULL
a=NULL;
//根据新的内存大小来扩展或者缩小
//如果重新分配成功,返回重新分配的指针;失败,则保留原来的动态内存分配不变并返回NULL。
a =(int *) realloc(a, sizeof(int) * 10);
3.C++的动态内存管理
使用new 申请动态内存
//单个元素的动态内存分配
int *m = new int;
//多个元素的动态内存分配
int *mm = new int[10];
使用delete来释放内存
delete m;
delete[] mm;
通过malloc分配的内存块必须用free关键字释放。
通过new关键字分配的内必须由相应的delete关键字释放。
4.标准文件I/O
标准C库提供了两种文件I/O
低级I/O:原始的I/O函数,更加适合处理数据流。
流I/O:更高级别的、可缓冲的I/O函数、更适合处理数据流。
(1)标准流
- stdin:应用程序标准输入流
- stdout:引用程序标准输出流
- stderr:应用程序标准错误流
(2)写入流
//打开流
FILE *f = fopen("/sdcard/Download/test.txt", "w");
if (f == NULL) {
//没有打开,返回NULL指针
} else {
//与流交互
}
写入数据
char c[] = {'c', 'a', '\n'};
int count = sizeof(c) / sizeof(c[0]);
//fwrite返回实际写入流的元素个数
if(count != fwrite(c, sizeof(char),count,f)){
//出现错误
}
fclose(f);
//如果不能写入,则返回EOF
if (EOF == fputs("hello", f)) {
//出现错误
}
fclose(f);
向流写入单个字符
char c = 'a';
//如果字符不能被写入流,则fputc函数返回EOF,否则,返回字符本省。
if (c != fputc(c, f)) {
//出现错误
}
fclose(f);
向流中的写入有格式的数据
//fprintf返回写入流的字符个数,出错的情况下,返回一个负数
int code = fprintf(f, "The %s is %d", "number", 2);
if (0 <code) {
//错误
}
fclose(f);
刷新缓冲区
在一下情况下会自动刷新缓冲区:
- 引用程序正常终止
- 在行缓冲时写入新行
- 当缓冲区已满
- 当流被关闭
手动刷新缓冲区
fprintf(f, "The %s is 123", "number");
//如果缓冲区不能写入,fflush函数返回EOF;否则返回0
fflush(f);
(3)读取流
char buff[5];
int count = 4;
//读取count个sizeof(char)大小的元素放入缓冲区buff
//返回实际读取的元素个数
if (count != fread(buff, sizeof(char), count, f)) {
//错误
}
读取字符序列
char buff[1024];
if (NULL == fgets(buff,1024,f)) {
//错误
}else{
__android_log_print(ANDROID_LOG_INFO, "buff", "%s", buff);
}
读取单个字符
int result;
result = fgetc(f);
if (EOF == result) {
//错误
} else {
unsigned char ch = (unsigned char) result;
__android_log_print(ANDROID_LOG_INFO, "test", "%c", ch);
}
从流中读取格式数据
char s[5];
int i;
//读取成功,返回读取的项目个数;若有错误,则返回EOF
if (2 != fscanf(f, "The %s is %d", s, &i)) {
//错误
}
__android_log_print(ANDROID_LOG_INFO, "123321", "%s%d", s, i);
检查文件结尾
char buff[1024];
//文件到达末尾返回一个非零值;如果可以从流中读取更多数据,则返回零。
while (0 == feof(f)) {
fgets(buff, 1024, f);
__android_log_print(ANDROID_LOG_INFO, "123321", "%s", buff);
}
搜索位置
int fseek(FILE *stream,long offset,int whence);
offset:相对偏移量
whence:
SEEK_SET:偏移量相对于流的开头
SEEK_CUR:偏移量相对于当前位置
SEEK_END:偏移量相对于流结尾
fputs("123456", f);
fseek(f, -6, SEEK_CUR);
fputs("654321", f);
fflush(f);
错误检查
ferror(FILE* stream )
关闭缓冲流
flose(FILE* stream)
if(0 != fclose(f)){
//错误可能是磁盘空间不足,缓冲的输出不能写入到流中
}
5.与进程交互
(1)执行shell命令
int result;
result = system("mkdir /data/data/com.example.testnt/test");
if (-1 == result || 127 == result) {
//执行失败
}
(2)与子进程通信
FILE *popen(const char* command,const char* type);
int pclose(FILE* stream);