源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2022-11-25 12:26 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:C++基础入门教程(七):一些比较特别的基础语法总结
这次又到了比较简单的内容了,介绍了一些基本的循环控制、关系表达式、逻辑控制等。 这里就简单抽一些稍微比较特别的内容来吹吹水,不,是来总结一下吧~ [b]一、i++和++i[/b] 不,我不是来解释i++和++i的区别的,只是书上提到一点,在使用for循环的时候,倒底i++和++i有没有区别呢? 答案是:几乎没有,随便你用哪一个。   但是,要稍微注意一下两种方式的内部处理方式: i++:先复制一个i的副本,然后将i加1,最后返回i的副本。 ++i:将i加1,然后返回i。   这么一说,大家都知道谁的效率更高,但对于现在的编译器而言,是会自动优化的(但不知道是不是所有编译器都这样)。 然后,C++是允许自定义操作符的行为的,也就是说,我们可以为自己的类定义++操作,这时候,复制类的副本,消耗明显就不能忽略不计了。 这个,就不多说了。 [b]二、逗号运算符[/b] 逗号运算符可以将多条语句放到一起,如:
[u]复制代码[/u] 代码如下:
    for (int i = 2, j = 10 * i; i < 999; i++) {         cout << j;         break;     }
int i = 2, j = 10 * i;就是逗号表达式了,那么,j的值是多少呢?没错,是20。 再来, 这样:
[u]复制代码[/u] 代码如下:
int num = 0; num = 10, 50;
注意,声明变量赋值的时候是不能使用逗号表达式的,这个自己在编译器编译一下就知道了~规则这东西,没必要死记~ 这里的num值是多少呢?没错,是10,因为赋值比逗号表达式优先级要高,所以先把10赋值给num,后面的50被舍弃了。 那么,这样呢:num = (10, 50);  结果是50,因为括号的优先级比赋值语句高,逗号表达式沾了光,所以最后是把50赋值给了num。   但是,如果有谁非特殊情况下用这样的赋值形式,那么,我保证不打死他。 [b]三、类型别名(typedef)[/b] 这又是新手的一个痛点,大部分初次接触Cocos2d-x的朋友,一定被这两条语句吓死过:
[u]复制代码[/u] 代码如下:
typedef void (Ref::*SEL_SCHEDULE)(float); #define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)
这看似神复杂的东西,倒底是什么?这其实就是我们使用schedule定时器功能时要用到的。 这里先放着。   我们先来看看最简单的typedef用法:
[u]复制代码[/u] 代码如下:
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去掉,就变成这样:
[u]复制代码[/u] 代码如下:
int IQ; char* mpointer;
没错,IQ和mpointer就像是一个变量名(在上面这段代码里它们就是变量名)。 结果就是,在声明变量之后,前面加上typedef,就然后这个变量成为了类型的别名。 很好理解吧?以后看到typedef很复杂的,就把typedef去掉,看看是声明的什么变量,那这个别名就是代表这样的变量了。   接下来,再回到那神复杂的两条语句:
[u]复制代码[/u] 代码如下:
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的:
[u]复制代码[/u] 代码如下:
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类型。   好了,我再解释下去的话,就越来越说不通了,就到这里吧~ [b]四、新的for循环(c++11)[/b] C++11新增一种for循环语法,可以很方便地遍历数组、vector以及array。 使用很简单,如下:
[u]复制代码[/u] 代码如下:
    int nums[3] = { 1, 2, 3 };     for (int num : nums) {     }
这样就能把nums的值以此赋值给num,从而遍历整个数组,不多说喇~ [b]五、cctype标准库[/b] 我问大家一个问题,给你一个字母A,要判断它是大写还小写,你怎么判断? (小若:你都说了是字母A了,当然是大写的啊!要判断吗?)   咳咳~!程序!我们是程序员,不能这么简单地去判断~!这样不严谨~! 我们应该这样:
[u]复制代码[/u] 代码如下:
char c = 'A'; if(c >= 'A' and c <= 'Z') {     // 嗯,是大写 }
一般人应该都会这么想吧?(小若:不,一般人都知道A是大写,不用判断) 其实这样不安全,万一字符编码不是ASCII呢?有可能答案就不一样了。 于是,我们应该这样写:
[u]复制代码[/u] 代码如下:
    char c = 'A';     if (isupper(c)) {         // 嗯,是大写         cout << "yes";     }
isupper是cctype库的函数,用来判断字母是否是大写。 这样就更方便和通用了,   cctype库在头文件ctype.h里(或者cctype里),关于这个库的更多函数,百度一下,会有很多~ [b]六、结束[/b] 好了,这次就到这里吧,C++果然不是我喜欢的东西,能吹水的地方比较少(都是比较严谨的东西),我还能坚持多久呢?~
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部