当前位置:网站首页>The NDK portal: C
The NDK portal: C
2022-08-02 14:54:00 【Who covereth the heaven is difficult】
目录
写在前面
前两天在看AndroidSystem from boot up toSystemServerProcesses and services to create this part of knowledge,有很多C++的代码,So is going to take a one or two daysC和C++Under this part of the things a little preview,Haha I didn't dare say review,Let oneself can understand a little.So there was the birth of this content,Then put it in theNDK专栏中,Crap I also not much said,开搞!
一、Linux内存布局原理
①、内存定义
- 硬件角度:内存是计算机必不可少的一个组成部分,是与CPU沟通的桥梁,计算机中所有的程序都是运行在内存中的.
- 逻辑角度:内存是一块具备随机访问能力,支持读、写操作,用来存放程序及程序运行中产生的数据的区域.
②、内存单位
- 位(bit):是计算机中最小的数据单位,每一位的状态只能是0或1
- 字节:1Byte=8bit,Is a basic unit of measurement in memory
- KB:1KB=1024Byte,也就是1024个字节
- MB:1MB=1024KB,类似的还有GB、TB
③、内存编址
In the computer memory in bytes addressing,Each storage unit can store a byte address(8个bit)的数据,CPU通过内存地址获取指令和数据,Don't care about the space the address represents specific in what position、怎么分布,Because hardware design to ensure that an address corresponds to a fixed space,所以说:内存地址和地址指向的空间共同构成了一个内存单元.
④、Memory address and distribution rules of
- 内存地址:内存地址通常用十六进制的数据表示,指向内存中某一块区域.
- Memory address allocation rules:Memory allocation rule is continuous,一个挨着一个.When the object to apply for a memory,This object is assigned a code first to,This code is the memory address
比如:The above is a memory address map,In each byte is an object to,Don't worry as to where the object is on,We need to know is this a series of encoding is continuous.
⑤、内存对象
Pointer to the area of memory storage is the memory object,Memory object can be of different types,Specific what are the types of?
- Int:4字节
- Short:2字节
- long:4字节
- char:1字节
- double:8字节
- long double:10字节
- 引用类型
问题: C里面longWhy only type4个字节?
long和int在早期16When a computerint 2个字节,long 4个字节,The computer to now,一般32位和64位机器下long和int一样.而Java中的long类型是8个字节
⑥、内存组成
首先来看Android的内存组成:
Android APPIs based on the virtual machine to load,Memory allocation as shown in the above,The memory in the graph are in the virtual machine,虚拟机是由C和C++进行开发的,These memory out of the virtual machine is not exist.下面要说的CMemory allocation is based on the local hardware environment,Compared with android memory is much simple:
栈:栈又称堆栈,存放程序的局部变量(但不包括static声明的变量,static 意味着 在数据段中 存放变量).除此以外,在函数被调用时,栈用来传递参数和返回值.由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场.储动态内存分配,Developers need to manually assign,手工释放
堆:堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减.当进程调用malloc/free等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)/释放的内存从堆中被剔除(堆被缩减)
BSS段:通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配.
数据段:数据段(data segment)Usually refers to used to store the global variable has been initialized in the program of a memory area.数据段属于静态内存分配.
代码段:代码段就是程序中的可执行部分,Intuitive understanding of the code segment is the function of.
二、函数
2.1、函数定义
函数和JavaThe method is a concept,C是面向过程的,It is the core carrier of function.
定义:函数是一组一起执行一个任务的语句.每个C程序都至少有一个函数,即主函数main(),所有简单的程序都可以定义其他额外的函数.
//返回值 函数名 参数列表
return_type function_name(parameter list){
body of the function //函数体
}
举个最简单的例子:
#include <iostream>
//定义函数func,返回值类型为int,入参类型为void,Meaning no parameters
int func(void) {
printf("这是一个简单的函数"); //打印一句话
return -1; //Give it a return value
}
int main()
{
func(); //在main函数中进行调用
}
结果很显然,Print out the correct word:
注意:这里不能把func()函数定义在main()函数的下面,比如这样:
这样写编译器会报错:
原因:在CThe implementation of language function is top-down to load,So when it executes tomain()函数的时候,它没有发现func()函数,所以会报错.这一点跟Java是不一样的,因为Java是面向对象的,它会把整个class文件加载到内存中,Up and down so it won't have this kind of concept.CThe language of this way of execution is more similar to the front ofDOM解析,Is also a top-down parsing.
解决方案:Based on the above this kind of situation has two solutions,The first is like the above the beginning,把func()函数定义在main()函数的上面,The second way is also define a header file.h,然后在.c文件中引入:
//类似于Java中的接口,Only a function declaration,没有函数的实现
int func(void);
int func(int a, int b);
#include <iostream> //System header files with<>引进来
#include "CTest.h" //自己的头文件用""引进来
int main()
{
func(); //在main函数中进行调用
func(1, 2);
}
//定义函数func,返回值类型为int,入参类型为void,Meaning no parameters
int func(void) {
printf("这是一个简单的函数"); //打印一句话
return -1; //Give it a return value
}
int func(int a,int b) {
printf("\nThis is a function of overloaded"); //打印一句话
return -1; //Give it a return value
}
So to perform don't have any problem:
2.2、指针函数
定义:指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针.比如:
举个例子:
//返回值类型为int*,入参void*For unsigned type pointer,相当于Java中的Object,So as long as pointer types are hereOK
int* pointerFuc(void* param) {
printf("指针函数");
int a = 100;
int *b = &a;
return b; //The return value for pointer type in here,Use address operator to obtain variablea的地址
}
int main()
{
int a = 10;
pointerFuc(&a); //Pass a pointer type
}
2.3、函数指针
指针函数是一个函数,Its return value is a pointer type,The following function pointer it is not a function,而是一个变量.
定义:函数指针是指向函数的指针变量,即本质是一个指针变量.比如:
举个例子:
CTest.h
//声明了一个变量,This variable is only function
void(*funcp)(int a); //(*func)Parentheses represent its priority,一定要写
void point_func(int a);
CTest.c
int main()
{
funcp = point_func; //The functions assigned to the above definition of pointer variable,In the process of assignment does not produce call
funcp(4); //手动调用funcp(),Only here can make call
}
void point_func(int a) {
printf("函数指针\n");
}
执行结果:
三、指针数组
3.1、数组
数组是一个数据的集合,Reflected in the memory is a continuity of memory area,比如,我们可以声明一个int类型的数组,长度为3,然后使用一个指针*p指向数组的首地址,This can operate it by pointer array:
#include <iostream>;
int main() {
//定义int类型的数组
int arr[] = {10,20,30};
for (int i = 0; i < 3; i++){
printf("数组元素 %d\n", arr[i]);
}
int*p = arr; //将arr赋值给指针p,指向数组的第一个元素
*p = 88; //The first element array is modified to10
for (int i = 0; i < 3; i++)
{
printf("The modified array elements %d\n", arr[i]);
}
return 0;
}
执行结果为:
The above example pointer is the default to the first address of the array,Below we through the pointer arithmetic to modify the second element of an array of,此时我们只需要修改 *p=88; 这一行代码即可,Add the pointer1修改为*(p+1) = 88; 这样一来,The results also became like this:
3.2、指针数组
Pointer to a pointer array as the name suggests is the each element in the array,比如有一个数组arr,Its each element to store an address,Each address all point to a variable,Such arrays we call it a pointer array.
Let's define a pointer array:
#include <iostream>;
int main() {
int arr[] = {10,20,30};//定义int类型的数组
int *p[3]; //指针数组
//补充:指针优先级 () > [] > *
for (int i = 0; i < 3; i++)
{
p[i] = &arr[i]; //For each element of the pointer array assignment,&是取地址符
printf("Array elements after operation%d\n", *p[i]); //*On behalf of pointing to the variable
}
return 0;
}
注意:在指针数组中 int *p[3]; This expression is a priority,Define the priority order for:()>[ ]>*
3.3、数组指针(行指针)
定义:int (*p)[n]
优先级高,首先说明p是一个指针,指向一个整型的一维数组,长度为n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数据的长度.
指针数组:代表的是一个数组,Each element deposit is an address
数组指针:不是一个数组,只是一个变量,Storage is a pointer,Its step changed,It is the address of the first point to a two dimensional array,If the current pointer+1操作,It will point to the second row first address,It forms and pointer array are not the same.举个例子如下:
四、结构体
4.1、结构体定义
结构体类似于Java中的Java Bean,Some variables can be encapsulated as an object,同样的在C语言中,Some variables can be encapsulated into a struct,The following view structure is how to say?Here are three kinds of definition:
第一种:
#include <iostream>;
//Student相当于类名
struct Student
{
int height;
int age;
};
int main() {
struct Student stu; //声明一个struct类型的变量,类似于Java中的private Person p;
stu.height= 175; //赋值
stu.age = 18;
return 0;
}
第二种:
#include <iostream>;
//h和a表示结构变量,也就是Student类型的变量
struct Student
{
int height;
int age;
}h,a;
int main() {
h.height = 175;
h.age = 18;
return 0;
}
第三种:
#include <iostream>;
//使用typedef定义
typedef struct {
int height;
int age;
}Student;
int main() {
Student stu;
stu.height = 175;
stu.age = 18;
return 0;
}
4.2、内存对齐
在介绍这个概念之前,Us to define the structure again and how much to print the size of the structure is:
#include <iostream>;
//使用typedef定义
typedef struct {
int height;
short age;
}Student;
int main() {
Student stu;
stu.height = 175;
stu.age = 18;
printf("结构体大小%d", sizeof(stu));
return 0;
}
嗯?一个int类型,一个short类型,怎么变成8了呢?在C语言中,To the object structure allocates memory,It will follow the memory alignment rules.
定义:对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,It is known as a natural alignment.比如在32位cpu下,假设一个整型变量的地址为0x00000004,It is naturally aligned.
When structures need too much memory,使用动态内存申请.结构体占用字节数和结构体内字段有关,指针占用内存就是4/8字节,So the pointer is higher than by value efficiency.
Structure principle of storage:
- 结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
- 结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数
在32位操作系统中,数据总线是32位,地址总线是32位.Because the address bus is32位,Means addressing space is according to the4递增的,数据总线32A a read/write4byte.
Then to see such a struct:
According to the common sense should be the total takes up6个字节,But in fact it was:
五、共用体
共用体和结构体类似,Said is a collection of data type,Structure in the body just save cost more.
定义:共用体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型.可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值.共用体提供了一种使用相同的内存位置的有效方式.举个例子如下:
union Data
{
int i;
float f;
char str[20];
}data;
共用体占用的内存应足够存储共用体中最大的成员.比如在上面的案例中,In each member variables,charTake up the space is one of the biggest,所以整个Data将占用20个字节的内存空间.
The following to define a common body together:
#include <iostream>;
union MyStudent
{
int i;
float f;
};
int main() {
union MyStudent myStu;
myStu.i = 10;
myStu.f = 11;
printf("i的地址 %#x\n", &myStu.i);
printf("f的地址 %#x\n", &myStu.f);
return 0;
}
执行结果为:Can see the starting address of each member of the share in the body is the same,Only in memory, respectively is a member of the different variables
And then to modify the code:
#include <iostream>;
union MyStudent
{
int i;
int j;
};
int main() {
union MyStudent myStu;
myStu.i = 10;
printf("之前 %d\n", myStu.i);
myStu.j = 11;
printf("i的地址 %#x\n", &myStu.i);
printf("f的地址 %#x\n", &myStu.j);
printf("之后 %d\n", myStu.i);
printf("之后 %d\n", myStu.j);
return 0;
}
执行结果如下:
We found a strange results at this time,给j赋值之后,i和j的值都变成了11,这是为什么呢?
因为:It order to save the open space on the memory size,将之前iValue area of memory to reusej值,This reuse scene in general use in common body has a lot of variable declaration,最开始初始化的时候iValues in the code used to,但是在下面的代码中iValues do not need to,This saves memory performance is very high.
六、动态库
6.1、库的概念
在windows平台和LinuxPlatform has a large number of library,Android中同样也是.Library as the name implies,Refers to a container file,Inside is a function,由于windows和Linux的平台不同(Mainly is the compiler、The compiler and the connector is different),因此二者库的二进制是不兼容的.
库的种类:库分为动态库和静态库,Below are(前者为Linux平台,后者为Windows平台)Different forms of:
6.2、编译动态库
How to compile a dynamic library?看下图的流程:
Below let us have a simple practical operation,首先创建一个test.h头文件:
接着创建test.c文件,And then to realize the abovetest()函数:
最后我们使用gccThe command line to compile the generated.so文件:
补充:Compile static library use-static,动态库使用-shared
Finally, to summarize the difference between the dynamic library and static library:
- Static library file is larger,The dynamic library is small
- 静态库需要在编译时被链接在目标代码中,动态库在运行时才会被加载到目标代码
- 静态库类似于Android中的Module,一旦打包APK需要重新进行编译
- 动态库类似于Jar包,Packaging does not need to recompile
Here is simply introduced the basic meaning and the static and dynamic library library,后面还会详细说,Here have a basic understanding of line.
OK,关于CLanguage basics first say so much,咱们下一篇再见!
祝:工作顺利!
边栏推荐
猜你喜欢
随机推荐
static关键字3种作用,简单粗暴对比,好理解
Handler你真的搞懂了吗?
The Handler you really understand?
函数递归和动态内存初识
[VCU] Detailed S19 file (S-record)
St. Regis Takeaway Notes - Lecture 05 Getting Started with Redis
宝塔搭建PHP自适应懒人网址导航源码实测
spark(standalone,yarn)
关于spark
Hession使用
NDK报错问题分析方案(一)
MySQL知识总结 (四) 事务
ng-style:动态控制样式
c语言三子棋详解!!! (电脑智能下棋)(附上完整代码)
C语言一级指针(补)
统计偏科最严重的前100名学生
什么是 Web 3.0:面向未来的去中心化互联网
MySQL知识总结 (三) 索引
自定义UDF函数
无人驾驶综述:等级划分