C++11标准越来越趋于稳定和成熟,国外c++11如火如荼而国内却依然处于观望期。每当提到C++很多程序员都很抵触,特别是学术界的呼声更高一些。其实不然,语言即工具,语言的好坏不在于本身,而在于驾驭它和适用它所在的范围所决定的。那么为什么国内大多数程序员都会遭到抵触呢?我觉得原因有如下(不要劈我,仅此个人意见):
“千里之行始于足下”。我们先来看一下c++的内置类型,先从算数类型开始:整型和浮点型。先贴一张图:
该图取自《C++ Primer》
这是由于整数的符号位表示造成的。
零开通的整数代表8进制,0x和0X开头的整数代表16进制。值得注意一点是,浮点数的默认是double类型。字符串字面值如下:
在C++中初始化是创建变量并赋予初始值因此叫初始化,赋值操作是更新对象值即将右值更新到操作符左侧对象中。C++11新增了列表初始化,由花括号括起来,如下:
int a = {12};
int b{12};
在C++中如果在代码中使用变量,必须先声明该变量。定义是指在初次使用变量时就需要定义变量。变量可以多次声明,但只能定义一次。
C++ 中的复合类型(Complex Type)有引用、指针、类等。
引用即别名,引用必须被初始化,引用不是对象。,引用主要是通过bind技术来实现,并不是拷贝。指针即地址,指针是对象,通过解引用获取值。。两者都间接提供了访问对象的功能,其中C++11提供字面值nullptr来初始化指针。void * 可以存放任意对象地址.
#include <iostream>
int main() {
int a = 12;
int &b = a;
int *c = nullptr;
c = &a;
std::cout << "a==" << a << ";b==" << b << ";c==" << *c << std::endl;
return 0;
}
### 输出
a==12;b==12;c==12
常量表达式不会改变且在编译期间得到结果,字面值是常量表达式,用常量表达式初始化的const对象也是常量表达式。例如:
#include <iostream>
int main() {
#是常量表达式
const int a = 12;
#是常量表达式
const int c= a+24;
#不是常量表达,是变量。
int b = 12;
#不是常量表达式,在运行时获得值。
const int count = get_count();
return 0;
}
c++11规定,可以通过将变量声明未constexpr,由编译器来验证变量是否是一个常量表达式
#include <iostream>
int main() {
const int a = 12;
const int c= a+24;.
#是常量表达式
constexpr int b = 12;
constexpr int count = get_count();
return 0;
}
自定义类、IO库和string类型不属于字面值类型,所以不能被定义为constexpr,而算术类型、引用和指针都属于字面值类型所以可以定义为constexpr,但是constexpr指针必须是nullptr或者固定地址中的对象,并且constexpr仅对指针有效,与它所指向的对象无关。
#include <iostream>
int main() {
const int c = 12;
#a是一个指向常量整数的指针
const int *a = &c;
#d是一个指向整数的常量指针
constexpr int *d = nullptr;
return 0;
}
###输出结果
main.cpp: In function 'int main()':
main.cpp:6:25: error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
constexpr int *d = &c;
const 是修饰一个变量且该变量的值是不可被改变的,const对象必须初始化,const对象是对文件有效,如果想跨多个源文件都使用一个const对象,需要在定义和声明是都添加extern。即extern const int a = 12。对于const的引用,引用类型必须与其所引用对象的类型保持一致,当然在初始化变量时可以使用常量表达式作为初始值:
#include <iostream>
int main() {
int a = 12;
float k = 12.0;
const int &b = a;
const int &c = 42;
#是可以编译通过,主要是在编译器创建一个临时常量对象。
const int &j = k;(const int j = k;const int &j=k)
}
对于const来说只是限定了所修饰的变量,并不能限定右值。我们来看一下指针。 指向常量的指针和常量指针指向常量的指针说明是一个指针,该指针指向的常量的地址。常量指针说明是一个指针本身定义为常量。
#include <iostream>
int main() {
int a = 12;
const int b = 23;
#指向常量整型的指针,不能通过该指针改变所指向那个对象的值,并没有规定该指针对象的值不能通过其它路径改变。
const int *c = &b;
c = &a;
#指向整型的常量指针,指针本身是一个常量,不能通过其它路径改变该指针对象的值。
int* const d = &a;
}
auto和decltype是c++11新增的特性,auto能让编译器自动分析表达式所属类型;decltye选择并返回操作数的类型。例如:
#include <iostream>
#类似c语言的typedef作用,类型别名
using INTER = int;
int sum(const INTER &a, const INTER &b) {
return a + b;
}
int main(void) {
INTER a = 10, b = 20;
auto c = a + b;
std::cout << "c====" << c << std::endl;
decltype(sum(a, b)) d = b;
std::cout << "d====" << d << std::endl;
}
auto作用在带有const变量时一般会忽略掉。decltype使用的表达式不是一个变量时,则返回表达式结果对应的类型。比如:
#include <iostream>
int main(void) {
const int a = 10, b = 20;
auto c = a + b;
#可以看到auto已经忽略了const的限定
c = 30;
const auto d = a + b;
#编译器将会报错
d = 30;
int j=22,*p=&j,&r=j;
#i是一个int,j+21结果还是int.
decltype(j+21) i;
#p是一个指针,*p对指针进行解引用将得到引用类型,即int &k
decltype(*j) k;
#双括号永远是引用
decltype((j)) q;
}
c++11在探索着……