C/C++基础(二)
(1)运算符优先级 
 #include <cstdio>
 
 using namespace std;
int main()
 
 {
 
    unsigned char a = 0xA5;
 
    unsigned char b = ~a>>4+1;
 
    //cout<<"b= "<<b<<endl; 这样看不到结果
 
    printf("b=%d\n",b); //b=250
 
    return 0;
 
 }
 
 /*
 
 这道题目考察两个知识点: 一是类型转换问题;二是算符的优先级问题。
 
 对于第一个问题:unsigned char b = ~a>>4,在计算时,编译器会先把a和4的值转换为int类型(即所谓整数提升)后再进行计算,当计算结果出来后,再把结果转换车个unsigned char 赋值给b.
 
 对于第二个问题:因为
 "~"的优先级高于">>"和"+",过程是这样的:先对1010 0101 取反 0101 1010; 再右移,这里有一个问题,是先右移4位再加1呢,还是直接右移5位。因为
 "+"的优先级高于">>",所以是右移5位。结果是0000 0010。结果是2,但运算结果是250,why? 原因在于,
 进入汇编指令我们可以看到eax是16位的寄存器,于是在机器中0xA5的寄存中表达式是0000 0000 1010 0101, 取反是 1111 1111 0101 1010, 那么右移5位是 0000 0111 1111 1010,由于是unsigned char型的只能表示低8位的数值,即是250.
 
 */
(2)运算技巧
用一个表达式,判断一个数X是否是2的n次方(2,4,8,16...),不可用循环语句。
 
 2,4,6,8 这样的数转换成二进制是10 100 1000 10000。
 在c/c++基础(一)中我们讲过判断一个数转换成二进制后1的个数是通过x&(x-1)来判断的。这里用同样的方法:如果x&(x-1)为0,则满足,所以答案为!x&(x-1)
int fun(int x, int y)
 
 {
 
    return(x&y)+((x^y)>>1)
 
 }
 
 (729,271) = ?
 
 当然可以转换成二进制后一步步算,但是这肯定不是理想的做法。仔细观察发现,
 x&y是取相同的位与,这个的结果是x和y相同位的一半,x^y是取x和y的不同位,右移相当于除以2,所以功能是取两个数的平均值。(729+271)/2 = 500。
有两个变量a和b,不用"if","?:","switch"或其他判断语句,找出两个数中间比较大的。
 ((a+b)+abs(a-b))/2
如何将a,b的值进行交换,并且不使用任何中间变量?
 
 简而言之,用异或语句比较容易,不用担心超界的问题。
 
 如果采用:
 
 a = a+b;
 
 b = a-b;
 
 a = a-b;
 
 缺点是 a,b都是比较大的两个数时,a=a+b会超出界限。
 
 正确应采用
 
 
 a = a^b;
 b = a^b;
 a = a^b;
 无需担心超界的问题。按位异或运算符"^"是双目运算符,其功能是参与运算的两数个对应的二进制位相异或,当对应的二进制位相异时,结果为1.参与运算数仍旧以补码形式出现。
(3)C/C++比较常识
在c++程序中调用被C编译器编译后的函数,要加extern "C" why?
 
 一句话:
 c++提供了C连接交换指定符号 extern "C"解决名字匹配问题。
 
 详细的说:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为void foo(int x, int y).该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。
头文件中的ifdef/define/endif是干什么用的?
 
 防止该头文件被重复引用。
评价一下C与C++的各自特点,如果一个程序既需要大量运算,又要有一个好的用户界面,还需要与其他软件大量交流,应该怎样选择合适的语言?
 
 
 C是一种结构化语言,重点在于算法和数据结构。C程序的设计首先考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。而对于C++,首先考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可一通过获取对象的状态信息得到输出或实现过程(事务)控制。
 对于大规模数值运算,C/C++和Java/.NET 之间没有明显的性能差异。不过,如果运算涉及向量计算,矩阵运算,可以使用FORTRAN 或者 MATLAB 编写计算组件 (如COM)
 大规模用户界面相关的软件可以考虑使用.NET进行开发(Windows环境下),而且.NET同COM之间的互操作十分容易,同时,.NET对数据库访问的支持也相当好。
