突破编程_C++_面试(操作符)

面试题 1 :C++中的操作符优先级是如何规定的?

在C++中,操作符的优先级是由语言规范明确规定的。这些优先级决定了当表达式中同时存在多个操作符时,哪些操作符会首先被执行。操作符优先级规则确保了表达式的计算顺序是一致的,从而避免了歧义。
以下是C++中一些常见操作符的优先级,从高到低排列:
(1)后缀操作符
obj.memberobj->memberfunc()(函数调用)、++i--i(后缀递增和递减)。
(2)一元操作符
+i-i!i~i(一元加、减、逻辑非、按位非)、sizeof&i*i(取地址和解引用)、++i--i(前缀递增和递减)。
(3)乘法类操作符
*/%(乘法、除法和取模)。
(4)加法类操作符
+-(加法和减法)。
(5)移位操作符
<<>>(左移和右移)。
(6)关系操作符
<<=>>=(小于、小于等于、大于、大于等于)。
(7)相等操作符
==!=(等于和不等于)。
(8)按位与操作符( & )
(9)按位异或操作符( ^ )
(10)按位或操作符( | )
(11)逻辑与操作符( && )
(12)逻辑或操作符( || )
(13)条件操作符( ? : )
(14)赋值操作符
=+=-=*=/=%=<<=>>=&=^=|=(赋值、复合赋值)。
(15)逗号操作符( , )
需要注意的是,优先级高的操作符将先于优先级低的操作符执行。当表达式中存在相同优先级的操作符时,它们的执行顺序将按照结合性来确定,即从左到右(左结合)或从右到左(右结合)。大多数操作符都是左结合的,但赋值操作符 = 是从右到左结合的,这意味着 a = b = c; 会被解释为 a = (b = c);
此外,可以通过使用括号来显式地指定操作符的执行顺序,从而覆盖默认的优先级和结合性规则。例如, a + b * c 会先执行乘法 b * c ,然后再执行加法 a + (b * c) ,但 (a + b) * c 则会先执行加法 a + b ,然后再执行乘法。

面试题 2 :什么是左结合和右结合?哪些操作符是左结合的,哪些是右结合的?

左结合和右结合是描述操作符在表达式中如何结合的概念。当表达式中存在多个相同优先级的操作符时,它们的结合性决定了这些操作符如何分组执行。
左结合
左结合指的是操作符从左到右依次结合。当表达式中出现多个相同优先级的左结合操作符时,它们会按照从左到右的顺序分组。大多数操作符都是左结合的,包括加法 + 、减法 - 、乘法 * 、除法 / 、模运算 % 、位运算(如 &|^ )、逻辑运算(如 &&|| )以及赋值运算(如 =+=-= 等)。
右结合
右结合指的是操作符从右到左依次结合。这意味着当表达式中出现多个相同优先级的右结合操作符时,它们会按照从右到左的顺序分组。少数操作符是右结合的,包括赋值操作符 = 、复合赋值操作符(如 +=-=*= 等)以及条件(三元)操作符 ? :
操作符的左结合和右结合示例
左结合示例: a + b + c 。由于加法操作符 + 是左结合的,所以表达式会解释为 (a + b) + c
右结合示例: a = b = c 。由于赋值操作符 = 是右结合的,所以表达式会解释为 a = (b = c)
需要注意的是,操作符的结合性不会改变它们的优先级。结合性仅当多个相同优先级的操作符连续出现时才有意义。通过使用括号,可以显式地改变操作符的结合性,从而覆盖默认的规则。

面试题 3 : sizeof 操作符是如何工作的?它返回的是什么类型的值?

sizeof 是 C++ 中的一个一元操作符,用于获取其操作数的大小(以字节为单位)。这个操作符可以应用于多种类型的操作数,包括基本数据类型、数组、结构体、类、联合体等。
sizeof 操作符的工作方式如下:
基本数据类型:对于基本数据类型(如 intcharfloat 等), sizeof 返回该类型在特定平台或编译器上所占用的字节数。这个值通常是固定的,但可能会因编译器或平台的不同而有所差异。
数组
当应用于数组时, sizeof 返回整个数组所占用的字节数,这包括数组的所有元素。例如, sizeof(int[10]) 将返回 int 类型大小乘以10的结果。
指针
对于指针类型, sizeof 返回指针本身的大小,而不是指针所指向的数据的大小。在大多数现代平台上,指针的大小是固定的,通常是 4 字节( 32 位系统)或 8 字节( 64 位系统)。
结构体和类
对于结构体和类, sizeof 返回该类型实例所占用的字节数。这包括该类型中所有成员的大小,并可能受到内存对齐规则的影响。
联合体
对于联合体, sizeof 返回该类型中最大成员的大小。
注意不能对函数使用 sizeof 操作符。
sizeof操作符返回的是一个 size_t 类型的值,这是一个无符号整数类型,用于表示对象的大小。 size_t 类型在 头文件中定义,通常足以容纳任何数组的大小。
需要注意的是, sizeof 返回的是类型或对象在内存中占用的字节数,而不是类型或对象表示的值的大小。此外, sizeof 在编译时计算,因此它不会考虑运行时动态分配的内存。

