C++学习路线(十六)

news/2024/10/16 16:01:58 标签: c++, 学习, 开发语言

void类型指针

void -> 空类型

void* -> 空类型指针,只存储地址的值,丢失类型,无法访问,要访问里面的值

我们必须对指针进行正确的类型转换,然后再间接引用指针

所有其它类型的指针都可以隐式自动转换成 void 类型指针,反之需要强制转换。

int arr[] = { 1, 2, 3, 4, 5 };
char ch = 'a';
void* ptr = arr;
printf("0x%p\n", ptr);
printf("%d\n", *(int*)ptr);

而且 void*指针 不允许算术运算

常见错误总结

1.使用未初始化指针

这里面去描述两种场景说明使用未初始化指针的场景

第一种场景 未初始化就使用

int x, * p;
x = 10;
printf("%p\n", p);
p = &x;

第二种场景 比较常见

void func(int* p) {
    static int count = 50;
    p = &count;
}

int main() {
    int x, * p;
    func(p);
    cout << "p = " << p << endl;
}

怎么解决上面的问题 之前的笔记有提到过 使用二级指针

#include <iostream>
using namespace std;

void func(int** p) {
	static int count = 50;
	*p = &count;
}

int main() {
	int x, * p;
	func(&p);
	cout << "p = " << p << endl;
}

2.将值当作地址赋值给指针

怎么解决

1)*p = x;

2)p = &x;

3.忘记解引直接访问内存

char input[64] = { 'h', 'e', 'l', 'l', 'o' };
char* p1, * p2;
p1 = &input[0];
p2 = &input[1];
if (p1 > p2) {
	cout << "p1 is greater than p2" << endl;
}
else {
	cout << "p2 is greater than p1" << endl;
}
return 0;

这种情况下 会打印 "p2 is greater than p1"

#include <iostream>
using namespace std;

int main() {
	char input[64] = { 'h', 'e', 'l', 'l', 'o' };
	char* p1, * p2;
	p1 = &input[0];
	p2 = &input[1];
	if (*p1 > *p2) {
		cout << "p1 is greater than p2" << endl;
	}
	else {
		cout << "p2 is greater than p1" << endl;
	}
	return 0;
}

4.常见的错误4:再次使用忽略重新赋初值

#include <iostream>
#include <string>
using namespace std;

int main() {
	char input[64];
	char* p1 = input;
	do {
		gets_s(input, 64);
		while (*p1 != '\0') printf("%c", *p1++);
	} while (strcmp(input, "exit") != 0);
	return 0;
}

这种只能打印第一个数字 因为p1没有被重新赋值给input

正确的做法是

#include <iostream>
#include <string>
using namespace std;

int main() {
	char input[64];
	char* p1;
	do {
		printf("Enter a string: ");
		gets_s(input, 64);
		p1 = input;
		while (*p1 != '\0') printf("%c", *p1++);
		printf("\n");
	} while (strcmp(input, "exit") != 0);
	return 0;
}

常量引用

在C++中可以声明const引用

语法:const Type&name = var;

const引用让变量拥有只读属性

分两种情况:
1.用变量初始化常引用
2.用字面量初始化常量引用
// 使用变量初始化常量引用
int a = 10;
const int& b = a;
// 用字面量初始化常量引用
const int& c = 20;//会给引用分配内存空间

函数指针

我们来探究一下 函数有没有指针

#include <iostream>
#include <string>
using namespace std;

int compare_int(const void* a, const void* b) {
	int* pa = (int*)a;
	int* pb = (int*)b;
	cout << "pa地址:" << &pa << endl;
	cout << "pb地址:" << &pb << endl;
	return *pa - *pb;
}

int main() {
	// 函数有没有地址?
	cout << "compare_int: " << &compare_int << endl;
	int x = 10, y = 20;
	compare_int(&x, &y);
	return 0;
}

函数指针的定义

#include <iostream>
#include <string>
using namespace std;

int compare_int(const void* a, const void* b) {
	int* pa = (int*)a;
	int* pb = (int*)b;
	cout << "pa地址:" << &pa << endl;
	cout << "pb地址:" << &pb << endl;
	return *pa - *pb;
}

int main() {
	// 函数有没有地址?
	int(*ptr)(const void*, const void*) = &compare_int;
	int x = 10, y = 20;
	//函数指针有两种调用方式
	//1.解引用方式调用
	(*ptr)(&x, &y);
	//2.直接调用
	ptr(&x, &y);
	return 0;
}

上面这个是函数指针和void*指针的应用

#include <iostream>
#include <string>
using namespace std;

