一、C和C++的混合编程
当C++程序使用C语言接口时,需要声明为外部C接口
extern "C"
{
//添加使用到的C语言接口文件
}
//extern "C" 在这里面的内容都采用gcc编译器进行编译,不使用g++进行编译
练习:使用C++与C接口完成文件写入的功能
#include <iostream>
using namespace std;
extern "C"
{
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
}
int main()
{
int fd = open("1.txt", O_CREAT | O_RDWR, 0777);
if(fd < 0)
{
cout << "创建文件失败" << endl;
}else{
cout << "创建文件成功" << endl;
}
cout << "请输入数据" << endl;
char buf[1024] = {
0};
cin >> buf;
write(fd, buf, strlen(buf));
close(fd);
}
二、计算机中的内存分配
1、计算机中的内存划分
2、C语言动态分配内存的方式(堆空间)
#include <stdlib.h>
void *malloc(size_t size)//分配大小为size大小的空间
void free(void *ptr);//通过堆空间的首地址释放该空间
void *calloc(size_t nmemb, size_t size);//分配 nmemb * size 大小的堆空间
void *realloc(void *ptr, size_t size);//把ptr 的堆空间改变大小为size
void *reallocarray(void *ptr, size_t
nmemb, size_t size);//把ptr 的堆空间改变大小为size*nmemb
练习:利用上述接口分配 一块int 的堆空间 和 一块100 个int 的堆空间, 并往该堆空间中赋值,输出
#include <iostream>
using namespace std;
extern "C"
{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
}
int main()
{
int *a = (int *)malloc(sizeof(int));
*a = 10086;
cout << *a << endl;
free(a);
char *b = (char *)calloc(100, sizeof(char));
strcpy(b, "hello world");
cout << b << endl;
free(b);
}
3、C++中的动态内存分配
C++中使用new分配堆空间,使用delete释放堆空间
①、语法:分配一块堆空间
数据类型 *变量名 = new 数据类型//分配一块内存空间
int *p = new int//一条龙服务!!自己计算空间的大小,自己进行类型的转换!!
int *q = new int(10086);//支持在分配空间的时候对堆空间进行初始化
释放堆空间:
delete 变量名
②、语法:分配多块堆空间
数据类型 *变量名 = new 数据类型[size];//->size用户需要分配多少块这样的堆空间
例子: 分配100 块int 类型的堆空间
int *p = new int[100];
例子: 分配多块堆空间并初始化
int *q = new int[5]{
1, 2, 3, 4, 5};
释放多块堆空间:
delete []变量名;
练习: 分配10块 float 的堆空间,与 100 块 char类型的堆空间,并初始化输出
#include <iostream>
using namespace std;
extern "C"
{
#include <stdio.h>
#include <string.h>
}
int main()
{
float *p = new float[10]{
1.1, 2.2, 3.3, 4.4, 5.5};
cout << p[0] << endl;
char *q = new char[100];
strcpy(q, "hello world");
cout << q << endl;
delete []p;
delete []q;
return 0;
}
例子:利用new 去分配一个二维数组
#include <iostream>
using namespace std;
extern "C"
{
#include <stdio.h>
}
int main()
{
//开辟二维数组空间
int (*p)[10] = new int[10][10];
//对二维数组进行赋值
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
(p[i][j]) = j;
cout << p[i][j];
}
cout << endl;
}
delete[]p; // 释放动态分配的内存
return 0;
}
③、总结new 与 malloc 的区别
- 1、new可以自动计算数据类型的大小
- 2、new可以在分配堆空间时进行初始化,malloc不行
- 3、在分配堆空间时,使用new会调用<<类中的构造函数>>,malloc不行
在C++开发中都是用new来分配堆空间内存
三、C++中的引用
1、引用:给已知的变量取别名,内存不会在为该引用分配新的内存空间(节省内存空间)
2、引用的语法
数据类型 &引用名 = 引用的变量名
int a = 100;
int &q = a;//a与q是完全等价的
- 优点:在传参的过程中就不会分配新的变量空间,节省空间
- 使用场合:一般都用来作为参数传递,让函数直接访问数据的本身,节省临时空间的产生
练习:编写一个函数,交换两个参数的值
#include <iostream>
using namespace std;
void swap(int &a, int &b) // 正确的函数名是 swap,而不是 swep
{
int temp = a;
a = b;
b = temp;
}
int main()
{
int a = 10;
int b = 20;
// 交换 a 和 b 的值
swap(a, b); // 正确调用 swap 函数
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0; // 添加返回值,符合 main 函数的返回类型为 int
}
注意:在初始化引用时,引用的值为一个变量。如果引用的值是一个常量,需要用常量引用。
const int &p = 1000;//对常量进行引用
3、常量引用
作用:
- 1、防止引用名去修改原来的数据
- 2、对数据常量进行引用
语法:
const 数据类型 &引用名 = 引用对象
例子:
int a = 10086;
//定义常量引用
const int &p = a;//别名p无法修改a的值
//对一个常量进行引用
const int &q = 10086;
4、引用作为函数的参数
在用户不需要修改参数值得时候,我们就可以传递常量引用
int add(const int &a, const int &b)
{
return a + b;
}
int main()
{
int a = 100;
int b = 200;
//传递变量
cout << add(a, b) << endl;
//传递常量
cout << add(100, 200) << endl;
}
特殊写法:
数据类型 &&引用名 = 常量
int &&aa = 10000;
//这种引用只适用于常量引用,不能引用变量
5、引用作为函数的返回值
注意:
当引用作为函数的返回值时,需要保证函数结束后返回值的空间还存在。
引用作为返回值时一般会返回:
静态变量、全局变量、堆空间、(传递的参数引用)…
不会被释放的空间
当一个引用作为返回值时,该函数可以为左值
#include <iostream>
using namespace std;
int &ret()
{
static int a = 100;
static int b = 200;
return a; //需要返回一个值,不能返回表达式 (a + b)
}
int main()
{
int q = ret();//引用作为返回值(q = a)
cout << q << endl;
ret() = 200;//引用作为左值(a = 200)
cout << ret() << endl;
}
6、引用的注意事项
- 1、引用必须要初始化
- 2、引用一个常量时,需要使用const 常量引用 或者 &&右值引用
- 3、引用的类型必须要匹配
4、当引用被修改后就无法在改变(无法改变引用名引用的对象)