(4)宏定义
 
 用一个宏定义FIND求一个结构提struc里某个变量相对struc的偏移量。
 
 {int a; char b[20];} 则: FIND(student,a);//等于0  FIND(student,b); //等于4//
 int 4个字节 char 1个字节 float 4个字节 double 8个字节
 
 答案可以是: #define FIND(struc,e) (size_t)&(((struc*)0)->e)
 
 其中
 (struct*)0 表示将常量0强制转化成struc * 类型指针所指向的地址;
 
 
 &(((struc*)0)->e)表示取结构提指针(struc*)0 的成员e的地址,因为该结构体的首地址为0,所以其实就是得到了成员e距离结构体首地址的偏移量。(size_t)是一种数据类型,为了便于不同系统之间移植,最好定义为一种无符号数据类型,如unsigned int。
用预处理指令#define 声明一个常数,用以表明1年中右多少秒(忽略润年问题)。
 
 这道题目虽然看起来简单,但包含以下知识点,值得注意:
 
 1 #define 语法的基本知识(例如,不能以分号结束,括号的使用,等等。)
 
 2 要懂得预处理其将为你计算常数表达式的值,因此,写出你是如何计算一年中右多少秒而不是计算出实际的值,会更有意义。
 
 3
 意识到这个表达式将使一个16位机的整型数溢出,因此要用到长整型符号L,告诉编译器这个常熟是长整型数。
 如果在表达式中用到UL(表示无符号长整型),那么是最好的。
 
 #define SECONDS_PER_YEAR (60*60*24*365)UL
写一个“标准”宏 MIN,这个宏输入两个参数并返回较小的一个。
 
 这道题目考察一下内容:
 
 1 标识#define 在宏中应用的基本知识。这是很重要的,因为直到嵌入(inline)操作符变为表转C的一部分,宏都是方便地产生嵌入代码的唯一方法。对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
 
 2 三重条件操作符的知识,这个操作符存在C语言中的原因是它使得编译器能产生比if-then-else 更优化的代码,了解这个用法很重要
 
 3 懂得在宏中小心地把参数用括号括起来。
 
 #define MIN(A,B) ((A)<=(B)?(A):(B))
(5)const
 
 const有什么用途?请至少说明两种。
 (1) 可以定义const常量;
 (2) const 可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮型。
