跟我一起学NDK-C++基础知识
前言
NDK 采用 C/C++ 语言进行开发,所以学习 NDK 开发之前我们先来补充下必要的 C/C++ 知识。C++ 是对 C 语言的升级,C++ 程序设计语言可以归结为 C 程序设计语言的语法 + 面向对象程序设计,因此本课程只介绍 C++ 程序设计语言。相信 Android 应用层开发的同学对于 Java 语言能够得心应手,本课程对于 C++ 程序设计语言的不少知识会用 Java 类推
基准语法
- 注释,和 Java 一致
单行
1 |
|
多行
1 |
|
语句之间用 ; 分隔,和 Java 一致
代码块包含在 {} 内,和 Java 一致
大小写敏感
数据类型
基本数据类型
基本数据类型的大小在不同机器上会有所不同
类型 | 关键字 | 大小 |
---|---|---|
布尔型 | bool | 1个字节 |
字符型 | char | 1个字节 |
整型 | int | 4个字节 |
浮点型 | float | 4个字节 |
双浮点型 | double | 8个字节 |
无类型 | void | / |
宽字符型 | wchar_t | 2字节 |
sizeof() 函数可以获取各数据类型所占字节数
类型修饰符
一些基本类型可以使用一个或多个类型修饰符进行修饰,修饰符修饰会改变所占内存大小
- signed
- unsigned
- short
- long
类型 | 大小 | 范围 |
---|---|---|
unsigned char | 1个字节 | 0 到 255 |
signed char | 1个字节 | -128 到 127 |
unsigned int | 4个字节 | 0 到 4294967295 |
signed int | 4个字节 | -2147483648 到 2147483647 |
short int | 2个字节 | -32768 到 32767 |
long int | 8个字节 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 |
long double | 16个字节 | +/- 1.7e +/- 308 (~15 个数字) |
定义新类型
关键字:typedef
语法:typedef type newname;
1 |
|
定义了新类型 feet,使用和 int 一致
其实 wchar_t 类型是这样来的
1 |
|
变量
语法:数据类型 变量名1,变量名2;
1 |
|
常量
语法:const 数据类型 常量名 = 常量值;
常量名一般用大写,运行时无法改变其数值,如果申明时并未设置初始值,那么之后无法再设置数值
1 |
|
也可以使用宏定义的方式
1 |
|
运算
包括赋值运算、算术运算、比较运算、逻辑运算、递增递减运算以及位运算,这些运算都和 Java 一致。浮点数的余数运算用 fmod(a,b) 函数
数据类型转换
自动转换
数值范围大的作为优先转换的对象,转换顺序如下:
double <- float <- unsigned long <- long <- unsigned int <- int
强制转换
语法:(强制转换类型名称) 表达式或变量;
1 |
|
转型运算符
运算符 | 说明 |
---|---|
static_cast | 转换数据类型 |
const_cast | 转换指针或引用的常数类型 |
dynamic_cast | 转换类继承体系中的对象指针或引用 |
reinterpret_cast | 转换无关联的数据类型 |
如下,用 static_cast 将变量 two 从 double 类型转换为 int 类型
1 |
|
流程控制结构
包括顺序结构、选择结构(if else)、循环结构(for、while/do while),都和 Java 一致
数组
数组定义
语法:数据类型 数组名[数组大小]; 或 数据类型 数组名[] = {值1,值2,…};
1 |
|
数组赋值取值
语法:数组名[下标] = 值;
1 |
|
字符串
数组形式
语法:char 字符串变量[] = “初始字符串”;
1 |
|
String 类
语法:string 字符串变量 = “初始字符串”;
1 |
|
String 类成员函数:
运算符 | 功能 | 用法 |
---|---|---|
append() | 串接字符串 | str.append(str2) |
assign() | 字符串赋值 | str.assign(str2) |
compare() | 比较两个字符串 | str.compare(str2) |
replace() | 替换字符串 | str.replace(开始位置,长度,str2) |
insert() | 插入字符串 | str.insert(开始位置,str2) |
erase() | 清除字符串的部分内容 | str.erase(开始位置,清除字符数) |
length() | 获取字符串的长度 | str.length(); |
size() | 获取字符串大小 | str.size(); |
find() | 寻找字符串 | str.find(str2); |
substr() | 获取字符串的部分子串 | str.substr(开始位置,长度); |
empty() | 判断是否为空字符串 | str.empty(); |
at() | 获取指定位置字符 | str.at(n);//n为第n个字符 |
函数
语法:
1 |
|
如:
1 |
|
有默认值的参数务必放置在参数行的尾端
C++ 从上往下编译程序代码,如果在前面调用了后定义的函数,则必须在调用前加声明
预处理指令
C++ 程序在开始进行编译前会先进行一项预处理操作,将程序中那些以 # 符号开头的预处理指令进行特别的处理。预处理指令不会翻译为机器码,只在编译之前起作用。因为预处理指令不是 C++ 语句,所以并不需要以分号 “;” 结束
- #define 宏定义指令
#define 是一种替换指令,可以用来定义宏名称,并且替换程序中的数值、字符串、程序语句或者函数
语法如下:
1 |
|
宏函数是一种可以传递参数来替换简单函数功能的宏,参数不需要指定类型
语法如下:
1 |
|
1 |
|
如果想要取消 #define 所声明的宏时,只要使用下面的语法声明即可。取消之后不可以再使用
1 |
|
标准预处理宏
宏名称 | 说明 |
---|---|
LINE | 正在编译的行在源文件的行号 |
FILE | 被编译的源文件的文件名 |
DATE | 存储编译开始的日期 |
TIME | 存储编译开始的时间 |
- #include 指令
#include 指令也是一种宏命令,可以将指定的头文件包含到源文件中(类似于 Java 的 import),实际上是用头文件中的声明替换,有两种指定方式
- #include <文件名>
编译程序将到默认的系统目录中查找指定的头文件,一般为系统头文件
1 |
|
- #inclide “”
编译程序将到当前程序文件的工作目录中查找指定的头文件,一般为自定义头文件
1 |
|
- 条件编译指令
有几个指令可以用来有选择地对部分程序源代码进行编译,这个过程被称为条件编译。条件预处理器的结构与 if 选择结构很像。共有六种:#if、#else、#elif、#endif、#ifdef、#ifndef
#if 指令类似于 if 条件语句,#else 指令类似于 else 条件语句,#elif 类似于 else if 条件语句,#endif 条件编译结束标识
语法如下:
1 |
|
#ifdef 如果定义了某宏定义标识符,#ifndef 如果没有定义某宏定义标识符
语法如下:
1 |
|
1 |
|
头文件
通常在一个 C++ 程序中,包含两类文件——.cpp 文件和 .h 文件。.cpp 文件被称为 C++ 源文件,.h 文件被称为 C++ 头文件
C++ 语言支持“分别编译”,b.cpp 中想要调用 a.cpp 中定义的函数,并不需要知道 a.cpp 的存在,只需要添加 a.cpp 函数相对应的声明。定义只能定义一次,声明可以多次声明
如 a.cpp 中定义个一个 add 的函数
1 |
|
在 b.cpp 中可以这样使用
1 |
|
源文件中维护大量的声明特别麻烦,同时会带来多次声明的重复工作。一旦定义发生改变,需要修改的地方众多
所以 C++ 语言提出了头文件的概念。你只需要在头文件中声明一次,在实现文件中定义一次。在所有需要用的文件中,就只需要引用这个头文件,相当于每个文件都包含了一个声明
头文件中应该包含下面内容:
- 类的声明(包含类里面的成员和方法)
- 函数原型
- #define 常量
命名空间
因为 C++ 中不存在 Java 的 package 概念,对于不用库相同名称的函数、变量等无法区分,所以引入了命名空间的概念
语法如下:
1 |
|
为了调用命名空间的函数或变量,需要在前面加上命名空间的名称
1 |
|
您可以使用 using namespace 指令,这样在使用命名空间时就可以不用在前面加上命名空间的名称。这个指令会告诉编译器,后续的代码将使用指定的命名空间中的名称
1 |
|
extern 关键字
extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义,表明当前只是声明
当 extern 和 “C” 一起使用的使用有其他含义,如: extern “C” void fun(int a, int b)。告诉编译器在编译 fun 这个函数名时按着 C 的规则去翻译相应的函数名而不是 C++ 的,C++ 的规则在翻译这个函数名时会把 fun 这个名字变得面目全非
异常处理
跟 Java 类似,语法如下:
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!