随笔-145  评论-173  文章-70  trackbacks-0

 

    题记:一直以来都被一些细节忽略了,然后,遇到很多的问题就杯具了……从现在开始,觉得很有必要从小事做起,认真的来看看曾经犯过的错误,做过的事情。特别是对于曾经以为很习以为常的事情,要特别的重视,于是便有了tips,下面不断的更新中…………

题外话:(如何在Office 2007中创建并发布博文?)今天发现可以在Word 2007中编辑博客,然后直接点击发布,就可以发布到C++博客网上了,很贴心的服务,不是吗?其实这个也是Office的一个功能,在新建中,点击新建博客文章,就可以创建一个新的blog,然后会提示你创建一个账户,估计这个是最关键的,需要选择其他运营商,然后下一步,会有个API让你选择,选择下面的按个MetaWebLog,然后输出你的账号密码,这里的昂URL,不是你的主页的,开始的时候我也是选择这个,错误,连接不上。需要的是:在你的主页上,点击管理,然后点击选项,下面有个configure选项,进入后,最下面就有一个你的那个URL了,添加进去,OK!然后就可以发布了!

 

下面开始正式的tips:

  1. int到底占用多少个字节?

    一直以来都被这个问题纠结,因为上过汇编和C的课,然后又看了《C++ Primer》一书,总是会出现各种的不一致,如果按照平时我们的认为,都是4个Byte(字节),可是无奈很多书上讲解不一致,所以造成了迷惑……今天找时间上网搜了下,发现答案很多,不过大致上都是一个解答,于是我也就凭借自己的思考,来说说了。

    答:首先摘录网上的朋友们的留言:

int的字节长度是由CPU和操作系统编译器共同决定的,一般情况下,主要是由操作系统决定,比如,你在64位AMD的机器上安装的是32位操作系统,那么,int默认是32位的;如果是64位操作系统,64位操作系统分为两种,1种是int为32位long为64位,2种int long均为64位。之所以说int同时也与编译器有关,编译器完全可以在32位系统模拟64位整数,例如Unix/Linux下的long long和Windows下的__int64均为64位整数。

 

机器第一作用,编译器第二作用.
现在新出的机器开始有64位的,编译器也逐渐的要适应这个改变,由32位向64位过渡.
如果机器是16位的,编译器强制为32位的话,效率及其低下,没那家厂商会做如此SB的事情,
我们现在的机器一般都是32位的,编译器所以一般也是32位,但也支持64位的,
__int64  就是64字节的,
总之int 只是一个类型,没有太大的意义,机器的位数才是关键所在!
离开机器,说有编译器决定的人,实在不敢恭维.
难道要在8位机上实现64bit的编译器?
机器进步了,编译器跟不上,就要被淘汰,
编译器超前了,效率低下,也不会有市场,
所以不要单纯的讨论编译器或者机器了。
OVER!

 


int仅是语言标准中的一项定义,定义了这类数据的性质、范围、操作等;
具体少长,标准并未硬性规定,而由编译器自行决定,甚至编译器也可由用户根据需要自行设定。
基于此,可认为还是受编译器决定,所谓县官不如现管。

 

综合上面的说法,我也觉得对于int到底占用多少个字节,其实是和机器以及编译器都有关系。这么来说吧,我觉得机器起决定性作用,如果是32位机,那么在这个平台上面运行的编译器,可以使32位版本的,也可以是16位版本的(向下兼容,只不过浪费了好机子,没有充分发挥效果),这也就是说我们在网上下载驱动的时候,有时候会发现官网上面有32位操作系统Windows版本和64位操作系统Windows的不同分类了。而决定这个位数的,就是你的CPU,也就是机器。

但是,编译器没有必要一定要这么做,对于TC 2.0这样的16位软件,曾经在Dos下呼风唤雨,但是到了32位机下,仍然是可以用的,这样的话,也就是说,它运算的结果是2个字节,可是因为软件的限制,只能够模拟出来16位机,所以虽然可以在32位上面跑,但是不能反映实际的字长。但是,没有多少人会在32位机子上面模拟出128位或者64位,因为这样寻址的话效率很低下,硬件条件没有达到,利用软件来模拟是不够的。于是,就是上面的那种说法。由于VC以及其他软件更新很快,而且及时开发了Win 32下的版本,所以是32位软件,也就是说,它计算处理的int是4个字节。

当然,我们需要知道的是,标准并没有规定int一定要是多少个字节,而只是规定了一个范围,只要你不越轨,那么肯定就没有问题,至于实现,那是你编译器的开发的事情,跟我无关。同样,CPU和机器的制造者,关心的是如何提高计算机的性能,让寻址方式更大,范围更长,也就是位数越多,(这也是为何目前的那些机器都朝着64位或者更高位发展的目的),而软件开发者,面临的则是需要来适应硬件的更新,从而做出更好的软件,充分利用到这个性能。

