zoukankan      html  css  js  c++  java
  • C++程序设计基础(2)变量

    注:读《程序员面试笔记》笔记总结

    1.知识点

    (1)C++变量命名只能包含字母、数字、下划线,其中开头不能是数字;大小写敏感;习惯上变量用小写字母,常量、宏定义用大写字母。

    (2)变量的作用域分为局部变量(函数内部定义),全局变量(函数外部定义)。

    (3)关键字extern:在头文件总声明变量,并在前面加上extern,在源文件中定义变量,其他文件使用#include导入头文件,即可使用该变量。附详细链接https://blog.csdn.net/chenqiai0/article/details/8490665

     1 //test.h
     2 extern int age;
     3 //test.cpp
     4 #include"test.h"
     5 int age = 10;  //直接使用age=10是不行的
     6 //test1.cpp
     7 #include"test.h"
     8 int main(int argc, char *argv[]) {
     9     cout << age << endl;
    10     getchar();
    11     return 0;
    12 }
    13 
    14 /*output
    15 10
    16 */

    (4)关键字static:静态变量,首次执行时初始化,其后再执行将不再进行初始化,虽然可能是局部变量,但其生命周期是整个程序运行过程。

    (5)关键字const:常量型变量,在头文件中直接定义和声明(不同于一般全局变量),其他文件通过#include使用(多个文件引用不会造成重复定义),如果在源文件中定义,则其作用域值是本源文件。

    2.面试题

    2.1简述i++和++i的区别

    写出下面代码执行后i,j,m,n的值

    1 int i=10,j=10;
    2 int m=(i++)+(i++)+(i++);
    3 int n=(++j)+(++j)+(++j);

    知识点:++i是先自身加一,然后再参与赋值运算,i++是先参与赋值运算,然后再自身加一。

    本题的特殊之处是不同的编译器会产生不同的结果,在VC编译器中,全部会先完成三个++j,然后再做加法运算,而在gcc编译器中当有两个操作数时就会进行加法运算。故结果如下:

    1 #VC编译器
    2 i=13,j=13,m=30,n=39//13+13+13=39
    3 #gcc编译器
    4 i=13,j=13,m30,n=37;    //12+12+13=37

    2.2简述C++的类型转换操作符

    在C语言中类型转换只需要通过变量前面加上变量类型,并且转换是双向的,这种方式对于简单类型可以,复杂数据类型就力不从心了。

    C++提供了四种类型转换操作符:static_cast,dynamic_cast,const_cast,reinterpret_cast。

    (1)static_cast可以完全替代C风格类型转换实现基本类型转换;

    1 int i = 1;
    2 double d = 1.5;
    3 int d2i = static_cast<int>(d);
    4 double i2d = static_cast<double>(i);

    同时相关类(如父子关系)可以完成转换,但是如果父类指针本身指向父类对象,不存在安全问题,如果父类指针本身指向子类对象,则不存在安全问题;

    1 class Base {};
    2 class Derived:public Base{};
    3 Base *b1 = new Base;    //父类指针指向父类对象
    4 Base *b2 = new Derived;     //父类指针指向子类对象
    5 Derived *b2d1 = static_cast<Derived *>(b1);    //转换成功(不安全)
    6 Derived *b2d2 = static_cast<Derived *>(b2); //转换成功(安全)

    (2)dynamic_cast:只能进行对象指针之间的转;转换结果可以使指针也可以是引用;转换时会进行类型检查(static_cast不会进行检查);只有当父类指针指向一个子类对象,并且父类中包含了虚函数,转换才会成功,否则返回空指针,引用的话抛出异常。

     1 class Base { virtual void dummy() {}; };
     2 class Drived : public Base{};
     3 Base *b1 = new Base;
     4 Base *b2 = new Drived;//父类指针指向子类对象,且父类中包含虚函数
     5 //转换结果为指针
     6 Drived *b2d1 = dynamic_cast<Drived*>(b1);//转换失败(返回NULL)
     7 Drived *b2d2 = dynamic_cast<Drived*>(b2);//转换成功
     8 //转换结果为引用
     9 Drived &b2d3 = dynamic_cast<Drived &>(*b1);//转换失败(抛出异常)
    10 Drived &b2d4 = dynamic_cast<Drived &>(*b2);//转换成功

    (3)const_cast:可以在转换过程中增加或删除const属性。一般情况下,无法将常量指针直接赋值给普通指针,但通过const_cast可以移除常量指针的const属性,从而实现const指针到非const指针的转换。

    1 class Test{};
    2 const Test *t1 = new Test;
    3 Test *t2 = const_cast<Test *>(t1);

    (4)reinterpret_cast:可以将一种类型的指针直接转换成另一种类型的指针,无论两个类型之间是否有继承关系。此外还可以吧一个指针转换为一个整数,也可以把一个整数转换成一个指针。另外还经常用在不同函数指针之间的转换。

    1 class A{};
    2 class B{};
    3 A *a = new A;
    4 B *b = reinterpret_cast<B *>(a);    //转换成功

    2.3简述静态全局变量的概念

    (1)在全局变量前面加上static关键字就成为的静态全局变量。

    (2)静态全局变量通常在源文件中声明定义,作用域为本文件,(而全局变量一般头文件声明,源文件定义,通过extern关键字,其作用域为整个工程。)

    (3)如果在头文件中声明了静态全局变量,那么即使在没有初始化的情况下,也会被初始化为默认值,即相当于也被定义了,这时其他文件#include该头文件,相当于拷贝了一份,其初始值相同,后面各个文件中将互相不影响。

    下面是静态全局变量的一个例子:

     1 static int sgn;//声明定义静态全局变量
     2 void increaseSG() { sgn++; }
     3 int main(){
     4     sgn = 10;
     5     cout << sgn << endl;
     6     increaseSG();
     7     cout << sgn << endl;
     8         getchar();
     9         return 0;
    10 }
  • 相关阅读:
    js 删除字符串中所有空格
    jquery easyui datagrid 设置设置在选中的所有行中只选择第一行
    编译Linux内核时出现错误gcc: error: elf_i386: No such file or directory
    AD9打印丝印层
    s3c2410 board.c分析
    2010.03 u-boot--Makefile完全分析
    mini6410移植--uboot移植(2)
    mini6410移植--uboot移植(1)
    uboot之uboot.lds文件分析
    Linux启动过程
  • 原文地址:https://www.cnblogs.com/ys99/p/9166559.html
Copyright © 2011-2022 走看看