常量表达式_常量表达式是指什么 - CSDN
精华内容
参与话题
  • 常量表达式概念与用处

    千次阅读 2017-12-30 21:13:08
    1)什么叫常量表达式?  在编译期间进行求值的表达式。  1、字面值常量是常量表达式;如123,‘a’,3.14等  2、用常量表达式初始化的const对象也是常量表达式。如int const a=5;语句中a就是常量表达式 2)...
    1)什么叫常量表达式?

            在编译期间进行求值的表达式。

            1、字面值常量是常量表达式;如123,‘a’,3.14等
            2、跟字面值常量相关的一些表达式;如123+3.14,2<<2等
            3、在C++中用常量表达式初始化的const对象也是常量表达式,并且也是C++推荐的使用方式,而C语言不是。如int const a=5;语句中a就是常量表达式

    2)什么地方会用到常量表达式?

            就目前所知道的有三个,后面如果发现再新增。
            1、静态存储变量需用常量表达式初始化;
                  ps:C语言静态变量初始化中,可以把可执行文件想要初始化的值放在变量将会使用的位置,当可执行文件载入到内存时,这个已经保存了正确初始值的位置将赋值给那个变量,因此必须使用常量表达式初始化。而C++中静态变量是动态分配的,即在程序运行时分配内存的,因此可以用变量对其进行初始化。
           
            2、case标签必须具有唯一的值,所以必须用常量表达式;
            
            3、定义一个数组,数组长度必须在编译时确定,必须为一个常量表达式
                  ps:为了便于维护,常使用#define为数值定义一个符号,如#define SIZE 50       int a[SIZE];
                          有些编译器允许声明动态数组,即用变量作为数组的长度,但此时不能对其进行初始化,即int a=5;int b[a];√   而int b[a]={1,2,3};×
    展开全文
  • 常量表达式

    2019-08-03 10:59:05
    常量表达式 Item 1:如果函数必须在编译期进行求值,就将其声明为constexpr 理由 需要用constexpr来告诉编译器允许对其进行编译期求值。 示例 阶乘的例子: constexpr int fac(int n) //constexpr函数 { return (n>...

    常量表达式

    Item 1:如果函数必须在编译期进行求值,就将其声明为constexpr

    理由

    需要用constexpr来告诉编译器允许对其进行编译期求值。

    示例

    阶乘的例子:

    constexpr int fac(int n)    //constexpr函数
    {
    return (n>1) ? n*fac(n-1) : 1;
    }
    
    void f(int n)
    {
    int f5 = fac(5);            //在编译期间可能进行了求值
    int fn = fac(n);            //在运行期间进行了求值(因为实参n是变量)
    constexpr int f6 = fac(6);  //在编译期间进行了求值
    constexpr int fnn = fac(n); //错误:无法在编译期求值,因为n的值在运行期才能得到
    }

    上例中给出了constexpr函数fac()的定义,在f()中列举了几种调用fac()的情形。在这里,编译期间能够求值的前提是fac()要为constexpr函数,此外还要保证其实参为常量,表达式被赋值变量为constexpr类型。

    注解

    不要试图让所有函数都变成 constexpr。大多数计算都最好在运行时进行。

    任何可能最终将依赖于高层次的运行时配置或者业务逻辑的API,都不应当是 constexpr 的。这种定制化是无法由编译期来求值的,并且依赖于这种 API 的任何 constexpr 函数也都应当进行重构,或者抛弃掉 constexpr

    Item 2: 以 constexpr 来定义可以在编译期计算的值

    理由

    更好的性能,更好的编译期检查。

    示例
    constexpr int f6 = fac(6);  //在编译期间进行了求值
    constexpr int fnn = fac(n); //错误:无法在编译期求值,因为n的值在运行期才能得到
    注解

    将变量声明为constexpr类型,编译器可以来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,并且必须用常量表达式初始化。

    转载于:https://www.cnblogs.com/Stephen-Qin/p/9100833.html

    展开全文
  • C++11系列-常量表达式

    2014-05-09 15:40:46
    这种改善之一就是生成常量表达式,允许程序利用编译时的计算能力。假如你熟悉模板元编程,你将发现constexpr使这一切变得更加简单。假如你不知道模板元编程,也没什么。constexpr使我们很容易利用上编译时编程的优势...

    C++11有一些这样的改善,这种改善保证写出的代码比以往任何时候的执行效率都要好。这种改善之一就是生成常量表达式,允许程序利用编译时的计算能力。假如你熟悉模板元编程,你将发现constexpr使这一切变得更加简单。假如你不知道模板元编程,也没什么。constexpr使我们很容易利用上编译时编程的优势。

    常量表达式主要是允许一些计算发生在编译时,即发生在代码编译而不是运行的时候。这是很大的优化:假如有些事情可以在编译时做,它将只做一次,而不是每次程序运行时。需要计算一个编译时已知的常量,比如特定值的sine或cosin?确实你亦可以使用库函数sin或cos,但那样你必须花费运行时的开销。使用constexpr,你可以创建一个编译时的函数,它将为你计算出你需要的数值。用户的电脑将不需要做这些工作。

    constexpr初探

    为了使函数获取编译时计算的能力,你必须指定constexpr关键字到这个函数。

    1
    2
    3
    4
    5
    6
    7
    
    constexpr int multiply (int x, int y)
    {
        return x * y;
    }
    
    // 将在编译时计算
    const int val = multiply( 10, 10 );
    

    除了编译时计算的性能优化,constexpr的另外一个优势是,它允许函数被应用在以前调用宏的所有场合。例如,你想要一个计算数组size的函数,size是10的倍数。如果不用constexpr,你需要创建一个宏或者使用模板,因为你不能用函数的返回值去声明数组的大小。但是用constexpr,你就可以调用一个constexpr函数去声明一个数组。

    1
    2
    3
    4
    5
    6
    
    constexpr int getDefaultArraySize (int multiplier)
    {
        return 10 * multiplier;
    }
    
    int my_array[ getDefaultArraySize( 3 ) ];
    

    constexpr函数的限制

    一个constexpr有一些必须遵循的严格要求:

    • 函数中只能有一个return语句(有极少特例)
    • 只能调用其它constexpr函数
    • 只能使用全局constexpr变量

    注意递归并不受限制。但只允许一个返回语句,那如何实现递归呢?可以使用三元运算符(?:)。例如,计算n的阶乘:

    1
    2
    3
    4
    
    constexpr int factorial (int n)
    {
        return n > 0 ? n * factorial( n - 1 ) : 1;
    }
    

    现在你可以使用factorial(2),编译器将在编译时计算这个值,这种方式运行更巧妙的计算,与内联截然不同。你无法内联一个递归函数。

    constexpr函数还有那些特点?

    一个constexpr函数,只允许包含一行可执行代码。但允许包含typedefs、 using declaration && directives、静态断言等。

    constexpr和运行时

    一个声明为constexpr的函数同样可以在运行时被调用,当这个函数的参数是非常量的:

    1
    2
    3
    
    int n;
    cin >> n;
    factorial( n );
    

    这意味着你不需要分别写运行时和编译时的函数。

    编译时使用对象

    假如你有一个Circle类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Circle
    {
        public:
        Circle (int x, int y, int radius) : _x( x ), _y( y ), _radius( radius ) {}
        double getArea () const
        {
            return _radius * _radius * 3.1415926;
        }
        private:
            int _x;
            int _y;
            int _radius;
    };
    

    你希望在编译期构造一个Circle接着算出他的面积。

    1
    2
    
    constexpr Circle c( 0, 0, 10 );
    constexpr double area = c.getArea();
    

    事实证明你可以给Circle类做一些小的修改以完成这件事。首先,我们需要将构造函数声明为constexpr,接着我们需要将getarea函数声明为constexpr。将构造函数声明为constexpr则运行构造函数在编译期运行,只要这个构造函数的参数为常量,且构造函数仅仅包含成员变量的constexpr构造(所以默认构造可以看成constexpr,只要成员变量都有constexpr构造)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    class Circle
    {
        public:
        constexpr Circle (int x, int y, int radius) : _x( x ), _y( y ), _radius( radius ) {}
        constexpr double getArea ()
        {
            return _radius * _radius * 3.1415926;
        }
        private:
            int _x;
            int _y;
            int _radius;
    };
    

    constexpr vs const

    假如你将一个成员函数标记为constexpr,则顺带也将它标记为了const。如果你将一个变量标记为constexpr,则同样它是const的。但相反并不成立,一个const的变量或函数,并不是constexpr的。

    constexpr和浮点数

    到这里我们讲到的constexpr功能都可以通过模板元编程实现。但constexpr支持的一项能力是可以计算浮点型的数据。因为double和float不是有效的模板参数,你不可以轻易的通过模板编译期计算浮点数的值。而constexpr允许编译期计算浮点型数据。

    权衡constexpr

    C++开发者早就深受修改一个头文件则引发重新编译导致编译缓慢的困扰。而constexpr可能引入增加编译时间的风险,但也有一些技术去降低这种风险。首先,因为constexpr函数相同的参数会输出相同的结果,所以它们可以被memoized,事实上GCC已经支持memoization。

    因为可以对constexpr函数memoize,所以用constexpr函数替换模板函数的地方,(编译)性能不会变得更坏,但代码会变得清晰。事实上,替换掉一部分模板实例,编译会显著加快。

    最后,标准允许编译器去限制递归函数的级数。这样可以限制深度递归的编译性能损耗。

    展开全文
  • 常量表达式:表达式就是由常量组成的,这时如果计算结果发生溢出,编辑器是会有下划线提醒的。 int x = 2147483647 + 10; 非常量表达式:表达式由一个或者多个非常量组成的,这时发生溢出是不会提醒的,使用...

    常量表达式:表达式就是由常量组成的,这时如果计算结果发生溢出,编辑器是会有下划线提醒的。

    int x = 2147483647 + 10; 

    非常量表达式:表达式由一个或者多个非常量组成的,这时发生溢出是不会提醒的,使用checked可以做溢出检查

             

    int ten = 10;
    int y = 2147483647 + ten;

     

    展开全文
  • c++常量和常量表达式

    千次阅读 2019-08-03 18:49:31
    const,默认情况下仅在文件内有效 const int i(12); const引用:对常量的引用不能被用作修改它所绑定的对象 ...允许常量引用绑定到非常量的对象、字面值或表达式上 int i = 20; const int &ri(20); con...
  • c语言各种类型常量表示方式

    千次阅读 2018-10-07 17:57:45
    xxxU : unsigned int xxxL : long int xxxLL : long long xxxF : float
  • 常量和常量表达式

    千次阅读 2013-11-02 22:05:28
    常量和常量表达式  long型常量以L或者l结尾,有时候,如果一个整数太大无法用int表达,也被当做long型;  无符号常量以U或者u结尾,unsigned long型常量以UL或者ul结尾;  没有后缀的浮点数常量为double型;  ...
  • 如图所示,pl是常量指针,而且需要用常量表达式初始化,按照常量表达式的规定,是在编译的时候就能确定出值的表达式。我的问题是,难道在编译的时候,就能确定普通变量 j 的地址了吗?为何图中可以如此初始化pl常量...
  • #include &lt;iostream&...//常量表达式 //1、运行时常量性与编译时常量性即const与constexpr const int GetConst(){ return 1; } //运行时常量 constexpr int GetConstexpr(){ return 1;...
  • C++常量表达式小结

    千次阅读 2016-10-16 17:36:31
    1 定义为constexpr类型的对象一般为字面值类型(算术类型,引用,指针等); 2 声明一个constexpr类型必须用constexpr初始化; 3 constexpr指针必须初始化为nullptr或0或是存放在固定地址中的变量;...
  • 表达式必须是常量表达式

    万次阅读 2014-03-21 09:58:33
    导入到其它的工程里面 case R.id.e : 出现了错误 错误提示为:case expressions must be constant expressions 网上查了一下 发现是 我的工程 勾选了isLibrary 的原因 ...将 勾选 去掉 再clear一下 就好了
  • 题目是:将两个字符数组链接起来拷贝给第三个字符数组。代码如下: ![图片说明]...报错大多是函数调用在常量表达式中必须含有常量值,请问是我初始化str1和str2的时候出错了么?
  • 替换成if else 参考资料: 中文:http://blog.csdn.net/wchinaw/article/details/7325641 英文文档:http://tools.android.com/tips/non-constant-fields
  • 常量表达式常量表达式指在编译时可以完全计算出结果的表达式,而不 是在程序运行时才能求值 常量表达式中的操作数只能为null 文本和整型、实数型、字符型、字符串型以及布尔型的字面常量或使用const声明的符号...
  • java中的switch语句 和 常量表达式

    千次阅读 2012-12-21 15:31:27
    switch的格式 ... case 值1:常量表达式(不可以是变量,也不可以是带变量的表达式);[break;]  case 值2:常量表达式(不可以是变量,也不可以是带变量的表达式);[break;]  case 值3:常量表达
  • 版权声明:本文为博主原创文章,转载请注明出处...Error:(149, 22) 错误: 需要常量表达式 Error:(149, 22) 错误: 需要常量表达式 解决方式: 将 switch中的case 改成 if 判断就可以了;注意:一般都会有提示的直接Al...
  • 常量表达式是指值不会改变且在编译过程中就能够得到计算结果的表达式,能在编译时求值的表达式。 例1: #include &lt;iostream&gt; using namespace std; int main() { const int a1 = 10; // a1是...
  • Android Studio 需要常量表达式

    千次阅读 2016-09-07 11:42:01
    某次修改build.gradle之后就出现了这种情况,排查了好久,发现是这个文件最上面一行被我写错了 错误的地方如下 ...出现这个问题基本上就是build文件出了问题,看了网上其他一些回答,并不仅限于这个地方出错。
  • 最近把主工程作为依赖工程,给另一个新的主工程使用时,AS报了一个错,如图: 矛头直指swich 语句,经过一番研究,发现用if 语句替换就可以解决问题了,原理俺也没弄明白,请路过的大神多多指教,这里做个...
  • 最近将一个项目作为library,通过import Moudle导入一个新项目引用时,爆出这个错误:需要常量表达式,定位到switch。于是百度一下,解决方法为把switch case,改成if else,即: @Override public boolean ...
1 2 3 4 5 ... 20
收藏数 227,658
精华内容 91,063
关键字:

常量表达式