C/C++ 语言要注意的一些问题

本文探讨了C++编程中的关键概念和技术细节,包括volatile关键字的正确使用、malloc(0)的行为、typedef与#define的区别、无符号与有符号运算的特点、64位类型的应用、函数和全局变量的声明与定义、模拟面向对象编程、表达式的副作用、函数调用顺序的影响、整数运算的特性、内联函数的优缺点、参数设置的灵活性、可变参数的处理方式、以及运算符重载的限制。

1,关键字volatile

<!-- lang: cpp -->
   long square(volatile int x) 
   {   //int a=x;
    return a*a;
    }    在此输入代码

经过编译器优化后可能代码变为

<!-- lang: cpp -->
 long square(volatile int x) 
 {   int a=x;
     int b=x;
    return a*a;
  }

因为变量x可能被意想不到的改变,所以不一定得到x的平方值。 应该把代码变为

<!-- lang: cpp -->
 long square(volatile int x) 
 {   int a=x;
    return a*a;
  }

2,malloc(0)的返回值 malloc(0)返回堆上的任意一个字节的地址,并且返回的地址空间可以对其进行操作。


3,typedef和#define 定义数据类型的别名,哪个最好 最好用typedef,原因如下:

<!-- lang: cpp -->
typedef struct str * tpstr;
#define struct str * dpstr

当定义变量时,tpstr s1,s2;定义的都是指针变量。 而 dpstr s1,s2;相当于struct str * s1,s2; s1是指针变量,s2是结构变量,不是自己最初想要的。


4,无符号数和有符号运算,结果为无符号,无符号和有符号数最好不要混用!内存中的编码为补码!正数为它本身,负数为补码(反码加1).


5,64 位机上的 64 位类型是什么样的?

C99 标准定义了 long long 类型, 其长度可以保证至少 64 位, 这种类型在某些 编译器上实现已经颇有时日了。其它的编译器则实现了类似 longlong 的扩展。


6,怎样定义和声明函数和全局变量? 首先要理解定义和声明的概念,两者的区别是定义要分配存储空间,声明告诉编译器要使用 某个变量类型和名字。同一个变量只能定义一次(可以指定初值),但可以声明多次。 例如,int a ,声明的时候就建立了存储空间。这是定义性声明,就是定义。 而 extern int a ,只是声明变量a在别的文件中定义了,是一种引用声明,所以说声明包含着定义,定义是声明的特例。 函数的声明和定义比较简单,不加“{}”就是声明,加“{}”就是定义。 而通常函数、变量的声明和定义都是分开在不同文件,声明放在.h头文件中,而定义是包含头文件放在.c中。


7,C 如何模拟继承等面向对象的程序语言的方法? 由于可以定义函数指针,因此定义的结构体直接加入函数指针就可以实现简单的方法,结构体进行简单的嵌套,就可以实现简单的继承!


8,这样的代码能不能被执行:a[i]=i++; 不能执行,原因i++表达式有一个副作用,改变i的值,由于i在同一表达式被其他地方引用,导致无定义的结果,无法判断该值是旧值还是新值。


9,能否用括号来强制改变函数的调用顺序 例如 f1()+f2()*f3();尽管我们知道运算规则是先算乘法再算加法,但我们并不知道三个函数的调用顺序,如果想获得我们期望的结果,只有使用独立语句和明确的临时变量。


10,两个整数相除结果为整数,整数才可求余,余数的符号与左边数的符号相同。


11,C++中的内联函数,定义方法是:在函数定义时,在函数的类型前增加修饰词inline。 其实质
是用存储空间(把代码插入到函数调用处)来减少执行时间。 使用内联函数要注意的问题:


一、C++中,除在函数体内含有循环,switch分支和复杂嵌套的if语句外,所有的函数均可定义为内联函数。


二、内联函数也要定义在前,调用在后。形参与实参之间的关系与一般的函数相同。


三、对于用户指定的内联函数,编译器是否作为内联函数来处理由编译器自行决定。说明内联函数时,只是请求编译器当出现这种函数调用时,作为内联函数的扩展来实现,而不是命令编译器要这样去做。


四、正如前面所述,内联函数的实质是采用空间换取时间,即可加速程序的执行,当出现多次调用同一内联函数时,程序本身占用的空间将有所增加。如上例中,内联函数仅调用一次时,并不增加程序占用的存储间。


12,关于C++的参数


一、参数可以有缺省值,但不可以靠左边缺省。

<!-- lang: cpp -->
void f(int a,int b=20);

二、函数原型说明时参数可以没有变量名。

<!-- lang: cpp -->
void f(int,long b,int c=20);

三、只能在前面定义一次缺省值,即原型说明时定义了缺省值,后面函数的定义不可有缺省值。


四、关于可变参数,前面的介绍都是参数数目固定的参数,但是在某些时候,函数参数个数并不能确定,而在调用的时候才确定,针对这种情况,C++定义允许参数个数不固定的函数。


首先,要用到va_start()、va_arg()、 va_end()这三个库函数,必须包含头文件“stdarg.h”,。


其次,要说明一个va_list类型的变量,va_list与int,float类同,它是C++系统预定义的一个数据类型(非float),只有通过这种类型的变量才能从实际参数表中取出可变有参数。如定义下面函数:

<!-- lang: cpp -->
  void fun(int a,int b,...){ //其中"..."表示可变参数,而可变参数前面是确定的参数b
  va_list   ap;
  va_start(ap,b);           //初始化,从确定参数b开始取可变参数
  int temp=va_arg(ap,int);          //依次取参数,int为可变参数的数据类型名
  va_end(ap);             //完成收尾工作
 }

使用参数数目可变的函数时要注意以下几点:


一、在定义函数时,固定参数部分必须放在参数表的前面,可变参数在后面,并用省略  号“...”表示可变参数。在函数调用时,可以没有可变的参数。

二、必须使用函数va_start()来初始化可变参数,为取第一个可变的参数作好准备工作;使用函数va_arg()依次取各个可变的参数值;最后用函数va_end()做好结束工作,以便能正确地返回。

三、在调用参数个数可变的函数时,必定有一个参数指明可变参数的个数或总的实参个数。

13,C++运算符的重载,当用成员函数实现运算符的重载时,运算符重载函数的参数只能有二种情况:没有参数或带有一个参数。对于只有一个操作数的运算符(如++),在重载这种运算符时,通常不能有参数;而对于有二个操作数的运算符,只能带有一个参数。这参数可以是对象,对象的引用,或其它类型的参数。在C++中不允许重载有三个操作数的运算符。

转载于:https://my.oschina.net/u/221120/blog/138849

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值