const 与 #define 相比有什么不同?
 C++语言可以用const 定义常量,也可以用#define 定义常量,但是前者比后者有更多的优点:
 (1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误。
 (2) 有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。在c++程序中只使用const 常量而不使用宏常量,即const常量完全取代宏常量。
有类如下:
 
 Class A_class
 
 {
 
   void f() const
 
   {
 
     ......
 
   }
 
 }
在C++程序中,类里面的数据成员加上mutable后,修饰为const的成员函数,就可以修改它里,代码如下:
 
 #include <iostream>
 
 #include <iomanip>
 
 using namespace std;
class C
 
 {
 
    public:
 
   
 C(int i):m_Count(i){} //m_Count赋值为i
 
    int incr() const
 
    {
 
      return ++m_Count;
 
    }
 
    int decr() const
 
    {
 
      return --m_Count;
 
    }
 
    private:
 
    int m_Count;
 
 }; //class定义结束有;
 
 int main()
 
 {
 
   C c1(0), c2(10);
 
   //cout<<c1.incr()<<endl;
 
   //cout<<c2.decr()<<endl;
 
   for(int tmp, i=0;i<10;i++)
 
   {
 
     tmp = c1.incr();
 
     cout<<setw(tmp)<<setfill('*')<<tmp<<endl;
 
     tmp = c2.decr();
 
     cout<<setw(tmp)<<setfill('*')<<tmp<<endl;
 
   }
 
   return 0;
 
 }
 
 /*如果去掉mutable 则显示如下
 
 jj@ubuntu:~/JJ$ g++ modifyconst.c -o modifyconst
 
 modifyconst.c: 在成员函数‘int C::incr() const’中:
 
 modifyconst.c:11:15: 错误: increment of member ‘C::m_Count’ in read-only object
 
 modifyconst.c: 在成员函数‘int C::decr() const’中:
 
 modifyconst.c:15:15: 错误: decrement of member ‘C::m_Count’ in read-only object
 
 正常情况下显示如下:
 
 1
 
 ********9
 
 *2
 
 *******8
 
 **3
 
 ******7
 
 ***4
 
 *****6
 
 ****5
 
 ****5
 
 *****6
 
 ***4
 
 ******7
 
 **3
 
 *******8
 
 *2
 
 ********9
 
 1
 
 ********10
 
 0
 
 */
在C++中,setw(int n)用来控制输出间隔。
 例如:
 cout<<'s'<<setw(8)<<'a'<<endl;
 则在屏幕显示
 s        a 
 //s与a之间有7个空格,setw()只对其后面紧跟的输出产生作用,如上例中,表示'a'共占8个位置,不足的用空格填充。若输入的内容超过setw()设置的长度,则按实际长度输出。
 setw()默认填充的内容为空格,可以setfill()配合使用设置其他字符填充。
 如
 cout<<setfill('*')<<setw(5)<<'a'<<endl;
 则输出:
 ****a //4个*和字符a共占5个位置。
C/C++基础(二)的更多相关文章
- Python全栈开发【基础二】
		Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ... 
- Bootstrap <基础二十九>面板(Panels)
		Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ... 
- Bootstrap <基础二十八>列表组
		列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ... 
- Bootstrap<基础二十七> 多媒体对象(Media Object)
		Bootstrap 中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用更少的 ... 
- Bootstrap <基础二十六>进度条
		Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ... 
- Bootstrap <基础二十五>警告(Alerts)
		警告(Alerts)以及 Bootstrap 所提供的用于警告的 class.警告(Alerts)向用户提供了一种定义消息样式的方式.它们为典型的用户操作提供了上下文信息反馈. 您可以为警告框添加一个 ... 
- Bootstrap<基础二十四> 缩略图
		Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ... 
- Bootstrap <基础二十三>页面标题(Page Header)
		页面标题(Page Header)是个不错的功能,它会在网页标题四周添加适当的间距.当一个网页中有多个标题且每个标题之间需要添加一定的间距时,页面标题这个功能就显得特别有用.如需使用页面标题(Page ... 
- Bootstrap <基础二十二>超大屏幕(Jumbotron)
		Bootstrap 支持的另一个特性,超大屏幕(Jumbotron).顾名思义该组件可以增加标题的大小,并为登陆页面内容添加更多的外边距(margin).使用超大屏幕(Jumbotron)的步骤如下: ... 
- Bootstrap <基础二十一>徽章(Badges)
		Bootstrap 徽章(Badges).徽章与标签相似,主要的区别在于徽章的边角更加圆滑. 徽章(Badges)主要用于突出显示新的或未读的项.如需使用徽章,只需要把 <span class= ... 
随机推荐
- HDU_1241 Oil Deposits(DFS深搜)
			Problem Description The GeoSurvComp geologic survey company is responsible for detecting underground ... 
- DOM对象与Jquery对象区别
- javascript ajax请求
			<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ... 
- 动画特效的原生、jQ和CSS3方法
			最近一直在看运动的JS特效,主要看的是原生写法,太麻烦了,最终看到写了个运动的方法,后面可以直接引用,然后发现这个方法和jQ其实差不多了,代码分别如下: 基本的HMTL和CSS <!DOCTYP ... 
- 策略模式(Strategy)
			行为型模式:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式 策略模式(Strategy) 策略模式定义了一系列算法,并将 ... 
- Hibernate 使用说明
			Eclipse中hibernate连接mySQL数据库练习(采用的是hibernate中XML配置方式连接数据库,以后在更新其他方式的连接) Hibernate就是Java后台数据库持久层的框架,也是 ... 
- Apache 多站点(虚拟主机)
			普遍 apache多站点(灰色(连接一起的红色)字体 为命令) 编辑文件:httpd.conf 找到以下内容: # Virtual hosts # Include /private/etc/apach ... 
- postgresql 的触发器
			今天编写了一个触发器 功能: 有两个表,当一个表的字段有所改动的时候,另一个表跟着改动 CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS T ... 
- 第一个deeplearning4jproject跑起
			deeplearning4j是基于java的深度学习库,当然,它有许多特点,但暂时还没学那么深入,所以就不做介绍了 需要学习dl4j,无从下手,就想着先看看官网的examples,于是,下载了exam ... 
- Coursera《machine learning》--(8)神经网络表述
			本笔记为Coursera在线课程<Machine Learning>中的神经网络章节的笔记. 八.神经网络:表述(Neural Networks: Representation) 本节主要 ... 
