当前位置: 首页 > news >正文

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;
}

相关文章:

C++学习路线(十六)

void类型指针 void -> 空类型 void* -> 空类型指针&#xff0c;只存储地址的值&#xff0c;丢失类型&#xff0c;无法访问&#xff0c;要访问里面的值 我们必须对指针进行正确的类型转换&#xff0c;然后再间接引用指针 所有其它类型的指针都可以隐式自动转换成 void 类型…...

2024年最受欢迎的AI工具与实际应用:AI技术对未来生活的深远影响

2024年最受欢迎的AI工具与实际应用&#xff1a;AI技术对未来生活的深远影响 随着2024年的到来&#xff0c;人工智能&#xff08;AI&#xff09;技术已经深入渗透到我们生活的方方面面。从日常工作到科学研究&#xff0c;AI工具的应用变得越来越广泛。无论是生成式AI工具&#…...

【网络安全】账户安全随笔

未经许可,不得转载。 作者:Enoch 原文出处:https://mp.weixin.qq.com/s/oKBpZ0F6Kl5NNmHSYCYIPw 文章目录 账户类型资金划转问题幂等ID使用错误多接口并发问题精度问题其他划转问题特殊资金盗取问题科学计数法问题账户类型 在互联网金融和电商企业中,账户安全直接关系到用…...

在线培训知识库管理系统:教育行业的新动力

在当今数字化时代&#xff0c;教育行业正经历着前所未有的变革。随着在线教育的兴起&#xff0c;如何高效地管理和传播知识成为了一个关键问题。在线培训知识库管理系统应运而生&#xff0c;它以其强大的知识整合、分享和管理能力&#xff0c;为教育行业注入了新的活力。 一、…...

【AI声音克隆本地整合包及教程】第二代GPT-SoVITS V2:声音克隆的新境界

在数字时代的浪潮中&#xff0c;个性化和创新是永恒的主题。GPT-SoVITS V2&#xff0c;作为第二代声音克隆技术&#xff0c;正以其革命性的特性和应用&#xff0c;为个人和企业打开一扇通往声音个性化的新大门。 声音克隆的新高度 GPT-SoVITS V2是由RVC变声器创始人“花儿不哭…...

博看书苑 8.8.1| 免费阅读海量图书期刊

博看书苑是一款免费的图书和期刊阅读神器&#xff0c;拥有海量的图书和期刊资源&#xff0c;涵盖了文学、历史、科技、教育等多个领域。无论你是想深入研究某个专业领域&#xff0c;还是想在闲暇时阅读一些轻松的读物&#xff0c;博看书苑都能满足你的需求。更令人惊喜的是&…...

导致动态代理无法使用的原因有哪些?

在动态代理的应用过程中&#xff0c;有时会遇到其无法正常使用的情况。这种现象可能源于多种原因&#xff0c;从网络配置到软件设置&#xff0c;了解和解决这些问题对保持代理的高效运行至关重要。本文将详细探讨导致动态代理无法使用的主要原因及对策&#xff0c;以帮助用户及…...

熟练使用Spring Boot、Spring Cloud Alibaba微服务开发框架,并深入理解其原理 学习要求

1. Spring Boot 核心理解 自动配置&#xff1a;了解 Spring Boot 的自动配置原理&#xff08;EnableAutoConfiguration&#xff09;&#xff0c;包括如何查看和定制自动配置的内容。需要能解释 Spring Boot 如何减少样板代码。Spring Boot Starter&#xff1a;熟悉各种 starte…...

2024-10-09 问AI: [AI面试题] 描述数据预处理在 AI 中的重要性

文心一言 数据预处理在人工智能&#xff08;AI&#xff09;中扮演着至关重要的角色&#xff0c;它是构建高效、准确和可靠AI模型不可或缺的步骤。以下是数据预处理在AI中重要性的详细描述&#xff1a; 1. 提高数据质量 清理和去噪&#xff1a;数据预处理可以识别和纠正数据中…...

Linux中文件的理解

✨前言✨ &#x1f4d8; 博客主页&#xff1a;to Keep博客主页 &#x1f646;欢迎关注&#xff0c;&#x1f44d;点赞&#xff0c;&#x1f4dd;留言评论 ⏳首发时间&#xff1a;2024年10月16日 &#x1f4e8; 博主码云地址&#xff1a;渣渣C &#x1f4d5;参考书籍&#xff1a…...

