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

C++回顾 day1

cout格式化输出

cout << setiosflags(ios::left) << setw(8) << a << endl;

重载:名字相同,意义不同

函数名相同,参数列表不同(类型,个数,顺序) 返回值类型不构成重载

先严格进行匹配,匹配到则执行对应算法

再隐式转换寻求匹配,匹配到则执行对应算法

隐式转换:C++允许将较小范围的类型自动转化为较大范围的类型(如int到long、double),或者将数值类型转换为bool类型

注意:函数重载时要避免二义性,比如double可以转flout也可以转int,就会出现二义性(包括像int转long和double)

ambiguous 二义性

q:我分别试了一下发现float既可以调用double的那个也可以调用int的那个,但是全放开他会选择double,这是为啥呢,为啥没有二义性的问题?

a:当 double 作为参数传递给 print(float) 时,编译器会报错,原因是C++ 进行重载解析时,标准转换分为不同的类别,具有不同的优先级:

提升(Promotion):如 char → int,float → double(优先级最高)。 标准转换(Standard Conversion):如 double → float,double → int(优先级较低)。 用户定义的转换和模板匹配(优先级最低)。 double 既可以转换为 int(截断)也可以转换为 float(精度损失),但这两者都是 标准转换(Standard Conversion),所以编译器无法决定哪一个更合适,导致 二义性错误。

q:还有视频里面说2.1这种小数默认是double类型,但是float和double不都是浮点数吗,只是精度不一样

a:auto a = 3.6; 会将 a 推导为 double 类型。 auto b = 3.6f; 会将 b 推导为 float 类型。

强类型和尽量减少类型推断在很多编程场景下都是非常有益的,它们能帮助我们在 编译时发现错误,提高代码可读性和可维护性,并有可能带来 性能提升 和更好的 工具支持。

重载的底层原理:命名倾轧(name mangling):通过修改函数名来区分参数不同的函数

e.g.

void print(int a)   //比如倾轧成void print_i(int a)
{}
​
void print(char a)  //void print_c(char a)
{}
​
void print(int a,char b)//void print_i_c(int a,char b)
{}
​
void print(char a,int b)//void print_c_i(char a,int b)
{}

运算符重载:

返回值类型 operator运算符(参数列表)
{
    重载实体;
}

默认参数规则:从右向左默认,中间不能跳跃

//合法
int valume(int l,int w = 4,int h = 5)
{
    return l * w * h;
}
​
cout << valume(2) << endl;
cout << valume(3,5) << endl;
cout << valume(1,2,10) << endl;
​
//不合法
int valume(int l = 2,int w,int h = 5)
{
    return l * w * h;
}
​
cout << valume(2,3) << endl;
cout << valume(3,5) << endl;
cout << valume(1,2,10) << endl;

重载和默认参数最好不要同时出现,会导致ambiguous二义性错误

引用语法:原数据类型& 别名 = 原名

引用是一种声明关系(意味着必须初始化)

引用不开辟空间

引用一经声明,不可变更(编译阶段就弄好了)

可以对引用再次引用,结果就是同一个变量具有多个别名

int a;
int& ra = a;//ra为a的引用
int& rr = ra;//rr也为a的引用
int& rrr = rr;//rrr还是a的引用
//等价于
int a;
int& ra = a;
int& rr = a;
int& rrr = a;

q:char *p = "askjank"是如何实现p储存字符串的?

a:在C++(以及C语言)中,字符串字面量(如 "askjank")通常存储在程序的只读数据段中。当你声明一个字符指针 char *p = "askjank"; 时,p 被初始化为指向这个字符串字面量的首字符的地址。

字符指针的初始化:char *p 声明了一个字符指针 p。当你将字符串字面量赋值给 p 时(实际上是将字符串字面量的地址赋值给 p),p 就指向了这个字符串的首字符 'a'

q:那cout << *p << endl;会是什么结果?

a:p 是一个字符指针,它指向字符串字面量 "askjank" 的首字符 'a'

q:那我输出p是啥结果?

在C++中,当你有一个字符指针 p 指向一个字符串(无论是字面量还是动态分配的内存中的字符串)时,直接输出指针 p(而不是解引用指针 *p)通常会得到该指针所指向的内存地址的十六进制表示。但是,如果你尝试直接输出一个指向字符串字面量的指针,并且你的编译器和环境支持将指针指向的字符串字面量直接作为字符串输出(这是许多C++编译器和标准库实现的一个常见但非强制的行为),那么输出可能会是字符串本身而不是地址。

然而,根据C++标准,直接输出一个字符指针应该输出指针的值(即地址),而不是它指向的字符串内容。但在实践中,许多编译器允许这种“偷懒”的写法,并会输出字符串内容,特别是当使用 std::cout 时。这种行为是编译器特定的,并且可能因编译器版本和设置而异。

为了明确起见,这里有两种可能的情况:

  1. 按照标准行为

    char *p = "askjank";
    std::cout << p << std::endl; // 可能输出指针的地址(十六进制),如 "0x7ffeefbff6f4"

  2. 编译器特定的“偷懒”行为

    char *p = "askjank";
    std::cout << p << std::endl; // 可能输出字符串内容 "askjank"


运行正常但是有警告,这条警告是在C++编程中遇到的,它表明你试图将一个字符串常量(例如 "hello")赋值给一个字符指针(char*)。在C++中,字符串常量是存储在程序的只读内存区域的,因此尝试通过字符指针修改这些字符串会导致未定义行为。

编译器给出这个警告是因为这种转换是不安全的,它可能会导致程序崩溃或其他不可预测的行为。

修改方法:使用 const char\* 而不是 char\*

相关文章:

  • MATRIX-BREAKOUT: 2靶场
  • StarRocks中优雅处理JSON与列表字段的初步示例
  • sass介绍
  • 操作系统IO多路复用select,poll,epoll
  • 英语词性--介词
  • 基于springboot的网上订餐系统(006)
  • python:music21 与 AI 结合应用探讨
  • Unity Enlighten与Progressive GPU Lightmapper对比分析
  • 清晰易懂的 PHP 安装与配置教程
  • 【蓝桥杯速成】| 7.01背包练习生
  • Framebuffer应用编程
  • 科研项目验收管理系统
  • Node.js系列(5)--数据库操作指南
  • 引用拷贝、浅拷贝和深拷贝
  • Pytorch使用手册—自定义 C++ 和 CUDA 运算符(专题五十一)
  • 12、Linux中如何查看一个进程,如何杀死一个进程,如何查看某个端口有没有被占用【中高频】
  • 供应链与生产制造L1L4级高阶流程规划框架(53页PPT)(文末有下载方式)
  • 关于redis中的分布式锁
  • VUE+element 在组件内有多个el-dialog同时打开时,遮罩会叠加
  • IntelliJ IDEA 中 Git 高频问题与操作详解|新手避坑指南
  • 一回合摘下“狮心”,张名扬霸气回应观众:再嘘一个我听听
  • 他比李白接地气,比杜甫乐观,比白居易刚毅
  • 海南旅文局通报游客入住酒店港币被调包:成立调查组赴陵水调查
  • 俄总统助理:普京与美特使讨论了恢复俄乌直接谈判的可能性
  • 王旭任甘肃省副省长
  • 外交部回应美财长涉中国发展经济模式言论:损害各国人民共同利益的是美方