关于NDK这个分类在N年前就已经创建了,但是一直木有系统的记录其学习过程,当然也没真正学会NDK的技术真谛,所以一直也是自己的一个遗憾,而如今对于Android程序员的要求也是越来越高,对于NDK也是应对高级职称时被很多公司所看中的,如今像热修复之类的也或多或少会用到一个NDK的东东,所以今天起下决定要来弥补这一门空缺的技术,而且是从浅到深一点点来记录,等坚持到彻底掌握之后再回过头来我想这些点滴也是一笔非常非常宝贵的财富,一定要坚持!!!!

为了学得更加扎实,语言关C、C++必须得过,说实话前几年也认真学习过它们,但是!太久时间木有用过了,也遗忘得差不多了,所以先来一个语言的整体的复习,虽说枯燥,但是这也是为NDK更加深入的学习打下良好的基石,下面开始:

基本数据类型:

这里采用的开发工具为CLion,比较轻巧又好用,而且因为它是Jet Brains出品的,而Android Studio也是它出品,所以对于里面的操作可以说是无缝连接,话不多说直接新建一个C工程:

环境一切正常,接下来看一下C语言中的基本数据类型,对于它分为两种:

1、signed 有符号的类型,也就是支持正负号的。

2、unsigned 无符号的类型,也就是没有负号,取值从0开始。

对于上面声明的这个整形变量默认就是有符号的,如果想声明成无符号的则在int前面加unsigned关键字既可:

那思考一下:有符号和无符号的数据类型有啥区别呢?其实就是取值范围不一样,下面看一张对照表:

基本跟java基本数据类型差不多,C中的基本整形数据类型为:int 、short、long、char。其中发现上面int 和 long在C中占的字节数是一样的,都是占4个字节,这个有别于java,在java中long是占8个字节嘛,下面可以用sizeof()来打印一下其类型的长度:

呃,那图中的说得不对呀,对于这个其实是随编译器而异的,下面来总结一下不同编译器下的基本数据类型所占的字节数:

16位编译器

char :1个字节
char*(即指针变量): 2个字节
short int : 2个字节
int:  2个字节
unsigned int : 2个字节
float:  4个字节
double:   8个字节
long:   4个字节
long long:  8个字节
unsigned long:  4个字节

32位编译器

char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   4个字节
long long:  8个字节
unsigned long:  4个字节

64位编译器

char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   8个字节
long long:  8个字节
unsigned long:  8个字节

另外对于数据类型还有类似的这种写法:

其实long int = long;在标准中规定int至少要和short一样长,long至少要和int一样长。

在实际中可能会用一个更加清晰的数据类型,如:

其实用的就是定义好的宏,具体来看一下它的定义就明白了:

这种写法是被推荐的,因为会比较清晰。

基数数据类型除了上面的整型之外,还有浮点型,具体如下表:

另外需要注意:在C中并没有专门的boolean类型,而是:非0既true、非null为true;

输出格式化:

对于C的输出函数print()函数是不能直接来打印变量的,如下:

必须要写一个格式化占位符参数,其实跟java中的String.format()的用法类似,如:

而其中的“%d”表示输出整型变量,那对于其它数据类型其输出占位符又如何写呢,其它之前的表格中已经有说明,如下:

虽说"%d"可以输出所有的整型,但是还是用上图中对应的输出会更加精准。

另外sprintf()这个函数在实际当中也非常常用,比如要打印某个目录下的按规律生成的文件,比如:

这时就可以采用该函数了,下面模拟一下:

也就是將2、3参数格式化的字符复制到str当中。

数组与内存布局:

在C中声明数组必须指定长度,或者声明与赋值写在一起,如下:

另外它是在栈上分配内存的,而栈上的内存是有限制的,在mac上可以使用“ulimit -a”来查看其最大栈内存:

也可以直接用“ulimit -s”来只看栈大小:

也就是最大栈的大小是8192K,但是需要注意:并不是我们程序也能申请这么大的栈内存的,因为像程序的一个函数参数,返回值等也是存放在栈中的。另外栈内存出了作用域就会自动释放掉,所以不需要手动去回收的。

前面说了栈大小不是特别大,那如果对于要的内存超过栈大小的该怎么办呢,当然就是在堆中进行申请喽,此时就存在以下几种堆中申请内存的一些函数,下面来说明下:

  • malloc:在堆中申请内存但不会对其申请的内存进行初始化,如在堆中申请1MB的内存:

    另外还需要注意:由于申请的内存还没初始化,所以一般在malloc申请内存之后会使用memset保存其申请的内存是一片纯白的,而不是用了之前的脏数据,因为申请内存有可能会重用之前的内存,具体用法如下:

    还有一点需要注意:堆中申请的内存是不会自动释放的,需要手动去释放,如下:

  • calloc():申请内存并将内存初始化为null,具体用法:

    其实它就等价于:

  • realloc():重新对malloc申请的内存大小进行调整,如下:

    那什么场景会用到它呢,这里举一个TCP传输粘包问题,比如发送“1,2,3,4,5,6”数据,而接收的时候可能分几次才能接收完,比如是先接收到了“1,2,3”,之后再接收到了“4,5”,最后接收了“6”,至此才将数据接收完,那此时的缓冲区char首先申请的是3个字节,于是乎“1、2、3”刚好接收满了,但此时还不是一个完整的数据包,所以还得接着等“4,5,6”,当接收到了“4、5”了,就需要对缓冲区进行扩容用以存放这两个字节了,同样的最后接收到了"6",则继续再要对缓存冲再扩容一个字节。 当然直接申请一个足够大的缓存区不就不用扩容了么,这是因为数据包的大小是无法确定的,这里只是为了说明问题举了个简单的粟子而已。

  • alloca():向栈中申请内存,了解一下既可,用得比较少。用法如下:

