C++中const和C++的引用
2017-09-18 14:24
232 查看
一、C++与C语言中const的比较
1、C语言中
#include <stdio.h>
int main()
{
// C++中 const 变量声明的是一个真正的常量,不是变量,所以编译器不会为该常量分配空间
// const 修饰的常量会被放到 符号表 中
const int a = 10;
// 这里对 const 常量取地址,这一步操作会让编译器为该变量分配空间,分配的空间并不会被 a 使用
int *p = (int *)&a;
// 通过指针改变指向的空间的值,这个空间是编译器为常量分配的空间,但是常量的值并不在这个空间内
// 所以即使通过指针修改了这个空间的值,也不会影响到 a 本身
*p = 5;
// a 的值不变,因为它的值在符号表中,不在程序运行的空间内
printf ("%d, %p\n", a, *p);
return 0;
}C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量
可能分配存储空间,也可能不分配存储空间
当const常量为全局,并且需要在其它文件中使用
当使用&操作符取const常量的地址
3、const和#define
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
二、C++的引用
1、C++引用的概念
变量名的回顾:变量名实质上是一段连续存储空间的别名,是一个标号(门牌号) ,程序中通过变量来申请并命名内存空间 ,通过变量的名字可以使用存储空间。
问题:一段连续的内存空间是否只能有一个别名吗?
引用:引用可以看作一个已定义变量的别名
引用的语法:Type& name = var;
#include <stdio.h>
int main()
{
// 定义一个int型变量a,在内存中占4个字节,
// 变量名 a 就代表了这一块内存,或者说 a 是这块内存的别名
int a = 10;
// 定义了一个引用变量 b ,它是 a 的别名,和 a 代表同一块内存空间
// 对 b 的操作 和 对 a 的操作是一样的
int& b = a;
// 改变 b 等于改变了 a
b = 20;
printf ("%d, %d\n", a, b);
// a 与 b 代表同一块内存空间
printf ("%p, %p\n", &a, &b);
return 0;
}
2、引用的意义
1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针
2)引用相对于指针来说具有更好的可读性和实用性
#include <stdio.h>
struct Student
{
char name[20];
int age;
};
void printS1(Student *pS)
{
printf ("%s\n", pS->name);
}
// 复杂数据类型的引用
void printS2(Student &pS)
{
printf ("%s\n", pS.name);
pS.age = 80;
}
void printS3(Student pS)
{
printf ("%s\n", pS.name);
}
int main()
{
Student stu = {"xiaoming", 2};
printS1(&stu); // 地址传递,pS 是 变量 stu 的指针,引用成员要用 ->
printS2(stu); // pS 是 stu 的别名,和 stu 代表的是同一块内存空间,使用成员和 stu 一样 用.
printf ("%d\n", stu.age);
printS3(stu); // 值传递,pS 是 stu 的一份复制
return 0;
}
4、引用的本质
1)引用在C++中的内部实现是一个常指针
Type& name çè Type* const name
2)C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
3)从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏
4)当我们使用引用语法的时,我们不去关心编译器引用是怎么做的
当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的
4000
#include <stdio.h>
int main()
{
int a = 10;
int &b = a; // int * const b = &a;
// *b = 20;
b = 20;
// printf ("%p, %p\n", &a, &(*b));
printf ("%p, %p\n", &a, &b);
return 0;
}
5、函数返回值作为引用
1)返回栈变量:
若返回栈变量,不能成为其它引用的初始值, 不能作为左值使用。
#include <iostream>
using namespace std;
int getAA1()
{
int a ;
a = 10;
return a;
}
//返回a的本身 返回a的一个副本 10
int& getAA2()
{
int a ; //如果返回栈上的 引用, 有可能会有问题
a = 10;
return a;
}
int* getAA3()
{
int a ;
a = 10;
return &a;
}
int main()
{
int a1 = getAA1();
// 用非引用类型接收函数返回的引用,就等于将函数返回的引用的数据值,复制给了该接收对象
// 效果和返回非引用数据是一样的
int a2 = getAA2();
int& a3 = getAA2();
printf ("%d\n", a2);
printf ("%d\n", a3);
return 0;
}
2)返回全局变量或静态变量:
若返回静态变量或全局变量,可以成为其他引用的初始值,即可作为右值使用,也可作为左值使用。#include <stdio.h>
int g_a = 10;
// 返回全局变量的引用
int& get_a()
{
return g_a;
}
// 返回局部变量的引用
int& get_sa()
{
static int a = 10;
a++;
return a;
}
int main()
{
// 返回全局变量的引用可以作为其他引用的初始值
int& a1 = get_a();
a1 = 30;
printf ("%d\n", g_a);
// 当不考虑接收的情况,返回全局变量的引用函数可以作为左值使用
get_a() = 40;
printf ("%d\n", g_a);
// 返回静态变量的引用和返回全局变量使用方式相同
int& a2 = get_sa();
get_sa();
get_sa();
printf ("%d\n", a2);
get_sa() = 40;
get_sa();
printf ("%d\n", a2);
return 0;
}
6、常引用
const & int e 相当于 const int * const e
普通引用 相当于 int *const e1
当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
使用字面量对const引用初始化后,将生成一个只读变量
#include <stdio.h>
int main()
{
int a = 10;
int &b = a; // 普通引用
int x = 20;
const int& y = x; // 常引用 让变量y拥有只读属性,不能通过y改变x的值
// 常引用 初始化 分为 2中情况
// 1、用变量初始化 常引用
{
int a1 = 20;
const int& b1 = a1; // a1 变量去初始化常引用
}
// 2、用常量去初始化常引用
{
const int a = 40; // C++编译器把a放在符号表中
// int& b = 41; // 普通引用,引用一个常量,常量是没有地址空间的,这样的做法是不合法的
// 使用常量去初始化常引用是合法的,C++编译器会为该引用分配空间,常量的值存储到分配的空间中去
// 使用常量对 const引用 初始化后,将生成一个只读变量
const int& b = 42;
int *p = (int *)&b;
*p = 50;
printf ("%d\n", b);
}
return 0;
}
1、C语言中
#include <stdio.h> int main() { // C语言中 const修饰的变量是一个 常变量,本质还是变量,有自己的地址空间 const int a = 10; int *p = (int *)&a; *p = 5; printf ("%d\n", a); return 0; }2、c++中
#include <stdio.h>
int main()
{
// C++中 const 变量声明的是一个真正的常量,不是变量,所以编译器不会为该常量分配空间
// const 修饰的常量会被放到 符号表 中
const int a = 10;
// 这里对 const 常量取地址,这一步操作会让编译器为该变量分配空间,分配的空间并不会被 a 使用
int *p = (int *)&a;
// 通过指针改变指向的空间的值,这个空间是编译器为常量分配的空间,但是常量的值并不在这个空间内
// 所以即使通过指针修改了这个空间的值,也不会影响到 a 本身
*p = 5;
// a 的值不变,因为它的值在符号表中,不在程序运行的空间内
printf ("%d, %p\n", a, *p);
return 0;
}C语言中的const变量
C语言中const变量是只读变量,有自己的存储空间
C++中的const常量
可能分配存储空间,也可能不分配存储空间
当const常量为全局,并且需要在其它文件中使用
当使用&操作符取const常量的地址
3、const和#define
C++中的const常量类似于宏定义
const int c = 5; ≈ #define c 5
C++中的const常量与宏定义不同
const常量是由编译器处理的,提供类型检查和作用域检查
宏定义由预处理器处理,单纯的文本替换
二、C++的引用
1、C++引用的概念
变量名的回顾:变量名实质上是一段连续存储空间的别名,是一个标号(门牌号) ,程序中通过变量来申请并命名内存空间 ,通过变量的名字可以使用存储空间。
问题:一段连续的内存空间是否只能有一个别名吗?
引用:引用可以看作一个已定义变量的别名
引用的语法:Type& name = var;
#include <stdio.h>
int main()
{
// 定义一个int型变量a,在内存中占4个字节,
// 变量名 a 就代表了这一块内存,或者说 a 是这块内存的别名
int a = 10;
// 定义了一个引用变量 b ,它是 a 的别名,和 a 代表同一块内存空间
// 对 b 的操作 和 对 a 的操作是一样的
int& b = a;
// 改变 b 等于改变了 a
b = 20;
printf ("%d, %d\n", a, b);
// a 与 b 代表同一块内存空间
printf ("%p, %p\n", &a, &b);
return 0;
}
2、引用的意义
1)引用作为其它变量的别名而存在,因此在一些场合可以代替指针
2)引用相对于指针来说具有更好的可读性和实用性
#include <stdio.h> void swap1 (int &a, int &b) { int tmp = a; a = b; b = tmp; } void swap2 (int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } int main() { int a = 10; int b = 20; swap2 (&a, &b); swap1 (a, b); printf ("%d, %d\n", a, b); return 0; }3、复杂数据类的引用
#include <stdio.h>
struct Student
{
char name[20];
int age;
};
void printS1(Student *pS)
{
printf ("%s\n", pS->name);
}
// 复杂数据类型的引用
void printS2(Student &pS)
{
printf ("%s\n", pS.name);
pS.age = 80;
}
void printS3(Student pS)
{
printf ("%s\n", pS.name);
}
int main()
{
Student stu = {"xiaoming", 2};
printS1(&stu); // 地址传递,pS 是 变量 stu 的指针,引用成员要用 ->
printS2(stu); // pS 是 stu 的别名,和 stu 代表的是同一块内存空间,使用成员和 stu 一样 用.
printf ("%d\n", stu.age);
printS3(stu); // 值传递,pS 是 stu 的一份复制
return 0;
}
4、引用的本质
1)引用在C++中的内部实现是一个常指针
Type& name çè Type* const name
2)C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
3)从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏
4)当我们使用引用语法的时,我们不去关心编译器引用是怎么做的
当我们分析奇怪的语法现象的时,我们才去考虑c++编译器是怎么做的
4000
#include <stdio.h>
int main()
{
int a = 10;
int &b = a; // int * const b = &a;
// *b = 20;
b = 20;
// printf ("%p, %p\n", &a, &(*b));
printf ("%p, %p\n", &a, &b);
return 0;
}
5、函数返回值作为引用
1)返回栈变量:
若返回栈变量,不能成为其它引用的初始值, 不能作为左值使用。
#include <iostream>
using namespace std;
int getAA1()
{
int a ;
a = 10;
return a;
}
//返回a的本身 返回a的一个副本 10
int& getAA2()
{
int a ; //如果返回栈上的 引用, 有可能会有问题
a = 10;
return a;
}
int* getAA3()
{
int a ;
a = 10;
return &a;
}
int main()
{
int a1 = getAA1();
// 用非引用类型接收函数返回的引用,就等于将函数返回的引用的数据值,复制给了该接收对象
// 效果和返回非引用数据是一样的
int a2 = getAA2();
int& a3 = getAA2();
printf ("%d\n", a2);
printf ("%d\n", a3);
return 0;
}
2)返回全局变量或静态变量:
若返回静态变量或全局变量,可以成为其他引用的初始值,即可作为右值使用,也可作为左值使用。#include <stdio.h>
int g_a = 10;
// 返回全局变量的引用
int& get_a()
{
return g_a;
}
// 返回局部变量的引用
int& get_sa()
{
static int a = 10;
a++;
return a;
}
int main()
{
// 返回全局变量的引用可以作为其他引用的初始值
int& a1 = get_a();
a1 = 30;
printf ("%d\n", g_a);
// 当不考虑接收的情况,返回全局变量的引用函数可以作为左值使用
get_a() = 40;
printf ("%d\n", g_a);
// 返回静态变量的引用和返回全局变量使用方式相同
int& a2 = get_sa();
get_sa();
get_sa();
printf ("%d\n", a2);
get_sa() = 40;
get_sa();
printf ("%d\n", a2);
return 0;
}
6、常引用
const & int e 相当于 const int * const e
普通引用 相当于 int *const e1
当使用常量(字面量)对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
使用字面量对const引用初始化后,将生成一个只读变量
#include <stdio.h>
int main()
{
int a = 10;
int &b = a; // 普通引用
int x = 20;
const int& y = x; // 常引用 让变量y拥有只读属性,不能通过y改变x的值
// 常引用 初始化 分为 2中情况
// 1、用变量初始化 常引用
{
int a1 = 20;
const int& b1 = a1; // a1 变量去初始化常引用
}
// 2、用常量去初始化常引用
{
const int a = 40; // C++编译器把a放在符号表中
// int& b = 41; // 普通引用,引用一个常量,常量是没有地址空间的,这样的做法是不合法的
// 使用常量去初始化常引用是合法的,C++编译器会为该引用分配空间,常量的值存储到分配的空间中去
// 使用常量对 const引用 初始化后,将生成一个只读变量
const int& b = 42;
int *p = (int *)&b;
*p = 50;
printf ("%d\n", b);
}
return 0;
}
相关文章推荐
- C++中 引用 和 const
- [第二节]C++ 引用 函数调用作为左值 用const限定引用 返回堆中变量的引用
- C++ const引用详解
- C语言和C++的几点不同之处,const,register,三目运算符,&引用
- C++ Prime:const的引用
- C++ 学习笔记(2)变量和基本类型(复合类型:引用、指针)、const、constexpr、typedef(using)、auto、decltype
- C++基础学习笔记----第六课(const和引用的扩展、重载函数和C方式编译的深入)
- 【C++专题】C++引用与const引用
- C++:const和引用
- C++的const和引用只能在初始化列表里初始化而不能在构造函数体内赋值初始化
- c和c++中const,指针和引用
- c++之const,reference(引用),
- C++学习笔记1-const引用
- C++箴言:用传引用给const取代传值
- C++中的引用、const引用和非const引用
- C++ const引用详解
- C++中的几个关键字(static、const、#define、inline、sizeof与strlen、指针与引用、new与malloc)
- 【转】C++ 类中的static,const,及引用类型的初始化
- C++ const引用详解
- C++中const修饰基本数据类型、指针、引用、对象