C++基础入门教程(七):一些比较特别的基础语法总结

这次又到了比较简单的内容了,介绍了一些基本的循环控制、关系表达式、逻辑控制等。
这里就简单抽一些稍微比较特别的内容来吹吹水,不,是来总结一下吧~

一、i++和++i

不,我不是来解释i++和++i的区别的,只是书上提到一点,在使用for循环的时候,倒底i++和++i有没有区别呢?
答案是:几乎没有,随便你用哪一个。
 
但是,要稍微注意一下两种方式的内部处理方式:

i++:先复制一个i的副本,然后将i加1,最后返回i的副本。
++i:将i加1,然后返回i。
 
这么一说,大家都知道谁的效率更高,但对于现在的编译器而言,是会自动优化的(但不知道是不是所有编译器都这样)。
然后,C++是允许自定义操作符的行为的,也就是说,我们可以为自己的类定义++操作,这时候,复制类的副本,消耗明显就不能忽略不计了。

这个,就不多说了。

二、逗号运算符

逗号运算符可以将多条语句放到一起,如:

代码如下:

for (int i = 2, j = 10 * i; i < 999; i++) {
        cout << j;
        break;
    }

int i = 2, j = 10 * i;就是逗号表达式了,那么,j的值是多少呢?没错,是20。
再来, 这样:

代码如下:

int num = 0;
num = 10, 50;

注意,声明变量赋值的时候是不能使用逗号表达式的,这个自己在编译器编译一下就知道了~规则这东西,没必要死记~
这里的num值是多少呢?没错,是10,因为赋值比逗号表达式优先级要高,所以先把10赋值给num,后面的50被舍弃了。
那么,这样呢:num = (10, 50);  结果是50,因为括号的优先级比赋值语句高,逗号表达式沾了光,所以最后是把50赋值给了num。
 
但是,如果有谁非特殊情况下用这样的赋值形式,那么,我保证不打死他。

三、类型别名(typedef)

这又是新手的一个痛点,大部分初次接触Cocos2d-x的朋友,一定被这两条语句吓死过:

代码如下:

typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)

这看似神复杂的东西,倒底是什么?这其实就是我们使用schedule定时器功能时要用到的。
这里先放着。
 
我们先来看看最简单的typedef用法:

代码如下:

typedef int IQ;
IQ mutouIQ = 250;
int normalIQ = 1;

所谓类型别名,就是给某个类型的名字取个外号,比如我们把使用IQ代替int,如上代码。
使用typedef int IQ,就代表把int取了个别名,叫做IQ,以后就可以用IQ来定义整数了。
粗俗地说,IQ就是int,int就是IQ,懂了吧~
 
再来看看这个:typedef char* mpointer;
那么,我们以后就可以使用mpointer来定义char类型的指针。
 
大家有没有发现什么?
如果把typedef去掉,就变成这样:

代码如下:

int IQ;
char* mpointer;

没错,IQ和mpointer就像是一个变量名(在上面这段代码里它们就是变量名)。
结果就是,在声明变量之后,前面加上typedef,就然后这个变量成为了类型的别名。
很好理解吧?以后看到typedef很复杂的,就把typedef去掉,看看是声明的什么变量,那这个别名就是代表这样的变量了。
 
接下来,再回到那神复杂的两条语句:

代码如下:

typedef void (Ref::*SEL_SCHEDULE)(float);
#define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)

先看第一条,很复杂,我们把typedef去掉,变成:void (Ref::*SEL_SCHEDULE)(float);
这是什么,其实我也解释不了,我C++很水的,但,这明显就是一个“函数变量”(暂时这么称呼它)。
一个返回值为void,参数为float的函数,并且限定其类为Ref,怎么样,很好理解吧。
 
把typedef放回去,这句代码就是把SEL_SCHEDULE定义为上述所说的那种函数。
接着看第二条代码,这是一个宏:
1.schedule_selector是宏的名称
2._SELECTOR是宏的参数
3.static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)简化为static_cast<SEL_SCHEDULE>(&_SELECTOR),这是强制类型转换,将传递进来的_SELECTOR转换为某种类型
4.转换为什么类型呢?没错,就是SEL_SCHEDULE类型,SEL_SCHEDULE是什么类型?刚刚已经解释过了,一个返回值为void,参数为float,其类为Ref的函数
 
最后,看看我们平时是怎么使用schedule_selector的:

代码如下:

this->schedule(schedule_selector(HelloWorld::update));

结果就是把我们的HelloWorld的update函数转换成了SEL_SCHEDULE类型,然后传递给schedule函数。
 
呼,这回明白了吧,最后看看我们的update函数是如何定义的:void update(float dt);
返回值为void,参数为float,HelloWorld类继承了Layer(最终也是继承了Ref的)。
update函数的类型和SEL_SCHEDULE的基本上一样,除了类的类型以外。
但因为Layer的最终基类是Ref,所以可以把update函数强制转换为SEL_SCHEDULE类型。
 