面试题 4 : ::(作用域解析)操作符在类外部和类内部有何不同?

:: (作用域解析)操作符在 C++ 中用于指定一个名称所属的作用域。在类外部和类内部,它的使用方式有所不同,但基本的功能是相似的:标识特定作用域中的名称。
在类内部
在类的成员函数内部, :: 操作符通常用于指定全局作用域中的名称,以区分成员函数参数或成员变量与全局变量或函数。这是因为类的成员函数内部默认的作用域是类的作用域,所以需要使用 :: 来显式地引用全局作用域中的实体。
例如,假设有一个全局变量 x 和一个类 MyClass ,该类有一个成员变量 x 。在 MyClass 的成员函数中,如果需要访问全局变量 x ,就需要使用 ::x 来避免与成员变量 x 混淆。

#include 

int x = 10; // 全局变量

class MyClass 
{
public:
    int x = 5; // 成员变量

    void print() 
	{
        std::cout << "member variable x: " << x << std::endl;
        std::cout << "global variable x: " << ::x << std::endl; // 使用作用域解析操作符来引用全局变量
    }
};

int main() 
{
    MyClass obj;
    obj.print(); // 输出成员变量和全局变量的值
    return 0;
}

在类外部
在类外部,::操作符通常用于访问类的静态成员或指定类的作用域。静态成员是属于类本身的,而不是类的任何特定实例,因此可以在没有类实例的情况下通过类名来访问它们。
例如,如果我们有一个类 MyClass ,它有一个静态成员变量 staticVar ,可以使用 MyClass::staticVar 来访问这个静态成员。

class MyClass 
{
public:
    static int staticVar; // 静态成员变量
};

int MyClass::staticVar = 1; // 在类外部定义静态成员变量

int main() 
{
    std::cout << "value of staticVar: " << MyClass::staticVar << std::endl; // 使用作用域解析操作符来访问静态成员变量
    return 0;
}

此外, :: 操作符还可以用于指定命名空间中的名称,这在大型程序中管理代码和避免命名冲突时非常有用。
总的来说, :: 操作符在类内部和类外部的基本功能是相同的,即指定名称所属的作用域,但在类内部它更常用于区分全局作用域和类的作用域,而在类外部它则更多地用于访问静态成员和指定命名空间。

面试题 5 :成员函数操作符和非成员函数操作符之间有什么区别?

成员函数操作符和非成员函数操作符(也称为全局函数操作符或友元函数操作符)在C++中用于重载操作符,它们之间区别如下:
成员函数操作符
(1)定义在类内部:成员函数操作符是类的成员函数,因此它们定义在类的内部。
(2)隐式参数:成员函数操作符的第一个参数隐式地是类的实例( this 指针),因此不需要显式地作为参数列出。
(3)访问权限:成员函数操作符可以访问类的私有( private )和保护( protected )成员。
(4)调用方式:通过类的实例或对象来调用成员函数操作符。
(5)参数个数:成员函数操作符可以定义为一个接受任意数量参数的函数。
非成员函数操作符
(1)定义在类外部:非成员函数操作符不是类的成员,它们定义在类的外部。
(2)显式参数:非成员函数操作符需要显式地列出所有参数,包括要操作的类类型的参数。
(3)访问权限:非成员函数操作符不能访问类的私有成员,除非这些成员是通过类的公有( public )接口暴露出来的,或者操作符被声明为类的友元( friend )。
(4)调用方式:非成员函数操作符通常通过操作数来调用,就像内置的操作符一样。
(5)参数个数:非成员函数操作符通常被定义为接受两个参数,表示操作符的两个操作数。
如下为样例代码:

class MyClass 
{
public:
    // 成员函数操作符
    MyClass operator+(const MyClass& other) const 
	{
        // ... 实现加法操作
    }

    // 友元函数操作符
    friend MyClass operator-(const MyClass& lhs, const MyClass& rhs);
};

// 非成员函数操作符的实现
MyClass operator-(const MyClass& lhs, const MyClass& rhs)
{
    // ... 实现减法操作
}

int main() 
{
    MyClass a, b, c;

    // 使用成员函数操作符
    c = a + b;

    // 使用非成员函数操作符
    c = a - b;

    return 0;
}

在这个例子中,operator+ 是一个成员函数操作符,它可以通过 a + b 的方式调用,并且它可以访问 MyClass 的私有成员。而 operator- 是一个非成员函数操作符(同时也是一个友元函数),它通过 a - b 的方式调用,并且不能直接访问 MyClass 的私有成员,除非它被声明为友元。

你可能感兴趣的:(突破编程_C++_面试,面试,c++)