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

做网站后台系统的规范为什么会显示危险网站

做网站后台系统的规范,为什么会显示危险网站,小红书推广怎么收费,网络推广网站推广淘宝运营商引用 一、C 引用 C 中的引用 (Reference) 是一种特殊的变量,本质上是一个已存在的变量的别名。它提供了一种间接访问其他变量的方式。 引用本身不占用额外的内存空间来存储数据,而是与一个已存在的变量绑定,通过引用访问或修改的就是该绑定的…

引用

一、C++ 引用

C++ 中的引用 (Reference) 是一种特殊的变量,本质上是一个已存在的变量的别名。它提供了一种间接访问其他变量的方式。

引用本身不占用额外的内存空间来存储数据,而是与一个已存在的变量绑定,通过引用访问或修改的就是该绑定的变量。因此可以说引用是一个已存在变量的另一种访问方式。

1、引用的使用

语法:

数据类型 &别名 = 变量名(已存在);

示例:

int main(){ int a = 10; int &b = a; //声明引用变量 只是绑定到已有的变量 a 上,成为它的另一个名字或者说别名。cout << "a = " << a << endl; //10cout << "b = " << b << endl; //10cout << "a地址 = " << &a << endl; //a地址和b地址是一样的cout << "b地址 = " << &b << endl; b = 20; cout << "a = " << a << endl; cout << "b = " << b << endl;
}

从上面示例代码中可以看到,修改了引用变量 b 的值,那么变量 a 的值也发生了变化,说明它们是指向同一块内存中的变量。引用即是一个变量的别名。

在这里插入图片描述

2、引用的注意事项

(1) 声明引用必须进行初始化:

在 C++ 中,引用在声明时必须初始化。因为引用是已存在变量的别名,它不可以“空引用”,必须与某个已有变量关联。

int x = 5;
int& ref = x;  // 正确,引用 ref 被初始化为 x 的别名int& ref2;      // 错误:引用必须在声明时初始化
(2) 引用初始化后,不可以改变:

一旦引用绑定到一个变量,就不能改变引用指向的对象,它始终引用最初绑定的变量。

int x = 10;
int y = 20;
int& ref = x;  // ref 是 x 的引用ref = y;        // 这是赋值操作,将 y 的值赋给 x,而不是改变引用的目标
cout << ref << endl;  // 输出 20,x 被修改为 20,但 ref 依然指向 x,而不是 y
(3) 引用不能为 NULL

引用不能是空引用,也不能指向 NULL。引用必须在创建时与一个有效的对象关联,不能指向一个“空”位置。

int x = 10;
int& ref = x;  // 正确:ref 引用 xint* ptr = nullptr;
int& ref2 = *ptr;  // 错误:不能为 NULL 引用

引用必须指向有效对象,这与指针不同,指针可以为 NULL

(4) 一个变量可以有多个引用:

一个变量可以有多个引用,它们都指向同一个内存地址,并且共享同一个值。

int x = 10;
int& ref1 = x;  // ref1 是 x 的引用
int& ref2 = x;  // ref2 也是 x 的引用ref1 = 20;       // 修改 ref1 所引用的值,也就是 x
cout << x << endl;  // 输出 20
cout << ref2 << endl;  // 输出 20
(5) 引用不能指向常量或临时变量:

普通引用不能绑定到常量或临时变量,因为它们无法修改常量的值或持有临时变量的地址。

int x = 10;
int& ref1 = x;    // ref1 是 x 的引用
// int& ref2 = 20;  // 错误:引用不能指向常量或临时变量,10 是一个临时变量

二、引用作为参数

由于引用提供了一种轻量级的、不增加额外存储开销的方式来操作已存在的变量,因此常用于函数参数传递、返回值优化等场景,以提高代码的效率和可读性。

1、避免复制成本

引用作为函数的参数,可以减少值传递带来的开销,尤其是在传递大型对象时,能避免昂贵的深拷贝。

2、修改原始数据

使用引用参数可以实现对实参的直接修改。