好了,我再解释下去的话,就越来越说不通了,就到这里吧~

四、新的for循环(c++11)

C++11新增一种for循环语法,可以很方便地遍历数组、vector以及array。
使用很简单,如下:

代码如下:

int nums[3] = { 1, 2, 3 };
    for (int num : nums) {
    }

这样就能把nums的值以此赋值给num,从而遍历整个数组,不多说喇~

五、cctype标准库

我问大家一个问题,给你一个字母A,要判断它是大写还小写,你怎么判断?
(小若:你都说了是字母A了,当然是大写的啊!要判断吗?)
 
咳咳~!程序!我们是程序员,不能这么简单地去判断~!这样不严谨~!
我们应该这样:

代码如下:

char c = 'A';
if(c >= 'A' and c <= 'Z') {
    // 嗯,是大写
}

一般人应该都会这么想吧?(小若:不,一般人都知道A是大写,不用判断)

其实这样不安全,万一字符编码不是ASCII呢?有可能答案就不一样了。
于是,我们应该这样写:

代码如下:

char c = 'A';
    if (isupper(c)) {
        // 嗯,是大写
        cout << "yes";
    }

isupper是cctype库的函数,用来判断字母是否是大写。
这样就更方便和通用了,
 
cctype库在头文件ctype.h里(或者cctype里),关于这个库的更多函数,百度一下,会有很多~

六、结束

好了,这次就到这里吧,C++果然不是我喜欢的东西,能吹水的地方比较少(都是比较严谨的东西),我还能坚持多久呢?~

(0)

