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

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\*


http://www.kler.cn/a/596788.html

相关文章:

  • 【Matlab笔记_22】Matlab地图矩阵左右置换
  • 阿里云国际站代理商:为什么边缘计算需要分布式防护?
  • 2025.3.22总结
  • DAY36贪心算法Ⅴ
  • linux内核数据结构分析之链表
  • 浅谈Qt事件子系统——以可拖动的通用Widget为例子
  • 腾讯 客户端实习 凉经(3)
  • LeetCode707设计链表
  • 四台电脑共享外设的终极方案:USB3.0 共享切换器 SV04 深度解析
  • PyCharm中使用pip安装PyTorch(从0开始仅需两步)
  • 连通图(并查集)
  • C# WebForm显示bootstrap模态对话框
  • 中颖SH366000介绍和使用全解
  • [01-04-02].第20节:PyQt5库初识及实现简易计算器
  • 数智读书笔记系列022《算力网络-云网融合2.0时代的网络架构与关键技术》读书笔记
  • css基础-浮动
  • 【工具变量】全国地级市克鲁格曼专业化指数数据集(2006-2023年)
  • 基于蒙特卡洛方法的网格世界求解
  • 使用netDxf扩充LaserGRBL使它支持Dxf文件格式
  • 在刀刃上发力:如何精准把握计划关键节点