当然,这个问题本身没有多少讨论的价值,不过,如果在面试或者考试中,遇到sizeof的操作,最好问清楚是在32位机子下还是16位或者是64位,这个能够反映你的严谨和认真。

注: 32位下:1int = 4 Byte            16位下:1 int = 2B        (当然,一般都不会考虑那个TC 2.0的)

 

 

 

 

 

2).普通类的继承中,如果派生类中的函数和基类函数同名时,是否会覆盖原来的那个函数?

    在java中,很明显是会覆盖的,因为继承的特性,注意同名函数,要求还有原型相同,否则的话,调用的时候是可以区分开来的,而当原型相同的时候,那么派生类会继承基类的函数,同时由于有一个自己的函数,所以两个同名,同原型的函数,是会发生覆盖的。

上代码看之:

#include <iostream>

using namespace std;

class A

{

    public:

        void moveto(){cout << "1" << endl;}

};

class B:public A

{

    public:

        void moveto(){cout << "2" << endl;}

};

int main()

{

    A a;

    B b;

    A *pstra = &b;

    B *pstrb = (B *)&a;

    pstra->moveto();

    pstrb->moveto();

    a.moveto();

    b.A::moveto();

    return 0;

}

输出的结果是:

        

从上面的结果可以看到,派生类的指针是调用派生类的对应的函数,配套的,而且还选择作用域较小的,而这样的优先级就要高些。这里有一个强制类型转换,因为是要将派生类的指针指向基类的对象,会发生截断,所以一定要强制类型转换,与此对比的是,基类的指针指向派生类的话不需要强制类型转换也可以实现。从结果可以看到,如果实行了转换,那么还是声明时候的类型,所以抓住了这点,声明时是B类型的,那么就调用B的moveto,所以输出时2,下面的另外一些的输出,就都是1了,也可以看到,如果要显示的调用被隐藏的基类,需要用作用域限定符来指示。

 

 2.隐藏的this指针不是实际的一个参数,也就是说,实际调用函数中,不能够使用这个参数。
上代码:

#include <string.h>
#include 
<iostream>
using namespace  std;

class STRING{
    
char *str;
public:
    STRING(
char *s=0);
    STRING(
const STRING &);
    
virtual int strlen(voidconst;
    
virtual int strcmp(const STRING &const;
    
virtual STRING &operator+(const STRING &);
    
virtual STRING &operator=(const STRING &);
    
virtual STRING &operator+=(const STRING &);
    
virtual operator const char *(voidconst;
    
virtual ~STRING();
}
;

STRING::STRING(
char *s/*=0*/){
    str 
= new char[::strlen(s)+1];
    ::strcpy(str,s);
}

STRING::
~STRING(){
    delete str;
}

int STRING::strlen(voidconst{
    
return ::strlen(this->str)+5//采用字符串的通用表示,不含null
}

int STRING::strcmp(const STRING &b) const{
    
return ::strcmp(this->str,b.str);
}

STRING 
&STRING::operator+(const STRING &b){
    ::strcat(
this->str,b.str);
    
return *this;
}

STRING 
&STRING::operator=(const STRING &b){
    
this->str = b.str;
    
return *this;
}

STRING 
&STRING::operator+=(const STRING &b){
    ::strcat(
this->str,b.str);
    
return *this;
}

STRING::
operator const char *(voidconst{
    
return this->str;
}

int main()
{
    STRING s(
"Hello,world");
    STRING e(
"I Love C++");
    cout 
<< "STRING:" << s << "\t strlen:" << s.strlen()<< endl;
    cout 
<< "STRING:" << e << "\t strlen:" << strlen(e)<< endl;
    
    
return 0;

}

 

  仅仅看输出,前面的一个是调用类函数strlen,没有参数,看到没有,如果有参数的话,就是下面的那个,那么此时就是调用的系统函数了。两者的输出不一样,我特意在自定义的strlen函数上面加5以表示区别,最后果然,前者就是调用自己的函数。
得到的结论就是,类的成员函数,都是有一个默认的this指针的,这个没有错,不过这个是编译器加的,我们手动是不能自己占有的,也就是说不能理解为有一个参数,然后放上面去,自己定义的是void参数,就没有参数,编译器加的是它的事情,那个地方提供给我们用户使用的就是无参的函数。此点要铭记,而且,即使你调用无参的,在具体编译器处理的时候,还是会给你加上,所以这部分你根本用不上,也不需要担心。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2010-01-09 00:20 deercoder 阅读(372) 评论(0)  编辑 收藏 引用 所属分类: C/C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理