面试题(1)基础知识
时间:2010-12-14 来源:yiweis
=,&,&&,|,&&,?:,++,--
C++操作符的优先级 |
|||
操作符及其结合性 |
功能 |
用法 |
|
L L L |
:: :: :: |
全局作用域 类作用域 名字空间作用域 |
::name class::name namespace::name |
L L L L L |
. -> [] () () |
成员选择 成员选择 下标 函数调用 类型构造 |
object.member pointer->member variable[expr] name(expr_list) type(expr_list) |
R R R R R |
++ -- typeid typeid 显示强制类型转换 |
后自增操作 后自减操作 类型ID 运行时类型ID 类型转换 |
lvalue++ lvalue-- typeid(type) typeid(expr) cast_name<type>(expr) |
R R R R R R R R R R R R R R |
sizeof sizeof ++ -- ~ ! - + * & () new delete delete[] |
对象的大小 类型的大小 前自增操作 (先+后用) 前自减操作 (先用后+) 位求反 逻辑非 一元负号 一元正号 解引用 取地址 类型转换 创建对象 释放对象 释放数组 |
sizeof expr sizeof(type) ++lvalue --lvalue ~expr !expr -expr +expr *expr &expr (type)expr new type delete expr delete []expr |
L L |
->* .* |
指向成员操作的指针 指向成员操作的指针 |
ptr->*ptr_to_member obj.*ptr_to_member |
L L L |
* / % |
乘法 除法 求模(求余) |
expr * expr expr / expr expr % expr |
L L |
+ - |
加法 减法 |
expr + expr expr - expr |
L L |
<< >> |
位左移 位右移 |
expr << expr expr >> expr |
L L L L |
< <= > >= |
小于 小于或等于 大于 大于或等于 |
expr < expr expr <= expr expr > expr expr >= expr |
L R |
== != |
相等 不等 |
Expr == expr Expr != expr |
R | & | 位与 | Expr & expr |
R | ^ | 位异或 | Expr ^ expr |
R | | | 位或 | Expr | expr |
R | && | 逻辑与 | Expr && expr |
R | || | 逻辑或 | Expr || expr |
R | ?: | 条件操作 | Expr ? expr : expr |
R R R R R |
= *=,/=,%= +=,-= <<=,>>= &=,|=,^= |
赋值操作 符合赋值操作 |
Lvalue= expr Lvalue+= expr …… |
R | throw | 抛出异常 | Throw expr |
L | , | 逗号 | Expr, expr |
问题:如何记住运算符的15种优先级和结合性?
解答:C语言中运算符种类比较繁多,优先级有15种,结合性有两种。
如何记忆两种结合性和15种优先级?下面讲述一种记忆方法。
结合性有两种,一种是自左至右,另一种是自右至左,大部分运算符的结合性是自左至右,只有单目运算符、三目运算符的赋值运算符的结合性自右至左。
优先级有15种。记忆方法如下:
记住一个最高的:构造类型的元素或成员以及小括号。
记住一个最低的:逗号运算符。
剩余的是一、二、三、赋值。
意思是单目、双目、三目和赋值运算符。
在诸多运算符中,又分为:
算术、关系、逻辑。
两种位操作运算符中,移位运算符在算术运算符后边,逻辑位运算符在逻辑运算符的前面。再细分如下:
算术运算符分 *,/,%高于+,-。
关系运算符中,》,》=,《,〈=高于==,!=。
逻辑运算符中,除了逻辑求反(!)是单目外,逻辑与(&&)高于逻辑或(||)。
逻辑位运算符中,除了逻辑按位求反(~)外,按位与(&)高于按位半加(^),高于按位或(|)。
这样就将15种优先级都记住了,再将记忆方法总结如下:
去掉一个最高的,去掉一个最低的,剩下的是一、二、三、赋值。双目运算符中,顺序为算术、关系和逻辑,移位和逻辑位插入其中。 2 类型转换
C++语言编译系统提供的内部数据的自动隐式转换规如下
- 程序在执行算术运算时,低类型自动隐式转换为高类型,在赋值表达式中,右边表达式的值自动抓换为左边变量的类型,并赋值给左边变量。
- 在函数调用时,将实参赋值给形参,系统隐式地将实参转化为形参的类型,并赋值给形参。
- 函数有返回值时,系统自动地给返回表达式类型转换为函数类型,并赋值给调用函数。
- 当程序中发现两个数据类型不相容时,又不能自动问成隐式转换,则出现编译错误。
2 #include<stdio.h>
3 char getChar(int x,int y)
4 {
5 char c;
6 unsigned int a=x;
7 //unsigned int res =a+y;
8 (a+y>10)?(c=1):(c=2);//y转化为unsigned 类型
9 //printf("res=%u,x=%u,y=%u\n",res,x,y);
10 return c;
11 }
12 int main(void)
13 {
14 char c1=getChar(7,4);
15 char c2=getChar(7,3);
16 char c3=getChar(7,-7);//-7转化为4294967289,与7相加后正好溢出 结果为0 返回2
17 char c4=getChar(7,-8);//-7转化为4294967288,与7相加后正好溢出 结果为4294967295 返回1
18 printf("c1=%d\nc2=%d\nc3=%d\nc4=%d\n",c1,c2,c3,c4);
19 }
3数值交换