相关推荐

  • 基于C++浮点数(float、double)类型数据比较与转换的详解

    浮点数在内存中的存储机制和整型数不同,其有舍入误差,在计算机中用近似表示任意某个实数.具体的说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学记数法.所以浮点数在运算过程中通常伴随着因为无法精确表示而进行的近似或舍入.但是这种设计的好处是可以在固定的长度上存储更大范围的数.1.将字符串转换为float.double过程存在精度损失,只是float.double各自损失的精度不相同而已std::string str="8.2&

  • C++实现strcmp字符串比较的深入探讨

    strcmp的实现函数简介原型:extern int strcmp(const char *s1,const char * s2); 用法:加头文件 #include <string.h> 功能:比较字符串s1和s2.一般形式:strcmp(字符串1,字符串2)返回值: 当s1<s2时,返回值<0 当s1=s2时,返回值=0 当s1>s2时,返回值>0 即:两个字符串自左向右逐个字符相比(按ASCII值大小相比较),直到出现不同的字符或遇'\0'为止.如:"A

  • 浅析C#与C++相关概念的比较

    1.在C#中,class的变量为引用类型,在C++中class的变量为值类型,如myclass mc,在C++中,mc是值类型,成员存储在程序的栈区,在C#中,mc是引用类型,指向堆中的成员. 2.switch语句,C#中case后面可根字符串,如case "abc",但在C++中却不行,C++中case后面只跟数字,字符,和枚举. 3.在C#中没有C++中的私有继承和保护继承,只有公有继承. 4.C#中可以通过关键字sealed把一个类声明为密封类,即不能被作为父类被继承出派出类,在

  • C++中十种内部排序算法的比较分析

    C++中十种内部排序算法的比较分析 #include<iostream> #include<ctime> #include<fstream> using namespace std; #define MAXSIZE 1000 //可排序表的最大长度 #define SORTNUM 10 //测试10中排序方法 #define max 100 //基数排序时数据的最大位数不超过百位: typedef struct node { int data3; int next; }

  • C/C++与Java各数据类型所占字节数的详细比较

    C/C++的数据类型: 一,整型 Turbo C:   [signed] int 2Byte//有符号数,-32768~32767   unsigned int 2Byte //无符号数,只能表示整数0~65535 [signed] short [int] 2Byte unsigned short [int] 2 Byte long [int] 4 Byte unsigned long [int] 4 Byte Visual C++ 6.0: [signed] int 4Byte   unsig

  • C语言字符串大小比较

    C语言字符串大小比较 #include <stdio.h> #include <string.h> int fun(char *a,char *b) { int i = 0,j = 0; while(a[i]&&b[j]) { if(a[i]-b[j]>0) return 1; else if(a[i]-b[j]<0) return -1; i++,j++; } if(strlen(a)==i&&strlen(b)==j) return

  • Bootstrap零基础入门教程(三)

    什么是 Bootstrap? Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的. 历史 Bootstrap 是由 Twitter 的 Mark Otto 和 Jacob Thornton 开发的.Bootstrap 是 2011 年八月在 GitHub 上发布的开源产品. 写到这里,这篇从零开始学Bootstrap(3)我想写以下几个内容: 1. 基于我对Bootstrap的理解,做一个小小的总结.

  • Bootstrap零基础入门教程(二)

    什么是 Bootstrap? Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的. 历史 Bootstrap 是由 Twitter 的 Mark Otto 和 Jacob Thornton 开发的.Bootstrap 是 2011 年八月在 GitHub 上发布的开源产品. 本文重点给大家介绍Bootstrap零基础入门教程(二),具体详情如下所示: 过程中会频繁查阅资料的网站: http://www.

  • Android 基础入门教程——开发环境搭建

    现在主流的Android开发环境有: Eclipse + ADT + SDK Android Studio + SDK IntelliJ IDEA + SDK 现在国内大部分开发人员还是使用的Eclipse,而谷歌宣布不再更新ADT后,并且官网也去掉了集成Android开发环境的Eclipse下载链接,各种现象都表示开发者最后都终将过渡到Android Studio,当然这段过渡时间会很长,但如果你是刚学Android的话建议直接冲Android Studio着手:而且很多优秀的开源项目都是基于

  • 一看就懂的ReactJs基础入门教程-精华版

    一.ReactJS简介 React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西很好用,就在2013年5月开源了.由于 React 的设计思想极其独特,属于革命性创新,性能出众,代码逻辑却非常简单.所以,越来越多的人开始关注和使用,认为它可能是将来 Web 开发的主流工具. ReactJS官网地址:http://facebook.github.io/re

  • MySQL基础入门教程之事务

    目录 引言 1.事务操作 1.1 未控制事务 1.2 控制事务一 1.3 控制事务二 2.事务的四大特性 3.并发事务问题 4.事务隔离级别 总结 引言 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败. 就比如: 张三给李四转账1000块钱,张三银行账户的钱减少1000,而李四银行账户的钱要增加1000. 这一组操作就必须在一个事务的范围内,要么都成功,要么都失败. 正常情况: 转账这个操作, 需

  • Leaflet 基础入门教程示例

    目录 什么是Webgis? 什么是Leaflet? 在Vue中安装Leaflet,与其他依赖 在App.vue中使用 初始化地图 chinaProvider地图瓦片 addControls使用工具集 attribution创建自定义版权 Marker创建点 创建线 Polygon创建三角形 Popup弹窗&Tooltip提示 Geojson区域描边 总结 什么是Webgis? webGis又称之为网络地理信息系统,GIS的全名是Geographic Information System,它是在计

  • Go语言七篇入门教程七GC垃圾回收三色标记

    目录 GC 如何判断一个对象是否可达 三色标记法 原理如下 GC GC全称Garbage Collection 目前主流的垃圾回收算法有两类,分别是追踪式垃圾回收算法(Tracing garbage collection)和引用计数法( Reference counting ). 而三色标记法是属于追踪式垃圾回收算法的一种. 追踪式算法的核心思想是判断一个对象是否可达,因为一旦这个对象不可达就可以立刻被 GC 回收了. 如何判断一个对象是否可达 分为两步: 第一步找出所有的全局变量和当前函数栈里

  • C++基础入门教程(一):基础知识大杂烩

    我很郁闷,这本书果然讲得很详细,我在看第二章,看完要深呼吸,实在太详(lao)细(dao)了. 不过这很好,后面难一些的内容应该会不错~   那么,这章只是作为预览的章节,我抽出一些稍微比较有营养的内容记录一下吧~   注意:本系列教程不适合无任何编程语言基础的朋友,只是作为C++基础的一种补充. 教程内容基于<C++ Primer Plus>一书,适合初学者,熟手请直接忽略. 1. 如果你不注释,那么,我会把你注释掉~! C++的注释有2种, 第一种,单行注释,那就是:// 如下代码: 复制

  • C++基础入门教程(七):一些比较特别的基础语法总结

    这次又到了比较简单的内容了,介绍了一些基本的循环控制.关系表达式.逻辑控制等. 这里就简单抽一些稍微比较特别的内容来吹吹水,不,是来总结一下吧~ 一.i++和++i 不,我不是来解释i++和++i的区别的,只是书上提到一点,在使用for循环的时候,倒底i++和++i有没有区别呢? 答案是:几乎没有,随便你用哪一个.   但是,要稍微注意一下两种方式的内部处理方式: i++:先复制一个i的副本,然后将i加1,最后返回i的副本. ++i:将i加1,然后返回i.   这么一说,大家都知道谁的效率更高,

  • C++基础入门教程(二):数据、变量、宏等

    哎,木了个头的,这书太详细了~看得累人 前面部分太过基础了,很多语法方法的东西我也不重复记录了~ 今天才看看C++涉及到数据的一些基础点吧,我把书中稍微比较有营养的部分抽离出来 1.初始化 一般情况下,我们声明和初始化变量是这样的:int iNum = 10; 其实这是延续了C语言的语法,C++还有一种语法,是这样的:int iNum(10); 其实大部分人还是习惯用第一种吧(我也是),但如果哪天我们在别人的代码里看到第二种形式,不要被吓蒙了~ 2.宏定义 宏,用最粗俗,不,是最通俗的说法来解释

随机推荐