Const的一些“奇闻轶事”。

2024-01-11 17:30
文章标签 const 轶事 奇闻

本文主要是介绍Const的一些“奇闻轶事”。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

const 关键字对于熟悉C/C++的朋友都不会陌生。下面梳理下学习过程中关于const的一些奇闻轶事!

1. const 在C中是个“冒牌货"

看如下代码:

 

 1 #include <stdio.h>
 2 
 3 int main(int argc, char *argv[])
 4 {
 5      const int n = 10;
 6      int *p = (int *)&n;
 7      *p = 20;         
 8      printf("n = %d\n", n);
 9      
10      return 0;    
11 }

 

在VC6.0中运行结果:

说明:将上述代码在新的编译器(新的C标准下)如CLion下编译运行,运行结果为:

将上述代码放入.cpp文件中并进行编译运行,在VC6.0中结果为:

在CLion中运行结果为:

两者没有变化!

 

除去C语言中新旧标准的不同对于结果的不同,为什么在C和C++同样的代码中会有上述不同的现象?

在C++中,对于所定义的const常量,在程序运行过程中系统会创建符号表,拷贝一份const常量的值存入符号表中。

当程序中有需要用到const常量时,从所创建的符号表中查找const常量并使用。

为了进一步说明这种情况,请看如下代码:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(int argc, char *argv[])
 5 {
 6     const int a = 10;
 7     int *p = (int *) &a;
 8     *p = 20;
 9 
10     cout << "a = " << a << endl;
11     cout << "*p = " << *p << endl;
12     cout << "p = " << p << endl;
13     cout << "&a = " << &a << endl;
14     cout << "*(&a) = " << *(&a) << endl;
15 
16     return 0;
17 }

运行结果为:

 

根据运行结果,验证了我们上面所说的。

编译过程中若发现使用常量则直接以符号表中的值替换。

 

如果对于上述描叙还是不太清楚,可以参考以下代码:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main(int argc, char *argv[])
 5 {   // 在C++中,对于所定义的const常量,在程序运行过程中系统会创建符号表
 6     int b = 10;
 7     cout << "b: " << b << endl;
 8     cout << "*(&b): " << b << endl;
 9 
10     const int c = 20;
11     int *pp = (int *)&c;
12     *pp = 1000;
13     cout << "c: " << c << endl;
14     cout << "*(&c): " << *(&c) << endl;
15 
16     return 0;
17 }

运行结果为:

b: 10
*(&b): 10
c: 20
*(&c): 1000

 

 

 

 

-------------------我是美腻的分割线-------------------

 结论:

C语言中的const常量

  C语言中的const变量是只读变量,有自己的存储空间

 

C++中的const常量

  可能分配存储空间,也可能不分配存储空间

  以下两种情况会分配存储空间:

    当const常量为全局,并且需要在其它文件中使用

    当使用&操作符, 取const常量的地址

    当 cosnt int &a = 10; const 修饰引用时,也会分配存储空间

     

 

 

 

 

 

转载于:https://www.cnblogs.com/muming-hardworking/p/6859224.html

这篇关于Const的一些“奇闻轶事”。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/595137

相关文章

c++的初始化列表与const成员

初始化列表与const成员 const成员 使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。 不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。 在定义const成员时进行初始化,该语法只有在C11语法标准下才支持。 初始化列表 在构造函数小括号后面,主要用于给

s let 和const的区别 ,它们可以变量提升吗

在 JavaScript 中,let 和 const 是 ES6 引入的新变量声明关键字,它们与之前的 var 关键字相比,有几个重要的区别。特别是关于变量提升(hoisting)的行为不同。 变量提升(Hoisting) 在 JavaScript 中,“变量提升”是指变量声明会被提升到作用域的顶部,但变量的初始化不会。这意味着你可以先使用变量,然后再声明它。然而,let 和 const 的行

C++中const关键字的使用方法,烦透了一遍一遍的搜,总结一下,加深印象!!!

之前一直在学习C/C++,关于const的使用,这里出现一点,那里出现一点。知识用时方恨少,这一段时间正好各种笔试题,其中关于const的用法也是层出不穷,所以疲于在书本上各种翻,这里汇总一下,加深自己的印象的同时,也方便以后查阅和学习。菜鸟一个,若有错误,望指正! const关键字 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。不管出现在任何上

const与#define的优缺点

1.define由预处理程序处理,const由编译程序处理 2.#define不分内存,因为它是预编译指令,编译前进行了宏替换。const 不一定?某种说法,Const常量是占有内存的被“冻结”了的变量 3.const定义常量是有数据类型的,这样const定义的常量编译器可以对其进行数据静态类型安全检查,而#define宏定义的常量却只是进行简单的字符替换,没有类型安全检查,且有时还会产生边际

【C++】类中成员函数声明后面接 const

const 表示对类中成员函数属性的声明; 表示不会修改类中的数据成员; 在编写const成员函数时,若不慎修改了数据成员,或者调用了其他非const成员函数,编译器将指出错误; 以下程序中,类stack的成员函数GetCount仅用于计数,从逻辑上讲GetCount应当为const函数。 class Stack{public:void Push(int elem);int Pop(vo

【C++】C++中的关键字:const、mutable、auto、new....

七、C++中的关键字:const、mutable、auto、new、 本部分打算是尽量多的罗列出C++中的关键字和一些花式操作。先总结一下我们之前讲过的:private、public、protect: 参考【C++】类、静态、枚举、重载、多态、继承、重写、虚函数_静态与多态:重写、重载、模板-CSDN博客中的第5小标题,可见性。static: 参考【C++】类、静态、枚举、重载、多态、继承、重写

[跨平台C++] 返回const char* 类型的函数样板

返回const char*类型的函数 方法1: const char* GetPathByFileNameFull(const char* szFileName_Full) { // const char* p = strchr(szFileName_Full,'\\'); //start 0 position find "\\"const char* p = strrchr(szF

7.const指针问题

double* ptr = &value;     //ptr是一个指向double类型的指针,ptr的值可以改变,ptr所指向的value的值也可以改变  const double* ptr = &value     //ptr是一个指向const double类型的指针,ptr的值可以改变,ptr所指向的value的值不可以改变 double* const ptr=&v

2.C语言实现函数void *memmove(void *dest, const void *src, size_t n)。memmove 函数的功能是拷贝src所指的内存内容前n个字节到dest所指

//用C语言实现函数void * memmove(void *dest, const void *src, size_t n)。memmove//函数的功能是拷贝src所指的内存内容前n个字节到dest所指的地址上。//分析:由于可以把任何类型的指针赋给void类型的指针,这个函数主要是实现各种数据类型的拷贝。//要考虑正向拷贝和反向拷贝问题#include<stdio.h>#include<

qt4.8.7编译中出现const void* 禁止转换为void *

编译错误 错误忘截图,大概是如下头文件的问题: 该文件中的这一段函数报了如图所示的错误: // Test and set for pointerstemplate <typename T>Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue){union