变量:

int i = 0;  // i 是变量

i=5;         //i 可以修改

变量就是程序内一个内存位置的符号名,在该内存位置可以保存数据,并可以通过符号名对该内存地址存放的数据进行访问。

变量的值可以修改,是可变的,但在某个确定的时刻,变量的值是确定的,并一直保持到下次被修改之前。

常量:

int a=10;       //a 是变量, 10 是常量,也是整形常量

double  b= 3.5;  //b是变量, 3.5 这个数是常量,也叫浮点型常量

char c= 'A' ;  //c是变量,  ‘A’ 是字符常量

std::string  str ="1234";   // str 是变量, “1234”是字符串常量

上面这四种常量都叫做普通常量,也称之为字面值常量。

字面值常量在程序中是直接表示的,整型直接写出大小,字符直接写出字符 ,如上面的10 和 ‘A ’ 

一个字面值常量在编译时被直接解析为立即数,编译器内部维护字面值常量的类型,

以前一直以为const修饰的变量是常量,既对,也错,应该称为  符号常量

const int   i = 10 ; // i 是const 修饰的,i本身是变量, 但是被const 修饰后变成了符号常量,不可修改

//当然,10 还是常量,也是字面值常量 ,而 i  是符号常量,和普通常量不一样的是,符号常量有一个名称,既i , 而普通常量也就是字面值常量是没有名称的

符号常量的定义的两种方式:#define  和const

#define A 10

const int B=10;

不同之处在于: 

a. 宏定义: 由预处理处理,单纯的是纯文本替换。 

b. const常量: 由C++编译器处理,提供类型检查和作用域检查。

ps:建议把常量定义为大写形式

常量存储在什么地方:

一个由C/C++编译的程序占用的内存分为以下几个部分 

1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 

2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 

3、全局(静态)区(static):

全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 

4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 

5、程序代码区—存放函数体的二进制代码。

例子程序: 

//main.cpp:

#include<iostream>

using namespace std;

 

int a = 0;                                 全局(静态)初始化区 

char *p1;                                 全局(静态)未初始化区

int  main() 



    int b=10;                             b在栈 ,10呢?10没有存在任何地方,编译器在指令中直接把10作为立即数赋值给了b

    char *p2;                            栈 

    char *p3 = "123456";         "123456"在常量区,p3在栈上。 

    p1 = (char *)malloc(10);     分配得来10字节的区域在堆区

    strcpy(p1, "123456");         "123456"放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方

}

重点有两个:

1.为什么  int b=10;   10这个常量 没有放在文字常量区,不是说常量都放在这里吗?

这是因为编译器认为普通的整型、浮点型或字符型常量在使用的时候是可以通过立即数来实现的,没有必要额外存储到数据区,如此节省了存储空间和运行时的访问时间

2.那么什么样的数据才将放入常量区呢?

第一就是”12345“ 这样的字符串常量,但是要除掉字符数组赋值的常量

第二就是被const修饰的全局变量

除了字符串之外,其他常量也可以放在常量区,但是前提是该数据必须被存放在全局变量的空间里,并且被const关键字修饰。如下:

#include<iostream>
using namespace std; const int v0=5; //5这个常量在常量区,因为是全局const, v0在全局(静态)初始化区 
const char c='t'; //'t'这个常量在常量区,因为是全局const, c在全局(静态)初始化区 
int v1=6; //6这个常量是立即数,没有存在任何地方 ,v1在全局(静态)初始化区  int main()
{
const int x=0; //'0'这个常量也是立即数,因为不是全局的,x则在栈中
double x=10; //'10'这个常量也是立即数,x则在栈中
string str="12345"; //"12345"在常量区,str在栈中
char a[]="123"; //特殊,"123"也相当于立即数,没有村拽任何地方,a在栈中,保存了123
return 0;
}

至于为什么?要好好学习汇编,看看编译器到底做了什么?

参考:http://emb.hqyj.com/Column/Column540.htm