ndk学习之C语言基础复习----基本数据类型、数组的更多相关文章

  1. ndk学习之C语言基础复习----虚拟内存布局与malloc申请

    在这一次中来学习一下C语言的内存布局,了解它之后就可以解释为啥在用malloc()申请的内存之后需要用memset()来对内存进行一下初始化了,首先来了解一下物理内存与虚拟内存: 物理内存:通过物理内 ...

  2. ndk学习之c++语言基础复习----C++容器、类型转换、异常与文件流操作

    继续来复习C++,比较枯燥,但是这是扎实掌握NDK开发的必经之路,不容小觑. 容器: 容器,就是用来存放东西的盒子. 常用的数据结构包括:数组array, 链表list, 树tree, 栈stack, ...

  3. ndk学习之c++语言基础复习----面向对象编程

    关于面向对象编程对于一个java程序员那是再熟悉不过了,不过对于C++而言相对java还是有很多不同点的,所以全面复习一下. 类 C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程 ...

  4. ndk学习之c++语言基础复习----C++线程与智能指针

    线程 线程,有时被称为轻量进程,是程序执行的最小单元. C++11线程: 我们知道平常谈C++线程相关的东东基本都是基于之后要学习的posix相关的,其实在C++11有自己新式创建线程的方法,所以先来 ...

  5. ndk学习之C语言基础复习----结构体、共用体与C++开端

    自己实现sprintf功能: 关于C中的系统函数sprintf在上次[https://www.cnblogs.com/webor2006/p/7545627.html]学习中已经用到过了,这里再来回顾 ...

  6. ndk学习之C语言基础复习----指针、函数、预处理器

    指针: 指针乃C.C++的灵魂之所在,所以有必要好好的复习复习.什么是指针?一句话来概括:“指针是一个变量,它的值是一个地址.”,其中指针变量的声明有如下三种形式: 其中第一种是被推荐的写法. 其中还 ...

  7. MySQL学习笔记_8_SQL语言基础复习

    SQL语言基础复习 一.概述 SQL语句注释方式 1)以"#"开头直到行尾的所有内容都是注释 2)以"--"(--后还有一个空格)开头直到行尾的所有内容都是注释 ...

  8. GO学习-(5) Go语言基础之基本数据类型

    Go语言中有丰富的数据类型,除了基本的整型.浮点型.布尔型.字符串外,还有数组.切片.结构体.函数.map.通道(channel)等.Go 语言的基本类型和其他语言大同小异. 基本数据类型 整型 整型 ...

  9. Java学习笔记:语言基础

    Java学习笔记:语言基础 2014-1-31   最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...

随机推荐

  1. 一步步分析Java深拷贝的两种方式-clone和序列化

    今天遇到一道面试题,询问深拷贝的两种方法.主要就是clone方法和序列化方法.今天就来分析一下这两种方式如何实现深拷贝.如果想跳过解析的朋友,直奔"重点来了!"寻找答案. clon ...

  2. 玩转ELK之三件套安装配置详解

    ELK是啥子??? ELK 是elastic公司提供的一套完整的日志收集以及展示的解决方案,是三个产品的首字母缩写,分别是ElasticSearch.Logstash 和 Kibana. 特点: 收集 ...

  3. 【转载】Bios报警声

    BB是报警的声音你可以根据报警声音长短,数目来判断问题出在什么地方 AWARD BIOS响铃声的一般含义是: 1短: 系统正常启动.这是我们每天都能听到的,也表明机器没有任何问题. 2短: 常规错误, ...

  4. rqnoj PID95:多多看DVD(加强版)

    题目描述 多多进幼儿园了,今天报名了.只有今晚可以好好放松一下了(以后上了学后会很忙).她的叔叔决定给他买一些动画片DVD晚上看.可是爷爷规定他们只能在一定的时间段L看完.(因为叔叔还要搞NOIP不能 ...

  5. 1、Ubuntu linux下同步windows火狐foxfire 浏览器收藏夹问题

    最近在ubuntu系统中使用自带的firefox浏览器,发现有一些问题,比如登陆后,书签,历史记录等,原本在windows下同步的数据无法同步,添加书签的功能也无法使用. 经过查询资料后得知,unbu ...

  6. sql数据库的基础语句

    1, 创建数据库 create database database-name 2, 删除数据库 drop database dbname 3, 备份sql server 创建 备份数据的device ...

  7. RocketMQ源码学习--消息存储篇

    转载. https://blog.csdn.net/mr253727942/article/details/55805876 1.序言 今天来和大家探讨一下RocketMQ在消息存储方面所作出的努力, ...

  8. [DEBUG] spring boot在eclipse中用maven打包成jar访问templates报500错误

    更新:打war包的话只要把html文件放在resources/templates下即可,根本不需要放外面. 配置application.yml和templates放外面这种做法,打war包确实不行. ...

  9. Scala 孤立对象和单例对象方法体的用法和例子

    [学习笔记] 1  以object关键字修饰一个类名,这种语法叫做孤立对象,这个对象是单例的. 相当于将单例类和单例对象同时定义.相当于java中的单例,即在内存中只会存在一个Test3实例.创建一个 ...

  10. spark调优篇-数据倾斜(汇总)

    数据倾斜 为什么会数据倾斜 spark 中的数据倾斜并不是说原始数据存在倾斜,原始数据都是一个一个的 block,大小都一样,不存在数据倾斜: 而是指 shuffle 过程中产生的数据倾斜,由于不同的 ...