C++17新语法之if和switch语句中可以初始化变量啦

29 篇文章 32 订阅
7 篇文章 0 订阅

前言

今天在看一些c++代码时偶然间发现一些示例,在if语句的小括号内居然出现了分号,难道这一段是伪代码吗?之前从来没见过这种写法,然后用写了一个例子,用最新的编译器编译后发现真的是正常的代码,并且可以成功运行,然后脑袋有个声音一闪而过,是不是一直就支持这种写法,只是我不知道而已,后来几经周折,终于发现真相,原来这其实是C++17新的语法。

if 语句本来的样子

C++17之前 if 语句的小括号内只能放判断逻辑,if (condition) { /* ... */ } 也就是这样,所以如果想使用一个变量进行判断,那么这个变量必须在if语句之前进行定义,比如我们常常使用的查找map元素的逻辑:

{
    auto it = mp.find("key");
    if (it != mp.end())
        return it->second;
    else
        return defaultValue;
}

if 语句新能力

从C++17开始,if 语句的小括号之中也可以初始化变量了,语法为 if (initializer; condition) { /* ... */ },这样做的好处就是可以更加精细的控制变量的作用域,使代码看起来更加紧凑,比如上面的例子可以改写为:

{
    if (auto it = mp.find("key"); it != mp.end())
        return it->second;
    else
        return defaultValue;
}

最直观的感受就是少了一行代码,但是更重要的特点还是他把变量 it 的作用域限制在了 if 语句之内。

另外就是能一定程度上解决代码缩进层数太多的问题,这也是实际开发过程中遇到的问题,比如下面这段代码:

{
    auto it = mp.find("key");
    if (it != mp.end())
        return it->second;
    else
    {
        int cfg = GetConfig();
        if (cfg)
            return defaultValue1;
        else
            return defaultValue2;
    }
}

在C++17之前的代码中,因为 if 语句中不能包含初始化变量的逻辑,所以会造成 if 嵌套层层递进,当这种条件太多时,缩进层数太多导致代码可读性变差,使用C++17的语法再改进一下就变成了下面这样,逻辑更加清晰了:

{
    if (auto it = mp.find("key"); it != mp.end())
        return it->second;
    else if (int cfg = GetConfig(); cfg)
        return defaultValue1;
    else
        return defaultValue2;
}

switch 语句也是相同的能力扩展,就不再展开说了,这里贴一个 cppreference - switch 上的例子:

{
    struct Device
    {
        enum State { SLEEP, READY, BAD };
        auto state() const { return m_state; }

        /*...*/

    private:
        State m_state{};
    };

    switch (auto dev = Device{}; dev.state())
    {
        case Device::SLEEP:
            /*...*/
            break;
        case Device::READY:
            /*...*/
            break;
        case Device::BAD:
            /*...*/
            break;
    }
}

似曾相识在go中

这个在if中既初始化又进行判断的语法,之前在go中也用过,类似的需求在go中的写法是:

func xxx() {
    if value := mp["key"]; value != nil {
        return value
    } else {
        return defaultValue
    }
}

是不是很像?其实在golang中更规范的用法是使用map查找的第二个返回值来判断元素是否存在,就像下面这样:

func xxx() {
    if value, ok := mp["key"]; ok {
        return value
    } else {
        return defaultValue
    }
}

关于语言的思考

看到上面这种golang和c++17的对比,会发现语言之间都在相互促进,这些所谓的高级语言,总能在其中一种语言中发现另一种语言的影子,也就是说在某些方面上他们是“趋同”的,可能在不久的将来会出现一种“超高级语言”,类似于C++模板机制,C++GolangPython 这些语言作为一种类型,传递到超高级语言之中,编写或者描述完功能逻辑后,自动生成对应语言的代码:

SuperLanguageTemplate<C++/Golang/Python>
[AutoGenerateByFollowingDescription]
{
    / * ... * /
}

总结

  • ifswitch 语句都可以在逻辑判断前初始化变量,变量的定义域可以更精细的控制
  • 编程语言之间相互“借鉴”,部分语法长得越来越像,最后不知道会不会归于统一

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

