这是我们NDK学习的第一课,了解下c语言的数据类型和数组的内存布局

一、基本数据类型

1. 整数类型

  • signed——>有符号,可修饰 char、int。Int是默认有符号的。
  • unsigned——>无符号,可修饰 int 、char


基本类型如下

整型 字节 取值范围 占位
int 4 -2,147,483,648 到 2,147,483,647 %d
unsigned int 4 0 到 4,294,967,295 %u
short 2 -32,768 到 32,767 %hd
unsigned short 2 0 到 65,535 %hu
long 4 -2,147,483,648 到 2,147,483,647 %ld
unsigned long 4 0 到 4,294,967,295 %lu
char 1 -128 到 127 %c
unsigned char 1 0 到 255 %c


tips:

  1. 为了得到某个类型或某个变量在特定平台上的准确大小,使用 sizeof 运算符。

    表达式 sizeof(type) 得到对象或类型的存储字节大小。

  2. long int 其实就是长整型 = long 可以省去int,在标准中,规定 int至少和short一样长,long至少和int一样长。

  3. 为什么会存在long?

    long和int在早期16位电脑时候 int 2字节,long 4字节,而计算机发展到现在,一般32、64下,long和int一样。和java类比的话,java的long就是 long long 8字节

2. 浮点数类型

浮点数类型如下

浮点型 字节 精度 占位
float 4 6位小数 %f
double 8 15位小数 %lf
long double 8 19位小数 %Lf

3. 其他

关于8进制和16进制的打印显示

进制 打印参数
8进制 %o
16进制 小写: %x 大写:%X
(0x)+16进制 %#x


tips :

C99标准以前,C语言里面是没有bool,C++里面才有,C99标准里面定义了bool类型,需要引入头文件stdbool.h
bool类型有只有两个值:true =1 、false=0,因此实际上bool就是一个int所以在c/c++中 if 遵循一个规则, 非0为true,非空为true;NULL 其实也就是被define为了 0

二、格式化输出

函数printf、sprintf

将格式化的数据写入第一个参数

1
2
3
4
5
6
7
8
// 打印
char str[100];
sprintf(str, "img/png_%d.png", 1);
printf("%s", str);

//使用 0 补到3个字符
sprintf(str, "img/png_%03d.png", 1);
printf("%s", str);

三、数组与内存布局

数组 : 连续的内存

1
2
3
4
5
6
7
8
9
10
11
//java
int[] a

//c
//必须声明时候确定大小
int a[10]
//或者 直接初始化
int a[] = {1,2,3}

//大小
printf("%d",sizeof(a)/sizeof(int));

tips

栈内存限制 查看 linux:

1
ulimit -a

但是直接分配这么大不行,因为堆栈可能保存参数,返回地址等等信息

1. 动态内存申请

malloc

​ 没有初始化内存的内容,一般调用函数memset来初始化这部分的内存空间.

calloc

​ 申请内存并将初始化内存数据为NULL.

1
int pn = (int)calloc(10, sizeof(int));

realloc

​ 对malloc申请的内存进行大小的调整.

1
2
char *a = (char*)malloc(10);
realloc(a,20);

alloca

特别的:在栈申请内存,因此无需释放.

1
int *p = (int *)alloca(sizeof(int) * 10);

2. 物理内存和虚拟内存

物理内存

​ 物理内存指通过物理内存条而获得的内存空间

虚拟内存

​ 一种内存管理技术
​ 电脑中所运行的程序均需经由内存执行,若执行的程序占用内存很大,则会导致内存消耗殆尽。
​ 虚拟内存技术还会匀出一部分硬盘空间来充当内存使用。

进程分配内存主要由两个系统调用完成:brk和mmap

  1. brk是将_edata(指带堆位置的指针)往高地址推;
  2. mmap 找一块空闲的虚拟内存。

通过glibc (C标准库)中提供的malloc函数完成内存申请

malloc小于128k的内存,使用brk分配内存,将_edata往高地址推,大于128k则使用mmap

存放程序执行代码(cpu要执行的指令)

栈是向低地址扩展数据结构
堆是向高地址扩展数据结构

代码收录

https://github.com/ddssingsong/AnyNdk


 评论