#include<stdio.h>
//使用了中间变量
void swap1(int & a,int & b)
{
int temp =a;//使用局部变量完成交换
a=b;
b=temp;
}
//利用加减运算完成交换
//可能产生溢出
void swap2(int & a,int &b)
{
a=a+b;
b=a-b;
a=a-b;
}
//利用异或运算完成交换
void swap3(int & a,int & b)
{
a^=b;
b^=a;
a^=b;
}
int main()
{
int a1=1,b1=2,a2=3,b2=4,a3=5,b3=6,a=2147483647,b=1;
swap1(a1,b1);
swap2(a2,b2);
swap3(a3,b3);
printf("after swap......\n");
printf("a1=%d,b1=%d\na2=%d,b2=%d\na3=%d,b3=%d\n",a1,b1,a2,b2,a3,b3);
swap2(a,b);
printf("a=%d,b=%d\n",a,b);
}
4头文件
#define _INCvxWorksh
#ifdef _cplusplus //表示使用的是C++编译器,如果要表示当前使用的是C编译器 用#ifdef _STDC_
extern "C"{
/************/
#ifdef _cplusplus
}
/*
"extern "C""的作用
1 被它修饰的目标是“extern"的。也就是告诉编译器,其声明的函数和变量可以在本模块或其他模块使用。
通常在模块的头文件中对本模块提供给其他模块引用的函数和全局变量用关键词extern声明。
如果模块B打算引用此模块A中定义的全局变量或函数,只需要模块A的头文件即可。
这样模块B调用模块A的函数时,在编译阶段,模块B即使找不到该函数,编译器也不回报错,
它会在连接阶段从模块A编译生成的目标代码中找到。
2 被它修饰的目标是“C“的,也就是说其修饰的变量和函数是按照C语言方式编译和连接的。用来解决名字匹配的问题
*/
#endif
#endif //_INCvxWorksh
//<xxxx.h>与"xxxx.h"的区别
/*
<>表示括号中的文件十一工程或标准头文件。查找过程会首先检查预定义的目录,开发者可以通过设置搜索路径环境变量或命令行选项来修改这些目录。
如果文件名用一对引号括起来则表明该文件是用户提供的头文件,查找该文件时将从当前文件目录或文件名指定的其他目录寻找,然后再在标准位置寻找。
*/
5 main函数之后的调用
#include<stdio.h>
void my_exit1(void);
void my_exit2(void);
int main()
{
atexit(my_exit1);
atexit(my_exit2);
printf("main exit..........\n");
/*进程有8种终止方式
1.从mian()返回,
2.exit,
3._exit,_Exit,
4.最后一个线程从启动例程返回
5.最后一个线程调用pthread_exit
6.调用abort
7.收到信号并终止
8.最后一个线程对取消请求做出响应*/
//return 0;//将调用atexit.处理程序的执行顺序与注册顺序相反。
_Exit(0);//不掉用atexit.
}
void my_exit1(void)
{
printf("calling my_exit1().....\n");
}
void my_exit2(void)
{
printf("calling my_exit2().....\n");
}
相关阅读 更多 +