呵呵,废话不多说,先看看到底是啥好玩的语言特性~~
1.

#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
int main(int argc,char* argv[])
{
    char a[20]=“world”;
    printf(“%c\n”,a[2]);
    printf(“%c\n”,2[a]);
    return 0;
}

对于这段代码,你觉得是否会编译通过,并且正确运行呢?

2.

#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
class Foo {
  public:
    static void bar() {
      std::cout << “I am bar()” << std::endl;
    }
};
 
int main(int argc,char* argv[])
{
    Foo * foo = NULL;
    foo->bar();
    return 0;
}

这段代码,你觉得输出的结果是啥呢?还是core掉?

===================我是华丽的分割线===================

在公司论坛上偶尔发现了这样几个好玩的东西,很遗憾的告诉大家,上面两个程序都可以编译通过并正确运行(windows下gcc 3.4.5)
先给大家贴一下运行结果吧
1.

qiguai2
2.

qiguai2

其实对于第一个小程序,可以简单的这样想:

a[2] == *(a+2) == *(2+a) == 2[a]

但是对于第二个程序的话,就实在想不通啦,需要去看一下C++内部的实现才行啦~

版权所有,转载请注明出处.http://www.vimer.cn

最近的一些技术整理(20120109)

前段时间一直没写博客,昨天更新了一篇,今天突然又来了兴致,那就再更新一篇吧(所以说啊,治疗拖延症最好的方法就是现在开始做) 这篇还是一些技术的整理,...

阅读全文

C++模板的几个应用

C++的模板其实是个挺纠结的东西,用的不好的话,编译的一堆错误够你调到崩溃,但要是用的好呢,又确实非常方便,我们来看看 一.获取数组长度 比如 ...

阅读全文

又见C++诡异问题

用C++越久,越是觉得C++太多陷阱,真是防不胜防。 我们看这样一段代码: C++ #include <stdio.h> using namespace std; ...

阅读全文

19则回应给“两个好玩的C/C++语言特性”

  1. bobby说道:

    第二应该是 static member function 没有this指针。其地址类型是一个“nomember的函数指针”。 上面的调用内部转换为 : bar( (Foo*)0 ); 在C++对象模型里面有讲。

    [回复]

    Dante 回复:

    多谢bobby指点~~~~ 发现我的每篇博客的疑问总有牛人能帮助解答,真希望这个博客能成为大家共同交流的地方~~呵呵~

    [回复]

  2. 依云说道:

    这个已经看过啦,原文好像是在 stackoverflow ,也有一些其他的博客转了部分。

    [回复]

    Dante 回复:

    是吗?我是在公司内部论坛看到的,觉得好玩就测试了一下~~~大家看着玩玩就行,本来就没啥实用价值……

    [回复]

  3. 王李李说道:

    其实bobby 说法欠妥,可以试试把那个static去掉,程序照样能运行。

    实质上:

    对于面向对象的语言来说 所谓的面向对象仅仅是语言层的封装,或者说是编译器的封装而已

    C++代码最终会编译成机器语言,而机器语言是”面向过程”的,不存在所谓的面向对象

    可以用面向过程的C语言代码来理解C++编译器
    上面那个C++函数声明会转为
    _Foo_bar_v_(Foo *this)
    {
    std::cout << "I am bar()" <bar(); 调用直接会被C++编译器转为 _Foo_bar_v_(Foo *foo); 这条语句
    注意上句的foo其实就是this指针了

    上面那个函数运行成功 主要在于你那个bar函数里面没有调用任何的成员变量 你可以试试往Foo添加一个成员变量(不是成员函数) 程序会core掉
    另外调用虚函数也会core 这和虚函数实现密切相关
    对象模型是C++学习里面比较偏门的hacker技术 我觉得即使理解了也对于用C++设计软件并没有太大的帮助(建议看看刘未鹏的博客 学习C++ 实践者的方法)
    对于C++设计架构大规模软件 我也是个菜鸟 也不太好多说了

    [回复]

    Dante 回复:

    哈哈,高手一个个冒出来啦~~
    我刚试了一下在bar函数里添加成员变量的调用,代码如下:
    class Foo {
    public:
    static int a;

    public:
    static void bar() {
    a=10;
    std::cout < < "I am bar()" << std::endl; } }; 代码是无法编译通过的: test2.cpp:(.text$_ZN3Foo3barEv[Foo::bar()]+0x8): undefined reference to `Foo::a' 但是去掉foo->bar();这行调用,就会编译正常。

    [回复]

    王李李 回复:

    test2.cpp:(.text$_ZN3Foo3barEv[Foo::bar()]+0×8): undefined reference to `Foo::a’
    主要是a是静态成员
    而静态成员需要在类外单独定义的
    static int Foo::a;
    博主忘了加这句话..

    另外 我的意思是a不是静态成员的情况下会core

    [回复]

    王李李 回复:

    另外说句 我用了两年多了vim 来看了博主的vim用法 才知道自己用vim有多菜 hoho~~ 所以订了你的博客 主要想向你学用vim

    [回复]

    Dante 回复:

    哈哈,我这边会尽量多的和大家分享VIM的使用啊~

    [回复]

  4. 王李李说道:

    格式有误,补发:

    可以用面向过程的C语言代码来理解C++编译器
    上面那个C++函数声明会转为
    _Foo_bar_v_(Foo *this)
    {
    std::cout << "I am bar()" <bar(); 调用直接会被C++编译器用 _Foo_bar_v_(Foo *foo); 代替
    注意上句的*foo其实就是this指针了

    [回复]

    小保哥 回复:

    static成员函数是没有this指针的

    [回复]

  5. GuoJing说道:

    有点意思,呵呵,虽然不经常弄C++

    [回复]

  6. GuoJing说道:

    不过要说的是,在项目开发中,这样写是非常危险的,其实最主要的是要整个team按照一个标准去写,否则可读性,可维护性马上降到最低。

    虽然我很少写c++,一般就是写算法用到,但是从任何语言上来说,一些特别奇怪的特性还是少用为好,要是我是老板的话我非得气死不可。。呵呵

    [回复]

    Dante 回复:

    哈哈,本来就是纯属消遣啦~~ 如果真在项目里写出这样的代码,那就完全是找抽啦~~

    [回复]

  7. huubby说道:

    第一个问题有点意思,第二个问题楼上各位已经讲的很清楚了

    [回复]

  8. egmkang说道:

    第一个问题其实有一点好玩的地方,就是C里面没数组.
    int a[10];
    我们通过下标访问a[1]元素,其本质就是*(a+1).
    所以1[a]也就是*(1+a),有区别么??
    没有.
    第二个没有Down掉,我认为是没有访问过this指针,否则就Down掉了.
    OO的最大特性是虚函数指针/虚函数表,其他的部分都可以成为OB(我自己这么叫~~).OB的部分在任何语言里面都能实现,无非就是this指针+函数.this指向的是数据,函数就是方法~~编译器在编译C++程序的时候,偷偷摸摸添加上去了this指针,我认为…..虽然我一直不知道他的参数怎么传递的

    [回复]

  9. egmkang说道:

    int * const a=NULL;
    a++;
    int b[10];
    b++;
    在VC下面看到的错误一样滴~~

    [回复]

    Dante 回复:

    呃,这个是因为这个指针是不可以改变值的吧

    [回复]

    egmkang 回复:

    恩,我认为那俩是一样的..
    b也是一个const 指针…..
    呵呵

    [回复]

发表评论