益安宁丸,国药准字,值得信赖

益安宁丸真品辨别唯一标准 益安宁丸是由同溢堂药业有限公司独家生产的一款中成药&#xff0c;主要用于调理心血管系统&#xff0c;广泛应用于内地市场及港澳地区。由于其疗效显著&#xff0c;益安宁丸在消费者中享有良好的声誉&#xff0c;被誉为心血管健康的守护者。然而&…...

Django项目的创建及说明(详细图解版)

Django项目的创建及说明 1、安装Django2、创建项目2.1、利用终端创建项目2.2、利用Pycharm企业版创建项目 3、默认文件介绍 1、安装Django 在终端输入下述命令行。 pip install django安装成功后执行如下命令查看Django是否安装好&#xff0c;若正确显示出Django版本号则安装…...

MySQL 9从入门到性能优化-二进制日志

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…...

Cloudlog delete_oqrs_line 未授权SQL注入漏洞复现

0x01 产品简介 Cloudlog 是一个自托管的 PHP 应用程序,可让您在任何地方记录您的业余无线电联系人。使用PHP和MySQL构建的基于Web的业余无线电记录应用程序支持从HF到微波的一般站记录任务 0x02 漏洞概述 Cloudlog delete_oqrs_line 接口存在未授权SQL注入漏洞,未经身份验…...

【Linux】解锁软硬链接奥秘,高效动静态库管理的实战技巧

软硬连接和动静态库 1. 软链接1.1. 概念1.2. 特点1.3. 应用场景 2. 硬链接2.1. 概念2.2. 硬链计数2.3. 特点2.4. 应用场景 3. 动静态库3.1 库存在的原因3.2. 静态库制作与使用3.2.1 打包3.2.2. 使用 3.3. 动态库制作与使用3.3.1. 打包3.3.2. 使用 4. 解决动态库查不到的4种方法…...

【设计模式】Python 后端开发中的工厂模式设计与实现

Python 后端开发中的工厂模式设计与实现 1. 引言 在后端开发中&#xff0c;如何设计一套易于扩展、可维护且灵活的系统架构是开发者面临的重要课题。设计模式在这一过程中扮演了至关重要的角色&#xff0c;尤其是在面向对象编程中&#xff0c;它提供了大量解决重复问题的标准…...

划重点!入门安全测试,这几点要注意!

朋友们&#xff0c;今天我们一起来学习下如何做安全测试。 那么首先&#xff0c;什么是安全测试&#xff1f; 安全测试是评估和验证软件系统、应用程序或网络的安全性和强度的过程。其目标是发现和修复潜在的安全漏洞和脆弱性&#xff0c;以确保系统能够抵御恶意攻击和未授权…...

mysql 09 独立表空间结构

表空间中的页实在是太多了&#xff0c;为了更好的管理这些页面&#xff0c;设计 InnoDB 的大叔们提出了 区 &#xff08;英文名&#xff1a; extent &#xff09;的概念。对于16KB的页来说&#xff0c;连续的64个页就是一个 区 &#xff0c;也就是说一个区默认占用1MB空间大小。…...

linux 虚拟环境下源码安装DeepSpeed

第一步&#xff1a;创建虚拟环境&#xff1a; conda create -n deepspeed python3.10 第二步&#xff1a;进入虚拟环境&#xff0c;安装Pytorch 2.3.1 # CUDA 12.1 conda install pytorch2.3.1 torchvision0.18.1 torchaudio2.3.1 pytorch-cuda12.1 -c pytorch -c nvidia 第…...

常见八大排序算法

今天我们带来数据结构中常见的8大排序算法。 排序算法平均时间复杂度最好情况最坏情况空间复杂度稳定性冒泡排序O(n方)O(n方)O(n方)O(1)稳定插入排序O(n方)O(n方)O(n方)O(1)稳定选择排序O(n方)O(n方)O(n方)O(1)不稳定希尔排序O(n1.3方到1,5方)O(n)O(n方)O(1)不稳定堆排序O(n lo…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...