2014笔试题目
1.sizeof的用法(附strlen函数)
1)通过指针指向字符串
转载于 http://blog.csdn.net/max_cpp/article/details/4268991
char* ss = "0123456789"; sizeof(ss) 结果 4 ===》ss是指向字符串常量的字符指针 sizeof(*ss) 结果 1 ===》*ss是第一个字符
strlen(ss)结果10 = = =》取得ss指针指向空间所存储的字符数
strlen(*ss)结果 错误 = = =》strlen的参数只能是char* 且必须是以''/0''结尾的 2)未指定数组大小的字符串数组
char ss[] = "0123456789"; sizeof(ss) 结果 11 ===》ss是数组,包括结束字符‘/0’,因此是10+1 sizeof(*ss) 结果 1 ===》*ss是第一个字符
3)指定数组大小的字符串数组
char ss[100] = "0123456789"; sizeof(ss) 结果是100 ===》ss表示在内存中的大小 100×1 strlen(ss) 结果是10 ===》计算ss数组中实际的串长度
4)指定数组大小的int数组
int ss[100] = "0123456789"; sizeof(ss) 结果 400 ===》ss表示再内存中的大小 100×4 strlen(ss) 错误 ===》strlen的参数只能是char* 且必须是以''/0''结尾的 5)
char q[]="abc"; char p[]="a\n"; char t[]={'a','\n'};
char tt[]={'\n'};
char tt1[100]={'\n'};
char ttt[]={'\n','\0'};
sizeof(q)结果是 4 = = =》使用” “给未指定大小的数组赋值,系统会自动在字符串后添加‘\0’结束符,sizeof()函数计算包括结束符在内的字符数,即3+1
sizeof(p)结果是 3 = = =》\n为转义字符,只占一个字节,则字符数为2
sizeof(t)结果是 2 = = =》使用{}初始化字符串数组,系统不会添加‘\0’,将字符串数组的长度定义为初始化字符的个数,即2
sizeof(tt)结果是1= = =》使用{}初始化字符串数组,系统不会添加‘\0’,将字符串数组的长度定义为初始化字符的个数,即1
sizeof(tt1)结果是 100= = =》获得字符串数组定义的大小
sizeof(ttt) 结果是 2 = = =》包含的字符个数
strlen(q) 结果是 3 = = =》实际包含的字符个数,不包含'\0'
strlen(p) 结果是 2 = = =》实际包含的字符个数,不包含'\0'
strlen(t)结果是 14 = = =》计算到'\0'前的字符个数
strlen(tt)结果是 23 = = =》计算到'\0'前的字符个数
strlen(tt1)结果是 1 = = =》初始化数组大小,并通过{}指定数组大小后,实际的字符个数
strlen(tt1)结果是 1 = = =》计算到'\0'前的字符个数
第二个例子:
class X { int i; int j; char k; }; X x; cout<<sizeof(X)<<endl; 结果 12 ===》内存补齐 cout<<sizeof(x)<<endl; 结果 12 同上
第三个例子:
char szPath[MAX_PATH]
如果在函数内这样定义,那么sizeof(szPath)将会是MAX_PATH,但是将szPath作为虚参声明时(void fun(char szPath[MAX_PATH])),sizeof(szPath)却会是4(指针大小)
二、sizeof深入理解。
- 1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。
- 2.sizeof是算符,strlen是函数。
- 3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''/0''结尾的。sizeof还可以用函数做参数,比如:
short f(); printf("%d/n", sizeof(f()));
输出的结果是sizeof(short),即2。 - 4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。
- 5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因
char str[20]="0123456789"; int a=strlen(str); //a=10; int b=sizeof(str); //而b=20;
- 6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。
- 7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
- 8.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof 归还全部数组的尺 寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸
- 9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:
fun(char [8]) fun(char [])
都等价于 fun(char *) 在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的大小, 需要这样做:进入函数后用memcpy拷贝出来,长度由另一个形参传进去fun(unsiged char *p1, int len) { unsigned char* buf = new unsigned char[len+1] memcpy(buf, p1, len); }
有关内容见: C++ PRIMER? - 10.计算结构变量的大小就必须讨论数据对齐问题。为了CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考一些计算机原理方面的书),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但理论上速度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的与实际不等。一般在VC++中加上#pragma pack(n)的设定即可.或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced compiler页中的Data alignment为按字节对齐。
- 11.sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。如sizeof(max)若此时变量max定义为int max(),sizeof(char_v) 若此时char_v定义为char char_v [MAX]且MAX未知,sizeof(void)都不是正确形式
三、结束语
sizeof使用场合。
- 1.sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如:
void *malloc(size_t size), size_t fread(void * ptr,size_t size,size_t nmemb,FILE * stream)。
- 2.用它可以看看一类型的对象在内存中所占的单元字节。
void * memset(void * s,int c,sizeof(s))
- 3.在动态分配一对象时,可以让系统知道要分配多少内存。
- 4.便于一些类型的扩充,在windows中就有很多结构内型就有一个专用的字段是用来放该类型的字节大小。
- 5.由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof来代替常量计算。
- 6.如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。
sizeof的总结:
基本类型:
sizeof(bool)=1;
sizeof(char)=1;
sizeof(short)=2;
sizeof(long)=4;
sizeof(int)=4;
sizeof(float)=4;
sizeof(double)=8;
sizeof(string)=16;
sizeof(vector<elemType>)=16;
元素类型为T,个数为n的数组array:
sizeof(array)=n*sizeof(T);
指针和引用:
sizeof作用于指针变量时,结果总是为4,而作用于引用变量时,结果等于所引用的变量的size。如:
double a; double* b=&a; double& c=a;
则sizeof(b)=4;sizeof(c)=8。
类:
1)无父类的类 : 其size原则上等于其非静态成员变量的size之和:
class CTest1{
public:
int a,b
static double c;
double d;
};
sizeof(CTest1)=sizeof(a)+sizeof(b) +sizeof(d)=4+4+8=16;
为什么说原则上等于呢?因为变量只能在内存中一个字的开头存储,所以定义成员变量的顺序可能会影响到类的size,如将上面的CTest1改为
class CTest2{
public:
int a;
static double c;
double d;
int b;
};
sizeof(CTest2)=24; 可以看出类中成员变量的定义顺序会影响到内存的利用率,这是跟编译器的对齐方式有关。
2)派生类:需要加上其基类的size
class CTest3:CTest1{
public:
int e;
}; sizeof(CTest3)=24
3)class CTest4{}; //sizeof(CTest4)=1
class CTest5{virtual ~CTest5(){}};//sizeof(CTest5)=4
C++中sizeof与strlen函数的区别
本文来自: IT知道网(http://www.itwis.com) 详细出处参考:http://www.itwis.com/html/c/ccc/20080826/2254.html
1. sizeof 操作符的结果类型size_t,它在头文件中typedef为unsigned int类型: typedef unsigned int size_t.
2. sizeof是是长度运算符, 获得数据类型或是变量的长度,如果是数据类型,则返回数据类型大小,如果是用数组,则 返回数组所占空间大小,strlen是计算字符串长度的函数,返回的是实际串长度,以char* 作参数 ,且必须是以'/0'结尾。
3. sizeof在编译的时候就把计算过,strlen的结果要在运行的时候才能计算出来。
4. 数组做长度运算符sizeof的参数不退化。数组做函数strlen的参数就退化为指针了,因为数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址。