Title:huubby的博客
Description:Keywords:Body:
huubby的博客
huubby的博客
渴望成为农场主的程序员
首页
关于
留言板
字符数组,字符指针,Sizeof总结-转载技术文章
2010年3月3日
huubby 没有评论
今天有位同事问到关于字符串数组和字符串指针的问题,我简单讲了一下。回来之后细想想讲的有点问题,本来想总结一下写篇blog详细说说,但随便一搜,网上很多讲的很好的文章,我从博客园转这篇讲的挺好的文章放这里,有兴趣的可以看看。原文在这里,作者是JeffChen。
1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写 #8221;abc #8221;,那么编译器帮你存储的是 #8221;abc\0 #8243;
2. #8221;abc #8221;是常量吗?答案是有时是,有时不是。
不是常量的情况: #8221;abc #8221;作为字符数组初始值的时候就不是,如char str[] = #8220;abc #8221;;
因为定义的是一个字符数组,所以就相当于定义了一些空间来存放 #8221;abc #8221;,而又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为 char str[3] = { #8216;a #8217;,'b #8217;,'c #8217;};
又根据上面的总结1,所以char str[] = #8220;abc #8221;;的最终结果是 char str[4] = { #8216;a #8217;,'b #8217;,'c #8217;,'\0 #8242;};
做一下扩展,如果char str[] = #8220;abc #8221;;是在函数内部写的话,那么这里的 #8221;abc\0 #8243;因为不是常量,所以应该被放在栈上。
是常量的情况: 把 #8221;abc #8221;赋给一个字符指针变量时,如
char* ptr = #8220;abc #8221;;
因为定义的是一个普通指针,并没有定义空间来存放 #8221;abc #8221;,所以编译器得帮我们找地方来放 #8221;abc #8221;,显然,把这里的 #8221;abc #8221;当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = #8216;x #8217;;也能编译通过,但是执行ptr[0] = #8216;x #8217;;就会发生运行时异常,因为这个语句试图去修改程序常量区中的东西。记得哪本书中曾经说过char* ptr = #8220;abc #8221;;这种写法原来在c++标准中是不允许的,但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,但是建议的写法应该是const char* ptr = #8220;abc #8221;;这样如果后面写ptr[0] = #8216;x #8217;的话编译器就不会让它编译通过,也就避免了上面说的运行时异常。
又扩展一下,如果char* ptr = #8220;abc #8221;;写在函数体内,那么虽然这里的 #8221;abc\0 #8243;被放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,只不过是它所指向的东西被放在常量区罢了。
3.数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。
4.字符串常量的类型可以理解为相应字符常量数组的类型,如 #8221;abcdef #8221;的类型就可以看成是const char[7]
5.sizeof是用来求类型的字节数的。如int a;那么无论sizeof(int)或者是sizeof(a)都是等于4,因为sizeof(a)其实就是sizeof(type of a)
6.对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型,如对于void func(char sa[100],int ia[20],char *p),则sa的类型为char*,ia的类型为int*,p的类型为char*
7.根据上面的总结,来实战一下:
对于char str[] = #8220;abcdef #8221;;就有sizeof(str) == 7,因为str的类型是char[7]。
也有sizeof( #8220;abcdef #8221;) == 7,因为 #8221;abcdef #8221;的类型是const char[7]。
对于char *ptr = #8220;abcdef #8221;;就有sizeof(ptr) == 4,因为ptr的类型是char*。
对于char str2[10] = #8220;abcdef #8221;;就有sizeof(str2) == 10,因为str2的类型是char[10]。
对于void func(char sa[100],int ia[20],char *p),就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,
因为sa的类型是char*,ia的类型是int*,p的类型是char*。
分类: 技术, 转载 标签: const常量, 字符串指针, 字符串数组
新浪围脖
2010年2月27日
huubby 没有评论
墙外待久了,容易与世隔绝。我也玩新浪围脖了,有兴趣的可以一起来。
围脖:http://t.sina.com.cn/huubby
推特:https://twitter.com/huubby
分类: 杂谈 标签: 围脖, 推特
新年快乐
2010年2月13日
huubby 1 条评论
又是一年除夕,小时候漫长的时光,长大后就穿了双轮滑鞋,哧溜一声,就滑过一年。过去的一年有不少收获,希望新的一年再接再厉。
祝各位朋友,认识我的,我认识的,素未谋面的推友们,新春快乐,虎年大吉大利。
借用@Fenng的一句话,一切高墙都会倒塌,只要我们坚持并坚信。
分类: 杂谈 标签:
CppUnit CookBook中文版
2010年1月27日
huubby 没有评论
自己翻译的cppunit cookbook,如有错漏,欢迎指出。可以在这里下载到cppunit的最新版本源码。
这只是一个cookbook的翻译,并没介绍安装方法,你可以在这里找到win32下的安装方法和例子。不过,这个例子并不清楚,还是建议你看看这里的例子,清楚的多。看完这些安装方法和例子之后,再回头看看这篇cookbook,应该会帮助你理解例子里面那些代码的含义。
1、简单的测试案例
怎么才能知道你的代码是不是能够正常工作?有很多方法可以达到这个目的。通过调试器单步跟踪,或者在你的代码里加入打印输出代码是两个比较简单的办法,但是这两个方法都有缺点。单步跟踪不能自动进行,每次代码稍有调整就要进行调试。打印输出也不错,只是这种方法会增加很多不必要的代码,导致代码臃肿丑陋。
CppUnit单元测试很容易建立起来,并且可以自动进行,而且,一旦你写完测试用例,就能通过它们保证你的代码质量。
按照下面的流程可以构造一个简单的test:
1、继承CppUnit::TestCase类。
2、重写runTest()方法。
3、使用CPPUNIT_ASSERT()和CPPUNIT_ASSERT(bool)两个宏来检测表达式或值,以判断测试成功与否。
举个例子,如果要测试一个复数类的赋值(=号)运算符,按照上面的步骤,代码如下:
class ComplexNumberTest : public CppUnit::TestCase
{
public:
ComplexNumberTest( std::string name ) : CppUnit::TestCase( name ) {}
void runTest()
{
CPPUNIT_ASSERT( Complex (10, 1) == Complex (10, 1) );
CPPUNIT_ASSERT( !(Complex (1, 1) == Complex (2, 2)) );
}
};
一个简单的test就建起来了。但通常来说,我们会在同一个对象里面有很多小的测试用例。这种情况下,我们用fixture。
2、fixture
fixture是为一组测试用例提供基础服务的对象,当你边开发边测试时,使用fixture非常方便。我们试着模拟一下这种边开发边测试情况。
假设我们真的在开发一个复数类,首先,定义一个空的Complex类:
class Complex {};
现在,创建一个上面的ComplexNumberTest类对象,然后编译代码看看会发生什么。我们会得到几个编译错误。因为测试过程中用到了==操作符,但我们并没定义这个运算符。
现在为Complex类定义一个:
bool operator==( const Complex amp;amp;a, const Complex amp;amp;b)
{
return true;
}
再次编译运行这个测试。这次编译虽然通过了,但测试却是失败的。
要再做一点点事情让==操作符正常工作,重写代码如下:
class Complex
{
friend bool operator ==(const Complex amp;amp; a, const Complex amp;amp; b);
double real, imaginary;
public:
Complex( double r, double i = 0 ) :real(r) , imaginary(i) {}
};
bool operator ==( const Complex amp;amp;a, const Complex amp;amp;b )
{
return a.real == b.real amp;amp; amp;amp; a.imaginary == b.imaginary;
}
编译运行,测试顺利通过。
好了,现在我们准备增加一些新的操作和新的测试。这个时候,fixture就体现出方便性了。因为在这个时候,如果使用fixture实例化三四个Complex对象,并且在测试过程中复用这几个对象,这样不需要重复构建这些实例对象,测试代码会更加好写。
fixture的使用步骤如下:
- 给每个fixture添加成员变量;
- 重写CppUnit::TestFixture::setUp()以初始化这些变量;
- 重写CppUnit::TestFixture::tearDown()方法释放setUp申请的系统资源。
class ComplexNumberTest : public CppUnit::TestFixture
{
private:
Complex *m_10_1, *m_1_1, *m_11_2;
public:
void setUp()
{
m_10_1 = new Complex( 10, 1 );
m_1_1 = new Complex( 1, 1 );
m_11_2 = new Complex( 11, 2 );
}
void tearDown()
{
delete m_10_1;
delete m_1_1;
delete m_11_2;
}
};
有了这个fixture之后,我们就能在开发过程中添加另外的测试用例和我们需要的其他东西了。
阅读全文 #8230;
分类: 技术 标签: cookbook, cppunit, 单元测试
下一页
订阅
Google
有道
鲜果
抓虾
My Yahoo!
newsgator
Bloglines
哪吒
Twitter
Calender
2010年三月
一
二
三
四
五
六
日
laquo; 二
1234567
891011121314
15161718192021
22232425262728
293031
Recent Posts
字符数组,字符指针,Sizeof总结-转载技术文章
新浪围脖
新年快乐
CppUnit CookBook中文版
聚合QQ,MSN,GTALK的即时聊天软件-Miranda IM
Recent comments huubby 在 【奇文赏析】百度首席产品设计师孙云丰评论谷歌退出中国事件 上的评论程子 在 【奇文赏析】百度首席产品设计师孙云丰评论谷歌退出中国事件 上的评论杨利军 在 新年快乐 上的评论huubby 在 聚合QQ,MSN,GTALK的即时聊天软件-Miranda IM 上的评论陈佳 在 笑死我了 上的评论
Archives
2010年三月
2010年二月
2010年一月
2009年十二月
Categories
技术
杂谈
转载
Tagsbaidu
boost
const常量
cookbook
cppunit
delete
exe程序启动
google
mirandaim
p2p下载
shared_ptr
TopLanguage
verycd
中产阶级
位向量
公民精神
函数指针
单元测试
围脖
字符串指针
字符串数组
对话
我们台湾这些年
排序
推特
析构函数
符号表
细节
经济
继承
编程之美
虚函数表
运行时库Blogroll
一五一十部落
老杨头(杨恒均)的独立博客
谷奥-探寻谷歌的奥秘
Programming
4G spaces
TopLanguage
vgod’s blog
吴阳春的blog
酷壳
回到顶部
WordPress
版权所有 copy; 2009-2010 huubby的博客
主题由 NeoEase 提供, 通过 XHTML 1.1 和 CSS 3 验证.
noscript