#include <iostream>
using namespace std;
void swap(int* a,int* b) {int temp = *a;*a = *b;*b = temp;
}
void swapWithXor(int &a, int &b) {if (a != b) {  // 避免当a和b是同一个变量时值被清零a = a ^ b;  // 第一步:a存储a和b的异或结果b = a ^ b;  // 第二步:b = (a^b)^b = a(恢复a的原始值)a = a ^ b;  // 第三步:a = (a^b)^a = b(恢复b的原始值)}
}
void swap(int& num1, int& num2){ int temp = num1; num1 = num2num2 = temp;
}
int main(){ int a = 10; int b = 20; swap(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl;
}

运行结果发现,a 和 b 的值发生了改变,也就是说通过引用传参相当与给变量起了一个别名,最终都是对同一个变量的操作。

3、对比指针

使用引用和指针作为函数参数的区别:

(1)直接使用引用变量进行赋值和修改,语法简洁,不需要解引用操作符 (*)。

(2)引用和指针都可以作为函数参数来实现数据的共享和修改,使用指针需要程序员自行管理内存和检查指针的有效性。而引用不能为 nullptr ,因为在定义时必须要进行初始化,总是指向某个有效的对象,所以这在一定程度上强制了函数调用时必须提供有效的对象。

void func(int& var){ var = 100; //不需要处理空值,因为引用在使用前必须初始化,保证值是有效的
}
int* func(int* var){ if (var != nullptr) { //需要检查指针的有效性return var;}
}
int main(){ int a = 10; func(a); int* result = func(&a); delete result; //手动释放内存result = nullptr;
}

(3)使用指针作为函数参数,可以在函数内部改变指针的指向,这是引用类型参数所不具备的。

void func1(int* var){ var = new int(10);//指向新的地址
}

三、引用作为函数的返回值

用引用作为函数的返回值,最大的好处是,在内存中不产生被返回值的副本。

1、引用作为函数返回值

我们来看一段代码:

//定义全局变量
int temp;
int fun1(){ temp = 10;return temp;
}
int& fun2(){ temp = 10;return temp;
}
int main() { // 1. 返回值类型int a = func1();  // 调用 func1 获取返回值a = 99;            // 修改 a,不影响 tempcout << temp << endl; // 输出 10,因为 func1 返回的是值// 2. 返回引用类型int& b = func2();  // 调用 func2 获取返回引用b = 88;            // 修改 b,同时修改 tempcout << temp << endl; // 输出 88,因为 func2 返回的是引用
}

上述代码中会出现两层拷贝,当执行语句 int a = fun1 (); 的时候会先创建一个临时变量,把返回值拷贝给隐藏的临时变量,然后再把临时变量的值再拷贝给 a,假设这个临时变量是 t,相当于做了这两个赋值的步骤:

t = temp;
a = t;

而返回引用在内存中不会产生副本,是原有变量的一个别名,这样就避免产生临时变量,相比返回普通类型的执行效率更高。

2、使用引用作为函数返回值注意事项

局部变量不要作为引用返回,函数执行完成后,局部变量会被销毁。

#include <iostream>
using namespace std;
int& test(){ int a = 1int& b = a; //局部变量不要作为引用返回,函数执行完成后,局部变量内存会被释放,导致返回的引用成为悬挂引用。return b;
}
int main(){ int& a = test(); cout << "返回结果:" << a << endl; //返回结果:-858993460
}

如果要返回局部变量,可以使用 static 修饰,静态变量存在于全局区,全局区上的数据在程序结束后释放。

int& test(){ static int a = 1; int& b = a; return b;
}

3、函数的调用可以作为左值

(1)左值
在 C++ 中,表达式分为左值和右值。

左值 (lvalue):指的是持久的对象,通常指代表达式结束后依然存在的对象。

特点:

  • 左值在内存中有明确的地址,可以取地址。
  • 左值可以被修改,即可以出现在赋值语句的左侧。
  • 左值可以出现在赋值表达式的左边或右边。
int a = 10; // 'a' 是左值,10 是右值
int* p = &a; // 正确,取变量地址,'a' 是左值
int b = a + 1; // 正确,使用左值

(2)右值
右值 (rvalue):指的是临时的对象,通常指表达式结束后不再存在的对象。

特点:

  • 右值不能取地址。
  • 右值不能出现在赋值语句的左侧。
int a = 10; 
int* p2 = &(a+1); // 错误,表达式(a+1)的结果是一个右值,右值不能取地址
int x = 10;
int y = 20;// 同样,下面的尝试也是无效的
(x + y) = 100; // 编译器错误:表达式 (x + y) 是一个右值,不能出现在赋值语句的左边

(3)函数调用作为左值
当函数返回引用时,函数的调用可以作为左值。

int a;
int& test(){ a = 10; return a;
}
int main(){ int& num1 = test(); //返回的是 a 的引用//num1是 a 的引用,因此输出10。cout << num1 << endl; //test()返回a的引用,所以可以将a的值改为 20test() = 20;cout << num1 << endl; //输出num1的值
}

四、常引用

1、常引用的定义

通过 const 关键字定义常量引用,必须在声明时初始化。

const int &a = 10;

上述代码中,10 是一个字面值常量,本身不是变量,不能直接被引用。但是使用 const 修饰后,编译器会创建一个临时变量,相当于下面的代码:

int temp = 10;
const int &a = temp;

此时,如果想要修改 a 的值,是不被允许的。会提示表达式必须是可修改的左值。

a=100;

常量引用主要用来修饰形参,提高安全性,防止形参改变实参。

如下代码,向 test () 函数传入实参变量 a,test () 函数执行之后,输出 a 的值是 100。也就是说函数执行完成后,会对外部的变量 a 产生影响。

int a = 10;
const int& ref = a;
  • 这里 ref 是对 a常量引用const int&),表示通过 ref 不能修改 a 的值(ref = 20; 是错误的)。

  • 但是 a 本身是非const变量,可以直接修改 aa = 20; 是合法的)

  • const int& 的重点是:引用本身是不能修改所引用对象的内容

2、指针常量和常量指针:

const 可以修饰指针的两部分:指针本身指针指向的内容。具体的含义如下:

  1. const int* pint const* p

    • p 可以改变指向不同的内存位置,但 不能修改指向的内容
    void func(const int* p) {// *p = 10;  // 错误:不能修改指针指向的内容int b = 20;p = &b;  // 正常:可以修改指针的指向
    }
    
  2. int* const p

    • p 是常量指针,指针本身不能修改,但 可以修改指向的内容
    void func(int* const p) {*p = 10;  // 正常:可以修改指针指向的内容int b = 20;// p = &b;  // 错误:不能修改指针的指向
    }
    
  3. const int* const p

    • p 是常量指针,指针本身不能修改指针指向的内容也不能修改
    void func(const int* const p) {// *p = 10;  // 错误:不能修改指针指向的内容// p = &b;  // 错误:不能修改指针的指向
    }
    
总结:
  • const 左边修饰指针的内容const int* p):指针指向的内容不可通过指针修改,但指针本身可以指向其他地址,指针指向的变量也可以直接被赋值修改。
  • const 右边修饰指针本身int* const p):指针本身指向的地址不可修改,但指针指向的变量的值可以被修改。