C++ 变量、常量、符号常量的更多相关文章

  1. iOS开发Swift篇(01) 变量&常量&元组

    iOS开发Swift篇(01) 变量&常量&元组 说明: 1)终于要写一写swift了.其实早在14年就已经写了swift的部分博客,无奈时过境迁,此时早已不同往昔了.另外,对于14年 ...

  2. C#基础总结之一变量常量-if嵌套语句-witch结构-类型转换

    //Console.WriteLine("Hello World"); //打印显示 //Console.ReadLine(); //接收输入的值 //Console.ReadKe ...

  3. 李洪强iOS开发Swift篇---11_变量&常量&元组

    李洪强iOS开发Swift篇---11_变量&常量&元组 说明: 1)终于要写一写swift了.其实早在14年就已经写了swift的部分博客,无奈时过境迁,此时早已不同往昔了.另外,对 ...

  4. PHP 获得当前页面所有变量常量的值

    get_defined_vars() - 返回由所有已定义变量所组成的数组,这个函数在二次开发的时候用起来非常给力: get_defined_constants();可以返回当前的所有常量 zend的 ...

  5. JAVA之旅(一)——基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算

    JAVA之旅(一)--基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算 Android老鸟重新学一遍JAVA是什么感觉?枯燥啊,乏味啊,而且归纳写博客,都 ...

  6. TF:Tensorflow定义变量+常量,实现输出计数功能—Jason niu

    #TF:Tensorflow定义变量+常量,实现输出计数功能 import tensorflow as tf state = tf.Variable(0, name='Parameter_name_c ...

  7. C#基础课程之二变量常量及流程控制

    课堂练习:.一个四位整数 输出它的千位,百位,十位,个位 数字. ; ; % ; % ; ; Console.WriteLine("千位数" + b+" 百位数" ...

  8. Swift-基础语法之变量&常量&元组

    使用 let来声明一个常量,用 var来声明一个变量.常量的值在编译时并不要求已知,但是你必须为其赋值一次.这意味着你可以使用常量来给一个值命名,然后一次定义多次使用 myVariable = let ...

  9. Java复习3.变量.常量.String.

    Java 中的变量常量数据类型 20131004 前言: 还是国庆节,无聊的很,就没事复习点Java的知识,其实C/C++基本上是现在大型企业面试的语言,但是多学习点Java是没有坏处的,而且,将来工 ...

  10. ios swift 里面关于变量 常量 可选类型 控制流的一些心得

    //swift 里面没有头文件和实现文件.只有一个.swift文件 //swift 里面没有main的概念,程序从main.swift开始执行 //swift 每一条执行语句可以不用分号结束,多条语句 ...

随机推荐

  1. Codeforces 479【A】div3试个水

    题目链接:http://codeforces.com/problemset/problem/977/A 题意:这个题,题目就是让你根据他的规律玩嘛.末尾是0就除10,不是就-1. 题解:题解即题意. ...

  2. 请求参数MD5加密---函数助手

  3. vs 查看IL

    vs--工具--外部工具--新增1 标题:随便填, 2 命令:C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Too ...

  4. redis通过命令传参以及主从复制

    config set appendonly  yes  临时生效 如果想永久生效的话,执行 config rewrite 并不是所有的都支持修改 config set bind ip  修改bind参 ...

  5. 既然 start() 方法会调用 run() 方法,为什么我们调用 start() 方法,而不直接调用 run() 方法?

    当你调用 start() 方法时,它会新建一个线程然后执行 run() 方法中的代码.如果直接调用 run() 方法,并不会创建新线程,方法中的代码会在当前调用者的线程中执行

  6. 廖雪峰Java16函数式编程-1Lambda表达式-1Lambda基础

    1. 函数式编程 Java有2类方法: 实例方法:通过实例调用 静态方法:通过类名调用 Java的方法相当于过程式语言的函数 函数式编程(Functional Programing): 把函数作为基本 ...

  7. 剑指Offer-13:调整数组位置使奇数位于偶数前面

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.例如给定一个数组 ...

  8. ThinkPHP 的缓存大概多久更新一次

    ThinkPHP 的缓存大概多久更新一次可以自己设置: thinkPHP的缓存默认是文件缓存,保存在Runtime文件夹里面, 如果不设置过期时间,且不清除Runtime文件,就会一直存在. 如果设置 ...

  9. python paramiko模块学习分享

    python paramiko模块学习分享 paramiko是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接.paramiko支持Linux, Sola ...

  10. JS break语句和continue语句

    break语句 描述:break语句,用于无条件结束各种循环(退出循环)和switch. 说明:一般情况下,需要在break语句之前加一个条件判断.换句话说:就是条件成立了,就退出循环 continu ...