一、数据类型
sizeof():获取数据类型占用的字节数
在 C 中,int 和 long 都是 4 字节,为什么 ?
早期 16位计算机,int 2、long 4,只不过现在 int 4
在标准中,int 至少要和 short 一样长,long 至少要和 int 一样长
Java 的 long 对应 C 的 long long
二、函数
sprintf(char* const _Buffer, char const* const _Format, …)
#include <iostream>
using namespace std;
int main()
{
char str[100];
sprintf(str, "今天天气好热,都%d℃了", 31); // 先把第三个参数的值赋给第二个参数的占位符,再把第二个参数的字符串赋值给第一个参数
cout << str << endl;
getchar(); // 避免运行结果的窗口打开后立马关闭
return 0;
}
点击运行
memset(void* _Dst, int _Val, size_t _Size)
int size = sizeof(int) * 10;
int* i = (int*)malloc(size);
memset(i, 0, size); // 申请的内存可能之前被赋值过,所以使用前需要初始化
三、C 程序的内存分布
内存有物理内存、虚拟内存
物理内存:
相对于虚拟内存
通过物理内存条获得的内存空间
虚拟内存:
一种内存管理技术
在早期计算机系统中,直接使用物理内存,取决于内存条空间大小,没有进程隔离,很不安全
若执行程序占用的内存很大,内存很容易就满了,使用虚拟内存,对内存进行管理,能够均出一部分硬盘空间充当内存使用
四、动态申请内存
malloc 在堆中申请内存
动态申请内存,主要是通过 glibc(C 标准库、运行库)中定义的 malloc 等函数去申请
申请内存的过程,主要是由两个系统调用完成:一个是 brk,另一个是 mmap
什么时候使用 brk,什么时候使用 mmap?
brk:申请内存小于 128K
将内存指针往高地址推
使用释放后可能产生内存碎片,碎片可重用
较 mmap 高效
mmap:申请内存大于 128K
找一块满足大小的内存,使用后释放不会产生内存碎片
动态申请的内存注意:
内存使用前,先调用 memset() 函数对内存进行初始化
内存使用后,先使用 free() 函数去释放,然后指针指向 NULL(避免成为悬空指针,即其指向被释放的内存) // 野指针不是悬空指针
.c 和 .h:
.h:
- 头文件
- 函数声明(也可以写实现)
.c:
- 源文件
- 函数实现
五、VisualStudio 创建 cmake 项目
DN_Ndk01.h
#pragma once
#include <iostream>
// TODO: 在此处引用程序需要的其他标头。
DN_Ndk01.cpp
#include "DN_Ndk01.h" // 引入头文件
using namespace std;
int main()
{
cout << "Hello CMake。" << endl;
getchar(); // 避免运行结果的窗口打开后立马关闭
return 0;
}
CMakeLists.txt
# CMakeList.txt: DN_Ndk01 的 CMake 项目,在此处包括源代码并定义
# 项目特定的逻辑。
#
cmake_minimum_required (VERSION 3.8)
# 将源代码添加到此项目的可执行文件。
add_executable (DN_Ndk01 "DN_Ndk01.cpp" "DN_Ndk01.h")
# TODO: 如有需要,请添加测试并安装目标。
C/C++ 的 include 和 Java 的 import 区别:
include 的内容可以传递
import 的内容不能传递
为什么需要 .h 文件
.h 把函数的定义暴露出去,具体实现不暴露
include 的 “” 和 <> 区别
“”:相对路径
<>:查找系统、定义的目录
5.1 cmake 项目添加文件
新建头文件:a.h
#pragma once // 照抄 DN_Ndk01.h 第一行
#include <iostream>
// 声明一个 test() 函数
void test();
新建 cpp 文件:a.cpp
#include "a.h" // 引入 a.h 头文件
using namespace std;
// 实现头文件 a.h 中声明的 test() 函数
void test() {
cout << "test()" << endl;
}
调用 test() 函数步骤:
① 在 DN_Ndk01.h 中引入 a.h 头文件
// DN_Ndk01.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。
#pragma once
#include <iostream>
// TODO: 在此处引用程序需要的其他标头。
#include "a.h" // 添加 a.h 头文件
② 在 DN_Ndk01.cpp 中调用 test()
// DN_Ndk01.cpp: 定义应用程序的入口点。
//
#include "DN_Ndk0.h" // 引入头文件
using namespace std;
int main()
{
cout << "Hello CMake。" << endl;
test(); // 调用 test() 函数
getchar(); // 避免运行结果的窗口打开后立马关闭
return 0;
}
点击运行,发现报错,提示生成失败
解决方式
在 CMakeLists.txt 配置文件中,添加使用的源文件 a.cpp
// add_executable():生成可执行文件
// add_executable 第一个参数:对应生成可执行文件的名称
// add_executable 第一个参数之后的是源文件(不是头文件)集合,以空格隔开
add_executable (DN_Ndk01 "DN_Ndk01.cpp" "DN_Ndk01.h" "a.cpp") # 头文件可以不写,不过最好写上,方便在头文件中引入其它头文件时能够有提示
再次运行,就 o**k 了