类型含义是否能修改值是否能修改指针
const int* p常量指针:不能通过 p 修改指向的值❌ 否✅ 是
int* const p指针常量:指针地址不可变,值可改✅ 是❌ 否
const int* const p指向常量的常量指针,两者都不可变❌ 否❌ 否

const 在 * 左边,指向内容不能变 → 常量指针
const 在 * 右边,指针地址不能变 → 指针常量

把const当作常量就行了!

http://www.dtcms.com/a/486835.html

相关文章:

  • [tile-lang] docs | 基准测试 | GEMM示例
  • 网站开发培训收费邯郸外贸网站建设
  • commons-imaging(图像处理库)
  • 打渔网站建设南冒网站建设制作推广公司
  • 可以充值的网站怎么建设wordpress英文文章格式
  • 惠州网站设计公司网站建设做什么会计分录
  • 基于自动驾驶仿真软件的交通事故档案建模与分析
  • Cursor 脚本如何进入Conda环境
  • Flink-Kafka 连接器的 Checkpoint 与 Offset 管理机制
  • 域名备案查询网站有哪些手机网站
  • C++智能指针的原理与应用
  • 做淘宝那样的网站麻烦吗宜昌网站网站建设
  • wordpress小说站模板wordpress在线教程
  • HTTP(2)~
  • 建网站需要什么条件小户型室内装修设计公司网站
  • 【深度学习】目标检测全解析:定义、数据集、评估指标与主流算法
  • 做网站构架河南app定制开发
  • 2025年--Lc187--120. 三角形最小路径和(多维动态规划,矩阵)--Java版
  • 脑电分析——论文解读
  • HTTPS 包 抓取与分析实战,从抓包到解密、故障定位与真机取证
  • 做网站实训目的和意义公司网页制作培训试题
  • 影响DCDC输出纹波的因素有哪些?
  • 婴儿辅食中企动力提供网站建设自适应全屏网站
  • 【征文计划】Rokid CXR-M SDK全解析:从设备连接到语音交互的AR协同开发指南
  • 川崎焊接机器人弧焊气体节约
  • 做网站横幅价格wordpress 36kr
  • Java-Spring入门指南(二十六)Android Studio下载与安装
  • 14.C 语言实现一个迷你 Shell
  • 【理解React Hooks与JavaScript类型系统】
  • 如何使用PyTorch高效实现张量的批量归一化原理与代码实战