人生并不是不断失去,反过来看,其实人生应该是不断拥有,1秒,2秒,3秒,这些本就不一定属于你的时间,作为馈赠出现在了你的生命里~

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
复习资料 1.1选择题 1.在一个C++程序,main函数的位置( c )。 (a) 必须在程序的开头 (b) 必须在程序的后面 ( c ) 可以在程序的任何地方 (d) 必须在其它函数间 2.用C++语言编制的源程序要变为目标程序必须要经过( d )。 (a) 解释 (b) 汇编 (c) 编辑 (d) 编译 3.C++程序基本单位是( c )。 (a) 数据 (b) 字符 (c) 函数 (d) 语句 4. C++程序语句必须以( b )结束。 (a) 冒号 (b) 分号 (c) 空格 (d)花括号 5. 执行C++程序时出现的“溢出”错误属于( c )错误。 (a) 编译 (b) 连接 (c) 运行 (d) 逻辑 6.下列选项,全部都是C++关键字的选项为( c )。 (a) while IF static (b) break char go (c) sizeof case extern (d) switch float integer 7. 按C++标识符的语法规定,合法的标识符是( a ,c )。 (a) _abc (b) new (c) int1 (d) “age” 8.下列选项,( a )不是分隔符。 (a) ? (b) ; (c) : (d) () 9.下列正确的八进制整型常量表示是( b )。 (a) 0a0 (b) 015 (c) 080 (d) 0x10 10.下列正确的十六进制整型常量表示是( a,b,d )。 (a) 0x11 (b) 0xaf (c) 0xg (d) 0x1f 11.在下列选项,全部都合法的浮点型数据的选项为( a,b,d ),全部都不合法的浮点型数据选项是( c )。 (a) -1e3 , 15. , 2e-4 (b) 12.34 , -1e+5 , 0.0 (c) 0.2e-2.5 , e-5 (d) 5.0e-4 , 0.1 , 8.e+2 12.下列正确的字符常量为( b,d )。 (a) " a " (b) '\0' (c) a (d) '\101' 13.下列选项,( a,b,c )能交换变量a和b的值。 (a) t=b ;b=a ;a=t; (b) a=a+b ;b=a-b ;a=a-b; (c) t=a ;a=b ;b=t; (d) a=b ; b=a ; 14.执行语句 int i = 10,*p = &i; 后,下面描述错误的是( a )。 (a) p的值为10 (b) p指向整型变量i (c) *p表示变量i的值 (d) p的值是变量i的地址 15.执行语句 int a = 5,b = 10,c;int *p1 = &a, *p2 = &b; 后,下面不正确的赋值语句是( b )。 (a) *p2 = b; (b) p1 = a; (c) p2 = p1; (d) c = *p1 *(*p2); 16.执行语句 int a = 10,b;int &pa = a,&pb = b; 后,下列正确的语句是( b )。 (a) &pb = a; (b) pb = pa; (c) &pb = &pa; (d) *pb = *pa; 17.执行下面语句后,a和b的值分别为( b )。 int a = 5,b = 3,t; int &ra = a; int &rb = b; t = ra;ra = rb;rb = t; (a) 3和3 (b) 3和5 (c) 5和3 (d) 5和5 18. 在下列运算符,( d )优先级最高。 (a) <= (b)*= (c)+ (d)* 19. 在下列运算符,( d )优先级最低。 (a) ! (b)&& (c)!= (d)?: 20.设i=1,j=2,则表达式i+++j的值为( c )。 (a) 1 (b)2 (c)3 (d)4 21.设i=1,j=2,则表达式 ++i+j的值为( d )。 (a)1 (b)2 (c)3 (d)4 22.在下列表达式选项,( c )是正确。 (a)++(a++) (b)a++b (c)a+++b (d)a++++b 23.已知i=0,j=1,k=2,则逻辑表达式 ++i||--j&&++k的值为( b )。 (a) 0 (b)1 (c)2 (d)3 24. 执行下列语句后,x的值是( d ),y的值是( c )。 int x , y ; x = y = 1; ++ x || ++ y ; (a) 不确定 (b) 0 (c) 1 (d) 2 25.设X为整型变量,能正确表达数学关系1< X < 5的C++逻辑表达式是( b, c, d )。 (a) 1<X<5 (b) X==2||X==3||X==4 (c) 1<X&&X<5 (d) !(X<=1)&&!(X>=5) 26. 已知x=5,则执行语句 x += x -= x*x ; 后,x的值为( c )。 (a)25 (b)40 (c)-40 (d)20 27. 设a=1,b=2,c=3,d=4,则条件表达式a<b?a:c<d?c:d的值为( a )。 (a) 1 (b)2 (c)3 (d)4 28. 逗号表达式“(x=4*5,x*5),x+25的值为( d )。 (a) 25 (b)20 (c)100 (d)45 1.已知 int i,x,y;在下列选项错误的是( c )。 (a) if(x == y)i++; (b) if(x = y)i--; (c) if( xy )i--; (d) if( x+y )i++; 2.设有函数关系为y= ,下面选项能正确表示上述关系为( c )。 (a) y = 1; (b) y = -1; if( x>=0 ) if( x!=0) if( x==0 )y=0; if( x>0 )y = 1; else y = -1; else y = 0 (c) if( x<=0 ) (d) y = -1; if( x<0 )y = -1; if( x<=0 ) else y = 0; if( x<0 )y = -1; else y = 1; else y = 1; 3.假设i=2,执行下列语句后i的值为( b )。 switch(i) { case 1:i++; case 2:i--; case 3:++i;break; case 4:--i; default:i++; } (a) 1 (b) 2 (c) 3 (d) 4 4.已知int i=0,x=0;下面while语句执行时循环次数为( d )。 while(!x && i<3 ){ x++;i++;} (a) 4 (b) 3 (c) 2 (d) 1 5.已知int i=3;下面do_while 语句执行时循环次数为( b )。 do{ i--; cout<<i<<endl;}while( i!= 1 ); (a) 1 (b) 2 (c) 3 (d) 无限 6.下面for语句执行时循环次数为( b )。 for ( int i=0,j=5;i=j;) { cout << i << j << endl; i++;j--; } (a) 0 (b) 5 (c) 10 (d) 无限 7.以下死循环的程序段是( b )。 (a) for(int x=0;x<3 ;){ x++;}; (b) int k=0; do { ++k;} while( k>=0 ); (c) int a=5;while(a){ a--;}; (d) int i=3;for(;i;i--); 1.以下正确的函数原型为( d )。 (a) f( int x; int y ); (b) void f( x, y ); (c) void f( int x, y ); (d) void f( int, int ); 2.有函数原型 void fun1( int ); 下面选项,不正确的调用是( c )。 (a) double x = 2.17 ; fun1( x ); (b) int a = 15 ; fun1( a*3.14 ) ; (c) int b = 100 ; fun1( & b ); (d) fun1( 256 ); 3.有函数原型 void fun2( int * ); 下面选项,正确的调用是( c )。 (a) double x = 2.17 ; fun2( &x ); (b) int a = 15 ; fun2( a*3.14 ); (c) int b = 100 ; fun2( &b ); (d) fun2( 256 ); 4.有函数原型 void fun3( int & ); 下面选项,正确的调用是( c )。 (a) int x = 2.17; fun3( &x ); (b) int a = 15; fun3( a*3.14 ); (c) int b = 100; fun3( b ); (d) fun3( 256 ) ; 5.有声明 int fun4( int ); int (*pf)(int) = fun4; 下面选项,正确的调用是( c )。 (a) int a = 15 ;int n = fun4( &a ); (b) int a = 15; cout<<pf(a*3.14); (c) cout<<(*pf)( 256 ); (d) cout << *pf( 256 ); 注意:选项(b)也可以调用函数fun4,但由于实参为浮点型表达式,VC6编译器将出现与形参类型不匹配的警告。 6.在VC,若定义一个函数的返回类型为void,以下叙述正确的是( a,c )。 (a) 用语句调用函数 (b) 用表达式调用函数 (c) 没有返回值 (d) 通过return语句可以返回指定值 7.函数参数的默认值不允许为( c )。 (a) 全局常量 (b) 全局变量 (c) 局部变量 (d) 函数调用 8.使用重载函数编程序的目的是( a )。 (a) 使用相同的函数名调用功能相似的函数 (b) 共享程序代码 (c) 提高程序的运行速度 (d) 节省存贮空间 9.下列的描述( b )是错误的。 (a) 使用全局变量可以从被调用函数获取多个操作结果 (b) 局部变量可以初始化,若不初始化,则系统默认它的值为0 (c) 当函数调用完后,静态局部变量的值不会消失 (d) 全局变量若不初始化,则系统默认它的值为0 10.下列选项,( c ,d )的具有文件作用域。 (a) 语句标号 (b) 局部变量 (c) 全局变量 (d) 静态全局变量 1.以下对一维数组 a 的正确定义是( c )。 (a) int n = 5, a[n]; (b) int a(5); (c) const int n = 5; int a[n]; (d) int n; cin>>n; int a[n]; 2.下列数组定义语句,不合法的是( a )。 (a) int a[3] = { 0, 1, 2, 3 }; (b) int a[] = { 0, 1, 2 }; (c) int a[3] = { 0, 1, 2 }; (d) int a[3] = { 0 }; 3.已知 int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }, *p = a ;则不能表示数组 a 元素的式子是( c )。 (a) *a (b) *p (c) a (d) a[ p-a ] 4.已知 int a[] = { 0, 2, 4, 6, 8, 10 }, *p = a ; 值不等于0的表达式是( b,d )。 (a) *(p++) (b) *(++p) (c) *(p-- ) (d) *(--p) 5.以下不能对二维数组a进行正确初始化语句是( c )。 (a) int a[2][3] = { 0 }; (b) int a[][3] = { { 0, 1 }, { 0 } }; (c) int a[2][3] = { { 0, 1 }, { 2, 3 }, { 4, 5 } }; (d) int a[][3] = { 0, 1, 2, 3, 4, 5 }; 6.已知int a[][3] = { { 0, 1 }, { 2, 3, 4 }, { 5, 6 }, { 7 } } ;则 a[2][1]的值是( c )。 (a) 0 (b) 2 (c) 6 (d) 7 7.已知int a[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ; 则不能表示数组元素a[2][1]的地址是( a,b )。 (a) &[2][1] (b) *(a[2]+1) (c) a[2]+1 (d) *(a+2)+1 8.已知char *a[]={ "fortran", " basic", "pascal", "java", "c++" ; 则 cout<<a[3];的显示结果是( c )。 (a) t (b) 一个地址值 (c) java (d) javac++ 9.若用数组名作为调用函数的实参,则传递给形参的是( a )。 (a) 数组存贮首地址 (b) 数组的第一个元素值 (c) 数组全部元素的值 (d) 数组元素的个数 10.在下列选项,( b, d )是错误的。 (a) gets和puts函数可以输入输出包含空格的字符串 (b) cin不能输入包含空格的字符串 (c) cout不能输出包含空格的字符串 (d) 使用赋值运算符可以对字符数组整体赋值 11.下列描述,错误的是( c )。 (a) 输出字符指针就是输出字符串 (b) 输出字符指针的间接引用就是输出单个字符 (c) 具有相同字符的两个字符串常量相等 (d) 两个数组名的比较是地址的比较 12.判断字符串s1和s2是否相等的表达式为( d )。 (a) s1=s2 (b) s1==s2 (c) strcpy(s1,s2)==0 (d) strcmp(s1,s2)==0 13.判断字符串s1是否大于字符串s2的表达式为( c )。 (a) s1>s2 (b) strcmp(s1,s2)==0 (c) strcmp(s1,s2)>0 (d) strcmp(s2,s1)>0 5.若有以下声明和定义,则下列错误的引用是( d )。 struct worker { int no ; char name[ 20 ] ; } w, *p = &w ; (a) w.no (b) p->no (c) (*p).no (d) *p.no 6.若有以下声明和定义,则下列引用非法的是( d )。 struct data { int n; float score; data *q ; }; data a[3] = {1001,87,&a[1],1002,75,&a[2],1003,90,&a[0]}; data *p = a; (a) p->n++ (b) (*p).n++ (c) ++p->n (d) *p->n 7.关于类和对象不正确的说法是( c )。 (a) 类是一种类型,它封装了数据和操作 (b) 对象是类的实例 (c) 一个类的对象只有一个 (d) 一个对象必属于某个类 8.在类定义的外部,可以被访问的成员有( c )。 (a) 所有类成员 (b) private或protected的类成员 (c) public的类成员 (d) public或private的类成员 9.关于this指针的说法错误的是( a,d )。 (a) this指针必须显式说明 (b) 当创建一个对象后,this指针就指向该对象 (c) 成员函数拥有this指针 (d) 静态成员函数拥有this指针 10.声明一个类的对象时,系统自动调用( b,d )函数;撤消对象时,系统自动调用( c )函数。 (a) 成员函数 (b) 构造函数 (c) 析构函数 (d) 复制构造函数 11.下面对构造函数的不正确描述是( b )。 (a) 系统可以提供默认的构造函数 (b) 构造函数可以有参数,所以也可以有返回值 (c) 构造函数可以重载 (d) 构造函数可以设置默认参数 12.下面对析构函数的正确描述是( a,c )。 (a) 系统可以提供默认的析构函数 (b) 析构函数必须由用户定义 (c) 析构函数没有参数 (d) 析构函数可以设置默认参数 13.对静态成员的不正确描述是( c,d )。 (a) 静态成员不属于对象,是类的共享成员 (b) 静态数据成员要在类外定义和初始化 (c) 调用静态成员函数时要通过类或对象激活,所以静态成员函数拥有this指针 (d) 只有静态成员函数可以操作静态数据成员 14.下面选项,不是类的成员函数为( c )。 (a) 构造函数 (b) 析构函数 (c) 友元函数 (d) 复制构造函数 15.下面对友员的错误描述是( d )。 (a) 关键字friend用于声明友员 (b) 一个类的成员函数可以是另一个类的友员 (c) 友员函数访问对象的成员不受访问特性影响 (d) 友员函数通过this指针访问对象成员 1.在下列运算符,能重载的是( a,c,d )。 (a) ! (b) sizeof (c) new (d) delete 2. 在下列运算符,不能重载的是( c )。 (a) <= (b) >> (c) && (d) &= 3.下列关于运算符重载的描述,( d )是正确的。 (a) 可以改变参与运算的操作数个数 (b) 可以改变运算符原来的优先级 (c) 可以改变运算符原来的结合性 (d) 不能改变原运算符的语义 4.下列函数,能重载运算符的函数是( b,c )。 (a) 成员函数 (b) 构造函数 (c) 析构函数 (d) 友员函数 5.不能用友员函数重载的是( a )。 (a) = (b) == (c) += (d) != 6.下面描述,错误的是( b )。 (a) 只有系统预先定义的运算符才可能被重载 (b) 使用类型转换函数不能把一个类转换为另一个类 (c) 使用类型转换函数可以把类转换为基本类型 (d) 类型转换函数只能定义为一个类的成员函数,不能定义为类的友员函数 1.在c++,类与类之间的继承关系具有( c )。 (a) 自反性 (b) 对称性 (c) 传递性 (d) 反对称性 2.下列关于类的继承描述,( a,b )是错误的。 (a) 派生类可以访问基类的所有数据成员,调用基类的所有成员函数 (b) 派生类也是基类,所以基类具有派生类的全部属性和方法 (c) 继承描述类的层次关系,派生类可以具有与基类相同的属性和方法 (d) 一个基类可以有多个派生类,一个派生类可以有多个基类 3.当一个派生类公有继承一个基类时,基类的所有公有成员成为派生类的( a )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 4.当一个派生类私有继承一个基类时,基类的所有公有成员和保护成员成为派生类的( b )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 5.当一个派生类保护继承一个基类时,基类的所有公有成员和保护成员成为派生类的( c )。 (a) public 成员 (b)private成员 (c) protected成员 (d)友员 6.不论派生类以何种方式继承基类,都不能使用基类的( b )。 (a) public 成员 (b)private成员 (c) protected成员 (d)public 成员和protected成员 7.下面描述,错误的是( b, c )。 (a) 在基类定义的public成员在公有继承的派生类可见,也能在类外被访问 (b) 在基类定义的public和protected成员在私有继承的派生类可见,在类外可以被访问 (c) 在基类定义的public和protected成员在保护继承的派生类不可见 (d) 在派生类不可见的成员要变成可访问的需进行访问声明 8.在c++,不能被派生类继承的函数是( b,c )。 (a) 成员函数 (b)构造函数 (c) 析构函数 (d)静态成员函数 9.在创建派生类对象时,构造函数的执行顺序是( d )。 (a) 对象成员构造函数、基类构造函数、派生类本身的构造函数 (b) 派生类本身的构造函数、基类构造函数、对象成员构造函数 (c) 基类构造函数、派生类本身的构造函数、对象成员构造函数 (d) 基类构造函数、对象成员构造函数、派生类本身的构造函数 10.当不同的类具有相同的间接基类时,有特点( d )。 (a) 各派生类对象将按继承路线产生自己的基类版本 (b) 派生类对象无法产生自己的基类版本 (c) 为了建立惟一的间接基类版本,应该必须改变类格 (d) 为了建立惟一的间接基类版本,应该声明虚继承 1.在C++,要实现动态联编,必须使用( d )调用虚函数。 (a) 类名 (b) 派生类指针 (c) 对象名 (d) 基类指针 2.下列函数,可以作为虚函数的是( c,d )。 (a) 普通函数 (b) 构造函数 (c) 成员函数 (d) 析构函数 3.在派生类,重载一个虚函数时,要求函数名、参数的个数、参数的类型、参数的顺序和函数的返回值( b )。 (a) 不同 (b) 相同 (c) 相容 (d) 部分相同 4.下面函数原型声明,( b )声明了fun为纯虚函数。 (a) void fun()=0; (b)virtual void fun()=0; (c) virtual void fun(); (d)virtual void fun(){ }; 5.若一个类含有纯虚函数,则该类称为( d )。 (a) 基类 (b) 纯基类 (c) 派生类 (d) 抽象类 6.假设 Aclass为抽象类,下列声明( a,c,d )是错误的。 (a) Aclass fun( int ) ; (b)Aclass * p ; (c) int fun( Aclass ) ; (d)Aclass Obj ; 7.下面描述,正确的是( b,d )。 (a) 虚函数是没有实现的函数 (b) 纯虚函数的实现在派生类定义 (c) 抽象类是只有纯虚函数的类 (d) 抽象类指针可以指向不同的派生类 使用虚函数编写程序求球体和圆柱体的体积及表面积。由于球体和圆柱体都可以看作由圆继承而来,所以可以定义圆类circle作为基类。在circle类定义一个数据成员radius和两个虚函数area()和volume()。由circle类派生sphere类和column类。在派生类对虚函数area()和volume()重定义,分别求球体和圆柱体的体积及表面积。 #include <iostream.h>const double PI=3.14159265;class circle{ public: circle(double r) { radius = r; } virtual double area() { return 0.0; } virtual double volume() { return 0.0; } protected: double radius;};class sphere:public circle{ public: sphere( double r ):circle( r ){ } double area() { return 4.0 * PI * radius * radius; } double volume() { return 4.0 * PI * radius * radius * radius / 3.0; }};class column:public circle{ public: column( double r,double h ):circle( r ) { height = h; } double area() { return 2.0 * PI * radius * ( height + radius ); } double volume() { return PI * radius * radius * height; } private: double height;};void main(){ circle *p; sphere sobj(2); p = &sobj; cout << "球体:" << endl; cout << "体积 = " << p->volume() << endl; cout << "表面积 = " << p->area() << endl; column cobj( 3,5 ); p = &cobj; cout << "圆柱体:" << endl; cout << "体积 = " << p->volume() << endl; cout << "表面积 = " << p->area() << endl;} 2、定义一个Book(图书)类,在该类定义包括 数据成员: bookname(书名)、price(价格)和number(存书数量); 成员函数: display()显示图书的情况;borrow()将存书数量减1,并显示当前存书数量;restore()将存书数量加1,并显示当前存书数量。 在main函数,要求创建某一种图书对象,并对该图书进行简单的显示、借阅和归还管理。 #include <stdlib.h>#include <stdio.h>int main(){class Book{public:long number;float price;char *bookname;void display(){printf("The name of this book is:%s\n",bookname);printf("The price of this book is:%fdolars\n",price);printf("The number of such book is:%d\n",number);}void restore(){number++;}void borrow(){number--;}};Book b;b.bookname="Harry Potter";b.price=18.00;b.number=100;b.display();b.borrow();b.display();b.restore();b.display();system("pause");return 0;} 1. #include <iostream.h> void main() { int a,b,c,d,x; a = c = 0; b = 1; d = 20; if( a ) d = d-10; else if( !b ) if( !c ) x = 15; else x = 25; cout << d << endl; } 2. #include <iostream.h> void main() { int a = 0, b = 1; switch( a ) { case 0: switch( b ) { case 0 : cout << "a=" << a << " b=" << b << endl; break; case 1 : cout << "a=" << a << " b=" << b << endl; break; } case 1: a++; b++; cout << "a=" << a << " b=" << b << endl; } } 3. #include <iostream.h> void main() { int i = 1; while( i<=10 ) if( ++i % 3 != 1 ) continue; else cout << i << endl; } 4、#include < iostream.h > class T { public : T( int x, int y ) { a = x ; b = y ; cout << "调用构造函数1." << endl ; cout << a << '\t' << b << endl ; } T( T &d ) { cout << "调用构造函数2." << endl ; cout << d.a << '\t' << d.b << endl ; } ~T() { cout << "调用析构函数."<<endl; } int add( int x, int y = 10 ) { return x + y ; } private : int a, b ; }; void main() { T d1( 4, 8 ) ; T d2( d1 ) ; cout << d2.add( 10 ) << endl ; } 答案: 调用构造函数1. 4 8 调用构造函数2. 4 8 20 调用析构函数. 调用析构函数. 5. #include < iostream.h > struct data { int n ; float score ; } ; void main() { data a[3] = { 1001,87,1002,72,1003,90 } , *p = a ; cout << (p++)->n << endl ; cout << (p++)->n << endl ; cout << p->n++ << endl ; cout << (*p).n++ << endl ; } 6. #include < iostream.h > struct node { char * s ; node * q ; } ; void main() { node a[ ] = { { "Mary", a+1 }, { "Jack", a+2 }, { "Jim", a } } ; node *p = a ; cout << p->s << endl ; cout << p->q->s << endl ; cout << p->q->q->s << endl ; cout << p->q->q->q->s << endl ; }
概念C语言”突破了以往任何一种语言教材的旧的模式,将教学内容分为入门篇和提高篇两个篇章。在入门篇只引进程序设计必要的语法现象,达到快速入门。激发兴趣的目的。在入门篇和提高篇之间插一个强化上机实验周,巩固学习内容。在提高篇完成完整的语法、算法、程序设计思想等教学目的的学习任务。由于学生对语言已具有了初步的了解并掌握了最基本的语法和程序设计思想,能设计较简单的程序,所以在提高篇的学习,不论对灵活语法的学习和掌握,还是对程序设计思想的掌握都更加容易,从而可以较容易达到教学目标。 第一部分 入门篇 1 第1章 C语言的产生及其工作流程 3 1.1 C语言的产生 3 1.2 程序和程序设计 3 1.2.1 C程序 3 1.2.2 程序设计 4 习题 4 第2章 C程序设计的初步知识 5 2.1 简单C程序的构成和格式 5 2.2 常量、变量和标识符 6 2.2.1 标识符 6 2.2.2 常量 7 2.2.3 用定义一个符号名的方法来代表一个常量 7 2.2.4 变量 8 2.3 整型数据 8 2.3.1 整型常量 8 2.3.2 整型变量 8 2.4 实型数据 9 2.4.1 实型常量 9 2.4.2 实型变量 9 2.5 字符型数据 10 2.5.1 字符常量 10 2.5.2 字符串常量 11 2.5.3 字符变量 11 2.6 算术表达式 11 2.6.1 基本的算术运算符 11 2.6.2 运算符的优先级、结合性和算术表达式 12 2.6.3 强制类型转换表达式 13 2.7 赋值表达式 13 2.7.1 赋值运算符和赋值表达式 13 2.7.2 赋值运算的类型转换 14 习题 15 第3章 顺序结构程序 16 3.1 复合语句和空语句 16 3.1.1 复合语句 16 3.1.2 空语句 16 3.2 程序举例 16 习题 17 第4章 选择结构 19 4.1 关系运算和逻辑运算 19 4.1.1 C语言的逻辑值 19 4.1.2 关系运算符和关系表达式 19 4.1.3 逻辑运算符和逻辑表达式 20 4.2 if语句和用if语句构成的选择结构 21 习题 22 第5章 循环结构 25 5.1 for语句和用for语句构成的循环结构 25 5.1.1 for语句构成的循环结构 25 5.1.2 for循环的执行过程 25 5.1.3 有关for语句的说明 25 5.2 循环结构的嵌套 27 习题 28 第6章 函数 30 6.1 函数的定义和返回值 30 6.1.1 函数定义的语法 30 6.1.2 函数的返回值 30 6.2 函数的调用 32 6.2.1 函数的调用方式 32 6.2.2 函数调用时的语法要求 32 6.3 函数的说明 33 6.3.1 函数说明的形式 33 6.3.2 函数说明的位置 34 6.4 调用函数和被调用函数之间的数据传递 34 6.5 库函数 36 6.6 数据输入输出及常用库函数 37 6.6.1 printf函数(格式输出函数) 37 6.6.2 scanf函数(格式输入函数) 39 6.6.3 调用putchar和getchar函数输出和输入字符 40 6.7 程序举例 41 习题 43 第7章 数组 45 7.1 一维数组的定义和一维数组元素的引用 45 7.1.1 一维数组的定义 45 7.1.2 一维数组元素的引用 46 7.1.3 一维数组的初始化 46 7.1.4 一维数组的定义和数组元素引用举例 47 7.2 函数之间对一维数组和数组元素的引用 47 7.2.1 数组元素做实参 47 7.2.2 数组名做实参 49 7.3 一维数组应用举例 50 7.4 字符数组 53 7.4.1 字符数组的定义 53 7.4.2 字符数组的初始化 54 7.4.3 字符数组的引用 54 7.4.4 字符串与字符串结束标志 55 7.4.5 字符数组的输入输出 56 7.4.6 字符串处理函数 58 7.4.7 字符数组应用举例 60 习题 61 第8章 文件 63 8.1 C语言文件的概念 63 8.2 打开文件 64 8.3 关闭文件 65 8.4 调用getc(fgetc)和putc(fputc)等常用函数进行输入和输出 65 8.5 判断文件结束函数feof 68 习题 69 第二部分 提高篇 71 第9章 算法 73 9.1 算法 73 9.2 结构化程序设计和模块化结构 74 9.2.1 结
目录 第1篇初级篇 第1章 初识C++ 1.1 c++简介 1.2 C++与C的区别 1.3 学习c++之前需要先学C吗 1.4 c++与其他语言的区别 1.5 c++的版本以及安装问题 第2章 做一个最简短的C4-+程序 2.1 简单的屏幕输出小程序 2.2 输出语句的使用 2.3 std::介绍 2.4 iostream与iostream.h的区别 2.5 重名问题 2.6 注释 2.7 总结 第3章 初步了解函数 3.1 一个简单的函数 3.2 函数的传参 3.3 函数的返回值、参数与变量 3.4.函数的声明与定义 3.5 局部变量 3.6 全局变量 3.7 总结 第4章 C4-+数据类型 4.1 变量的定义 4.2 将变量及数据存储在内存 4.3 布尔型变量 4.4 字符型变量 4.5 wchart双字符型变量 4.6 整型概述 4.7 整型变量的定义 4.8 浮点型变量 4.9 常量 4.10枚举型常量 第5章 if语句与运算符 5.1 语句的定义 5.2 块的定义 5.3 表达式的定义 5.4 运算符的定义 5.4.1 赋值运算符的定义 5.4.2 数学运算符的定义 5.4.3 赋值运算符与数学运算符的联合 5.5 自加与自减 5.5.1 前置 5.5.2 后置 5.6 表达式的优先级 5.7 关系运算符 5.8 if语句 5.8.1 else语句 5.8.2 elseif语句 5.8.3 if语句的嵌套 5.9 逻辑运算符及其使用 5.9.1 逻辑“与” 5.9.2 逻辑“或” 5.9.3 逻辑“非” 5.9.4 逻辑运算符的优先级 5.9.5 运算式的真假关系 5.1 0三目运算符 5.1 0.1 三目运算符的优先问题 5.1 0.2 三目运算符的使用问题 5.1 0.3 三目运算符的型别问题 5.1 0.4 三目运算符在字符型变量的应用 5.1 1复杂嵌套的if语句 5.1 2总结 第6章 面向对象 6.1 面向对象程序语言的主要特征 6.2 类、对象和成员 6.3 类、对象和成员的使用方法及区别 6.3.1 声明一个类 6.3.2 命名习惯 6.3.3 定义一个对象 6.3.4 类与对象的区别 6.3.5 对象与成员的关系 6.3.6 不要给类赋值 6.3.7 对象只能调用类存在的方法 6.4 公有 6.5 私有 6.6 成员函数的声明和定义 6.7 内联函数 6.7.1 普通内联函数 6.7.2 内联成员函数 6.8 头文件与源文件 6.9 const成员函数 6.10构造函数 6.11默认构造函数 6.12析构函数 6.13析构对象数组 6.14总结 第7章 循环语句 7.1 循环语句的前身——goto语句 7.2 慎用goto语句 7.3 while语句 7.3.1 带运算符的while语句 7.3.2 以字符为条件的while语句 7.3.3 限定while循环的次数 7.3.4 continue语句 7.3.5 break语句 7.3.6 永不休止的while循环 7.4. do……while循环 7.5 for循环 7.5.1 灵活的for循环 7.5.2 条件为空的for循环 7.5.3 执行为空的for循环 7.5.4 嵌套的for循环 7.6 switch语句 7.6.1 switch语句常见错误 7.6.2 switch的菜单功能 7.7 总结 第8章 指针 8.1 什么是地址 8.2 用指针来保存地址 8.2.1 空指针 8.2.2 指针与变量类型 8.2.3 用指针来访问值 8.2.4 指针地址、指针保存的地址和 该地址的值 8.2.5 指针对数值的操作 8.2.6 更换指针保存的地址 8.3 为什么使用指针 8.3.1 栈和堆 8.3.2 用指针创建堆空间 8.3.3 用指针删除堆空间 8.4 动态内存 8.4.1 内存泄漏 8.4.2 在堆创建对象 8.4.3 在堆删除对象 8.4.4 访问堆的数据成员 8.4..5 在构造函数开辟内存空间 8.4.6 对象在栈与堆的不同 8.5 this指针 8.6 指针的常见错误 8.7 指针运算 8.7.1 指针的加减运算 8.7.2 指针的赋值运算 8.7 _3指针的相减运算 8.7.4 指针的比较运算 8.8 指针 8.8.1 常量指针 8.8.2 指向常量的指针 8.8.3 指向常量的常指针 8.9 总结 第9章 引用 9.1 什么是引用 9.1.1 引用的地址 9.1.2 引用就是别名常量 9.1.3 引用对象 9.1 4空引用 9.2 函数的参数传递 9.2.1 按值传递 9.2.2 按址传递 9.2.3 按别名传递 9.2.4 让函数返回多个值 9.3 传递对象 9.3.1 按值来传递对象 9.3.2 利用指针来传递对象 9.3.3 利用cost指针来传递对象 9.3.4 利用引用来传递对象 9.3.5 到底是使用引用还是指针 9.3.6 引用和指针可以一块用 9.4 引用应注意的问题 9.4.1 引用容易犯的错误 9.4.2 引用一个按值返回的堆对象 9.4 -3引用一个按别名返回的堆对象 9.4.4 在哪里创建,就在哪里释放 9.5 总结 第10章 深入函数 10.1 函数重载 10.1.1 普通函数的重载 10.1.2 成员函数的重载 10.2 函数的默认参数 10.3 重载构造函数 10.3.1 成员变量的赋值与初始化 10.3.2 成员变量初始化与构造函数 10.3.3 复制构造函数 10.3.4 构造函数和new运算符 10.3.5 再谈默认构造函数 10.4.析构函数和delete运算符 10.4..1 默认析构函数 10.4.2 调用构造函数进行类型转换 10.5 浅层复制构造函数 10.6 深层复制构造函数 第11章 运算符重载 11.1 运算符重载 11.2 在成员函数实现自加 11.3 重载前置自加运算符 11.4 创建临时对象 11.5 创建无名临时对象 11.6 取消创建临时对象 11.7 重载后置自加运算符 11.8 重载加法运算符函数operator+ 11.9 重载赋值运算符函数operator 11.10转换类型运算符 11.10.1 温习调用构造函数实现的类型转换 11.10.2 通过构造函数将变量转换为一个对象的成员变量 11.10.3 通过operator关键字进行转换 11.11什么可以重载,什么不可以重载 第12章 继承 12.1 什么是继承和派生 12.1.1 复杂的继承和派生 12.1.2 继承和派生如何在C++实现 12.1.3 继承的种类及语法 12.1.4 单一继承 12.2 公有型、保护型和私有型 12.3 访问权限 12.4 多重继承 12.5 继承的构造与析构 12.6 合理利用基类构造函数 12.7 继承和重载的两义性问题 12.7.1 多重继承容易产生两义性 12.7.2 继承的重载 12.7.3 两义性的归属问题 12.7.4 减少两义性产生的混淆问题 12.7.5 虚基类不会产生两义性 12.8 总结 第13章 虚函数 13.1 指向子对象的父指针 13.2 虚函数 13.3 拳击游戏 13.4 继承是否可以实现多态性 13.5 在编译时的静态联编 13.6 在运行时的静态联编 13.7 在运行时的动态联编 13.8 在编译时的动态联编 13.9 调用虚函数 13.9.1 在虚函数调用成员函数 13.9.2 3种调用虚函数的方式比较 13.10被继承的虚函数仍然是虚函数 13.11系统是如何调用虚函数的 13.12在虚函数使用成员名限定 13.13虚析构函数 13.14总结 第14章 数组 14.1 数组的基本用法 14.1.1 什么是数组 14.1.2数组元素 14.1.3数组下标越界 14.1.4 倒序输出 14.1.5 将数组的下标定义为常量 14.1.6 手动操作数组元素 14.1.7 数组的初始化 14.2 数组的用途 14.2.1 求平均考试成绩 14.2.2 兔子繁殖问题 14.2.3 数字排序问题 14.3 数组在内存的分布 14.4.输出数组名 14.5 数组名与函数 14.6 传递与接收 14.7 数组与函数 14.7.1 函数传参实例一——求数组所有元素的和 14.7.2 函数传参实例二——用递增法查找数据 14.7.3 函数传参实例三——用二分算法查找数据 14.7.4 函数传参实例四——判断数组是否按照顺序排列 14.7.5 函数传参实例五——判断数组排列方式后执行不同的函数 14.8 数组在对象的传参 14.9 对象数组 14.10 在对象数组初始化成员变量 14.11 指针数组 14.12 枚举常量与数组 14.13 多维数组 14.14 多维数组的初始化 14.15 字符数组 14.16 重载数组下标操作符 14.17 总结 第15章 链表 15.1 声明链表结构 15.2 简单的图书链表 15.2.1 图书链表 15.2.2 类的链表 15.3 动态链表 15.3.1 动态链表的建立 15.3.2 解决输入字符造成死循环的问题 15.3.3 动态链表的显示 15.3.4 动态链表的删除 第16章 多态性 第17章 类的特殊成员 第2篇 高级篇 第19章 代码重用 第20篇 高级篇 第20章 友元类与嵌套类 第21章 流 第22章 命名空间 第23章 模板 第24章 异常和错误处理 第25章 补充知识 附录A ASCII码对照表 附录B C++的关键字 附录C C++常用头文件列表 附录D 运算符的优先级 后记
C++ 并发 C++11 C++17 I encountered the concept of multithreaded code while working at my first job after I left college. We were writing a data processing application that had to populate a database with incoming data records. There was a lot of data, but each record was independent and required a reasonable amount of processing before it could be inserted into the database. To take full advantage of the power of our 10-CPU UltraSPARC, we ran the code in multiple threads, each thread processing its own set of incoming records. We wrote the code in C++, using POSIX threads, and made a fair number of mistakes—multithreading was new to all of us—but we got there in the end. It was also while working on this project that I first became aware of the C++ Standards Committee and the freshly published C++ Standard. I have had a keen interest in multithreading and concurrency ever since. Where others saw it as difficult, complex, and a source of problems, I saw it as a powerful tool that could enable your code to take advantage of the available hardware to run faster. Later on I would learn how it could be used to improve the responsiveness and performance of applications even on single-core hardware, by using multiple threads to hide the latency of time-consuming operations such as I/O. I also learned how it worked at the OS level and how Intel CPUs handled task switching. Meanwhile, my interest in C++ brought me in contact with the ACCU and then the C++ Standards panel at BSI, as well as Boost. I followed the initial development of the Boost Thread Library with interest, and when it was abandoned by the original developer, I jumped at the chance to get involved. I have been the primary developer and maintainer of the Boost Thread Library ever since.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertS

常来“玩”啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值