c++位运算符
下面是C/C++位操作运算符列表,其中运算符优先级为从上到下递减,但<<,>>优先级相同。
操作符 | 功能 | 用法 |
~ | 位求反 | ~expr |
<< | 左移 | expr1 << expr2 |
>> | 右移 | expr1 >> expr2 |
& | 位与 | expr1 & expr2 |
^ | 位异或 | expr1 ^ expr2 |
| | 位或 | expr1 | expr2 |
sizeof c/c++中判断数据类型在栈调用中的长度符的关键字 判断字节数
Q1.如何判断程序是由c++编译程序还是c编译程序编译的。
c++编译时,编译器会自动定义预处理名字_cplusplus .
c编译时自动定义名字_STDC_ .
__cplusplus详解
2012-11-25 20:28:00| 分类: |举报|字号
Code:
#ifdef __cplusplusextern "C" { #endif ... #ifdef __cplusplus} #endif 解释:1.c++中定义了__cplusplus,C语言中没有该定义。即:识别是c代码还是c++代码。如下段代码:
#includeint main(int argc,char *argv[]){#ifdef __cplusplusprintf("This is a c ++ program!\n");#endif#ifndef __cplusplusprintf("This is a c program!");#endifreutrn 0;}
分别编译:gcc test.c
./a.out
g++ test.c
./a.out
看到程序输出内容你便知道了。
解释2.C语言和C++编译出来的函数不用,调用extern "C"会让c++编译器按照c的编译格式来编译。多用于c++库的头文件。
Q2.c++程序在调用被c编译器编译后的函数,为什么要加 extern "C"?
答:c++语言支持函数重载,C语言不支持函数重载,函数被C++编译后在库中的名字与C语言的不同。假设某函数原型为 void _foo(int x,int y).该函数被C编译器编译后在库中的名字为_foo,而C++编译器泽会产生_foo_int_int之类的名字。C++提供了C连接交换指定符extern "C"解决名字匹配问题。
Q3.#include <filename.h> #include "filename.h"的区别
<>,编译器会从标准库路径开始搜索filename.h
"",编译器会从工作路径开始搜索filename.h
Q4.main主函数执行完后,是否可能会在执行一段代码?给出说明。
答:若要加入一段在mian退出后执行的代码,可以使用atexit()函数注册一个函数:
#include <>void fn1(void),void fn2(void);void main(void){atexit(fn1);atexit(fn2);printf("......");}void fn1(){printf("f1\n");}void fn2(){printf("f2\n");}
Q5.
#define SQR(x) (x*x)main(){int a,b=3;a=SQR(b+2);printf("%d\n",a);return 0;}
输出A:25,B:11 答案B
宏定义展开时容易造成二义性问题。 展开式b+2*b+2,得11.
若#define SQR(x) ((x)*(x)),则得25.
Q6. 用预处理指令#define 声明一个常数,以表明一年中有多少秒(忽略闰年问题)。
答:#define SECONDS_PER_YEAR (365*24*60*60)UL
预处理器将为你计算常数表达式的值,不用计算。将使一个16位机的整数型溢出,因此用长整型符号L,告诉编译器这个常数市场整形。
Q7.写一个“标准”宏MAX,这个宏输入两个参数并返回较大值。
#define MAX(a,b) (a>=b)?a:b //Error
#define MAX(a,b) ((a)>=(b)?(a):(b)) //参数要小心的用括号括起来 三重条件操作符的优先级与“>=”?
Q8.#define与const区别。
c++中两者都可以定义常量,但是const更好。因为
a):const常量有数据类型。而宏常量没有数据类型,编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能出现意想不到的错误(边际效应)。
b):有些集成化调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在C++程序中只是用const常量而不使用宏常量,即const常量完全取代宏常量。
宏和内联函数。
内联函数和普通函数相比可以加快程序运行,将有关代码嵌入到调用处,而不是在调用处跳转。
与c时代的宏相比,inline更安全可靠。可是这个是以增加空间消耗为代价的。
inline一般只用于:1)一个函数不断被重复调用。2)函数只有简单的几行,且函数内不包含for,while,switch语句。一般小程序没必要用inline,若是一个工程项目,其中一个简单函数被多次调用,则考虑用inline。
c中宏很重要,c++中少多了。宏的第一规则是:绝不该用它,除非不得不这样做。几乎每个宏都代表了一个缺陷,因为它将在编译器看到程序的正文前重新摆布这些正文。
宏是在代码处不加任何验证的简单替换,而内联函数是将代码直接嵌入调用处,而减少了普通函数调用的资源消耗。
宏不是函数,只是在编译前(编译预处理阶段)将程序中有关字符串替换成宏体。
inline fac(float i){return i*i};//没有写返回值
printf("bb= %d",fact(8));//调用时就执行printf("bb= %d",8*8);
Q9.sizeof:
1 class A{}; //sizeof(A)---1(对于一个类而言,即便是一个空类,编译器仍要给他一个空间所以是1) 2 3 class B{ char a,b;};//sizeof(B)---2 4 5 void main() 6 7 { 8 9 B bb=new B(); //---210 11 struct C{};//----112 13 struct D{ int a,b};//814 15 char *p;//sizeof(p) 416 17 char pp[]="12345";//sizeof(pp) 618 19 char ppp[100]="12345";//sizeof(ppp) 10020 21 char q[]="a\n";//3,'\n'---122 23 }
Q10.求程序结果
#includeusing namespace std;class A1{public: int a; static int b;/*默认情况下,在class关键字定义的类中,第一个作用域限定词(public、private、projected)出现之前的成员变量或方法都是private的。而在用struct关键字定义的类中,第一个限定词出现之前的成员变量和方法都是public的。两个作用域限定词之间的成员变量和方法都是被前一个限定词限制的。如 public: int a; int b; private double d; 以上例子中,int b;相当于public int b;*/ A1();~A1();}class A2{ public:int a;float b;char c;double d;A2();~A2();}
sizeof(A1)值是4.因为static,静态变量是放在全局数据区的,而sizeof计算的是调用栈中分配的大小,是不会把全局数据区(程序数据段)中的计算在内的。
/**
在及由其派生出的与等程序语言中,static是控制变量的生命周期和连接方式(作用域,可见性)的保留字。与C族语言中的extern,auto,register这些保留字一样,也是一种存储类(此类非面向对象的类)。每个变量或函数都有一种以上存储类标志,若声明时没有标志存储类,编译器会根据上下文选择默认存储类。如在源文件中所有文件级变量用extern,函数体中auto。
存储类名 | 生命周期 | 作用域 |
---|---|---|
extern | 静态(程序结束后释放) | 外部(整个程序) |
static | 静态(程序结束后释放) | 内部(仅翻译单元,一般指单个源文件) |
auto,register | 函数调用(调用结束后释放) | 无 |
- 对于静态来说,针对某一源文件的以static声明的文件级变量与的作用域只限于文件内(只在文件内可见),也即“内部连接”,因而可以用来限定变量的;
- 对于静态来说,在函数内以static声明的虽然与自动局部变量的作用域相同(即作用域都只限于函数内),但存储空间是以静态分配而非默认的自动分配方式获取的,因而存储空间所在区域不同(一般来说,静态分配时存储空间于编译时在程序分配,一次分配全程有效;而自动分配时存储空间则是于上分配,只在调用时分配与释放),且两次调用间变量值始终保持一致;
- 对于静态来说,在C++中,在类的定义中以static声明的成员变量属于,也即在所有类实例中共享,与之相对的就是。
**/
sizeof(A2)值是4+4+1+8=17,为了照顾数据对齐,为24
/**
http://pppboy.blog.163.com/blog/static/30203796201082494026399/
其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
**/
sizeof(string)是4,解释:string的实现在不同库中有所不同,但都有以共同点,无论string有多少字符,sizeof()都是固定的,字符串所占的空间是从堆中动态分配的 ,与sizeof()(栈)无关。sizeof(string)=4可能是最典型的实现之一,不过也有sizeof()为12、32字节的库实现。 但是VC6.0测试后sizeof(string)=16.还是跟编译器有关
Q11.
#inlude#inlude class base{public: base(){cout<<"base-ctor"< ){cout<<"d::f(complex)"<
sizeof 结果是4 4
只要下面这三行有一行存在,输出就是4,因此virtual函数实际上是一个联合指针。 virtual void f(int) {cout<<"base::f(int)"<
Q12.
char var[10]
int test(char var[])
{return sizeof(var)}sizeof()值是4,var[]等价于*var,已经退化成指针了。
Q13.
class A{}; class A2{};classB:public A{};class C:public virtual A{};class D:public B{};class E:public A,public A1{};
sizeof()分别是1,1,4,1,1.即空类占空间1,但以继承和多重继承的空类1,虚继承涉及到虚表(虚指针),4.