int compare_int(const void* a, const void* b) {
	int* pa = (int*)a;
	int* pb = (int*)b;
	return *pa - *pb;
}

int main() {
	// 函数有没有地址?
	int arr[12] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10, 11, 12 };
	int(*ptr)(const void*, const void*) = &compare_int;
	int x = 10, y = 20;
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), ptr);
	cout << "After sorting: ";
	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
		cout << arr[i] << " ";
	}
	return 0;
}

qsort也可以对char数组进行排序

#include <iostream>
#include <string>
using namespace std;

int compare_int(const void* a, const void* b) {
	int* pa = (int*)a;
	int* pb = (int*)b;
	return *pa - *pb;
}

int compare_char(const void* a, const void* b) {
	char* pa = (char*)a;
	char* pb = (char*)b;
	return *pa - *pb;
}

int main() {
	// 函数有没有地址?
	char charArray[] = "asodifoadfjdvn";
	int(*pCompare)(const void*, const void*) = &compare_char;
	qsort(charArray, sizeof(charArray) / sizeof(char), sizeof(char), pCompare);
	for (int i = 0; i < sizeof(charArray) / sizeof(char); i++) {
		cout << charArray[i];
	}
	return 0;
}


http://www.niftyadmin.cn/n/5708186.html

相关文章

高级算法设计与分析 学习笔记13 线性规划

注意是线性规划不是动态规划哦 好家伙&#xff0c;这不是凸优化吗&#xff1f; 凸优化标准形式&#xff1a; 先改成统一最大化&#xff08;凸优化那边怎么是统一最小化&#xff1f;&#xff09; 原来的x2正负无所谓&#xff0c;但我希望每个x都是有限制的&#xff0c;所以把它改…

【整合包及教程】第二代GPT-SoVITS V2:革新声音克隆技术

随着人工智能技术的飞速发展&#xff0c;语音克隆技术也在不断进化。近期推出的第二代GPT-SoVITS V2&#xff0c;以其强大的功能和易用性&#xff0c;成为该领域的一大突破。GPT-SoVITS V2不仅能够基于少量的语音样本&#xff08;例如1分钟的音频&#xff09;来克隆音色&#x…

深入解析 Go 语言接口:多接口实现与接口组合的实际应用

文章目录 一、引言二、一个类型实现多个接口1. 定义多个接口2. 类型实现多个接口3. 使用多个接口 三、接口的组合1. 接口嵌套2. 实现复合接口 四、实际开发中的应用场景1. 多态与模块化设计2. 松耦合系统设计3. 测试与依赖注入4. 事件驱动架构中的应用 五、小结 一、引言 在 G…

【修订中】ffmpeg 知识点

一、两种安装方式 static FFmpeg binaries for macOS 64-bit Intel brew install ffmpeg 时间有点长 需要挂上代理 二、ffmpeg 使用这个工具去除水印以后原来水印的那个点就模糊了如何解决这个问题呢 使用 FFmpeg 的delogo过滤器去除水印时&#xff0c;通常会导致水印所…

【玩转 JS 函数式编程_014】4.1 JavaScript 纯函数的相关概念(下):纯函数的优势

文章目录 4.1 纯函数4.1.1. 引用透明 Referential transparency4.1.2. JS 函数中的副作用 Side effects4.1.3. 纯函数的优势 Advantages of pure functions ✔️1 执行顺序 Order of execution2 函数记忆 Memoization3 自带文档描述 Self-documentation4 利于测试 Testing (接上…

不用搭建服务?MemFire Cloud让开发更简单

不用搭建服务&#xff1f;MemFire Cloud让开发更简单 在当今的开发世界里&#xff0c;想要开发一个功能齐全的应用&#xff0c;往往意味着需要搭建复杂的后端、开发API接口、处理认证授权、管理数据库……这些琐碎的工作让很多开发者头疼不已&#xff0c;尤其是独立开发者或者…

关于使用conda和pip二者安装包

想安装另外的不在Anaconda中的Python包&#xff1a; 方式1&#xff1a;conda install package_name 方式2&#xff1a;pip install package_name 想升级另外的不在Anaconda中的Python包&#xff1a; conda update package_name pip install --upgrade package_name 注意&am…

《15分钟轻松学Go》教程目录

在AI快速发展的时代&#xff0c;学习Go语言依然很有用。Go语言擅长处理高并发任务&#xff0c;也就是说可以同时处理很多请求&#xff0c;这对于需要快速响应的AI服务非常重要。另外&#xff0c;Go适合用来处理和传输大量数据&#xff0c;非常适合机器学习模型的数据预处理。 …