sizeof()用法汇总

sizeof()用法汇总
sizeof()用法汇总

sizeof()功能:计算数据空间的字节数

1.与strlen()比较

strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素。

而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。

2.指针与静态数组的sizeof操作

指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。注意:int *p; sizeof(p)=4;

但sizeof(*p)相当于sizeof(int);

对于静态数组,sizeof可直接计算数组大小;

例:int a[10];char b[]="hello";

sizeof(a)等于4*10=40;

sizeof(b)等于6;

注意:数组做型参时,数组名称当作指针使用!!

void fun(char p[])

{sizeof(p)等于4}

经典问题:

double* (*a)[3][6];

cout<

cout<

cout<

cout<

问题解析:a是一个很奇怪的定义,他表示一个指向double*[3][6]类型数组的指针。既然是指针,所以sizeof(a)就是4。

既然a是执行double*[3][6]类型的指针,*a就表示一个double*[3][6]的多维数组类型,因此sizeof(*a)=3*6*sizeof(double*)=72。同样的,**a表示一个double*[6]类型的数组,所以sizeof(**a)=6*sizeof (double*)=24。***a就表示其中的一个元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一个double了,所以sizeof(*** *a)=sizeof(double)=8。

3.格式的写法

sizeof操作符,对变量或对象可以不加括号,但若是类型,须加括号。

4.使用sizeof时string的注意事项

string s="hello";

sizeof(s)等于string类的大小,sizeof(s.c_str())得到的是与字符串长度。

5.union 与struct的空间计算

总体上遵循两个原则:

(1)整体空间是占用空间最大的成员(的类型)所占字节数的整倍数

(2)数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐,以此向后类推。。。。。

注意:数组按照单个变量一个一个的摆放,而不是看成整体。如果成员中有自定义的类、结构体,也要注意数组问题。

例:[引用其他帖子的内容]

因为对齐问题使结构体的sizeof变得比较复杂,看下面的例子:(默认对齐方式下)

struct s1

{

char a;

double b;

int c;

char d;

};

struct s2

{

char a;

char b;

int c;

double d;

};

cout<

cout<

同样是两个char类型,一个int类型,一个double类型,但是因为对齐问题,导致他们的大小不同。计算结构体大小可以采用元素摆放法,我举例子说明一下:首先,CPU判断结构体的对界,根据上一节的结论,s1和s2的对界都取最大的元素类型,也就是double类型的对界8。然后开始摆放每个元素。

对于s1,首先把a放到8的对界,假定是0,此时下一个空闲的地址是1,但是下一个元素d 是double类型,要放到8的对界上,离1最接近的地址是8了,所以d被放在了8,此时下一个空闲地址变成了16,下一个元素c的对界是4,16可以满足,所以c放在了16,此时下一个空闲地址变成了20,下一个元素d需要对界1,也正好落在对界上,所以d放在了20,结构体在地址21处结束。由于s1的大小需要是8的倍数,所以21-23的空间被保留,s1的大小变成了24。

对于s2,首先把a放到8的对界,假定是0,此时下一个空闲地址是1,下一个元素的对界也是1,所以b摆放在1,下一个空闲地址变成了2;下一个元素c的对界是4,所以取离2最近的地址4摆放c,下一个空闲地址变成了8,下一个元素d的对界是8,所以d摆放在8,所有元素摆放完毕,结构体在15处结束,占用总空间为16,正好是8的倍数。

这里有个陷阱,对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:

struct s1

{

char a[8];

};

struct s2

{

double d;

};

struct s3

{

s1 s;

char a;

};

struct s4

{

s2 s;

char a;

};

cout<

cout<

cout<

cout<

s1和s2大小虽然都是8,但是s1的对齐方式是1,s2是8(double),所以在s3和s4中才有这样的差异。

所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。

补充:不要让double干扰你的位域

在结构体和类中,可以使用位域来规定某个成员所能占用的空间,所以使用位域能在一定程度上节省结构体占用的空间。不过考虑下面的代码:

struct s1

{

int i: 8;

int j: 4;

double b;

int a:3;

};

struct s2

{

int i;

int j;

double b;

int a;

};

struct s3

{

int i;

int j;

int a;

double b;

};

struct s4

{

int i: 8;

int j: 4;

int a:3;

double b;

};

cout<

cout<

cout<

cout<

可以看到,有double存在会干涉到位域(sizeof的算法参考上一节),所以使用位域的的时候,最好把float类型和double类型放在程序的开始或者最后。

相关常数:

sizeof int:4

sizeof short:2

sizeof long:4

sizeof float:4

sizeof double:8

sizeof char:1

sizeof p:4

sizeof WORD:2

sizeof DWORD:4

(完整版)数据结构课后习题及解析第二章

第二章习题 1.描述以下三个概念的区别:头指针,头结点,首元素结点。 2.填空: (1)在顺序表中插入或删除一个元素,需要平均移动元素,具体移动的元素个数与有关。 (2)在顺序表中,逻辑上相邻的元素,其物理位置相邻。在单链表中,逻辑上相邻的元素,其物理位置相邻。 (3)在带头结点的非空单链表中,头结点的存储位置由指示,首元素结点的存储位置由指示,除首元素结点外,其它任一元素结点的存储位置由指示。3.已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。按要求从下列语句中选择合适的语句序列。 a. 在P结点后插入S结点的语句序列是:。 b. 在P结点前插入S结点的语句序列是:。 c. 在表首插入S结点的语句序列是:。 d. 在表尾插入S结点的语句序列是:。 供选择的语句有: (1)P->next=S; (2)P->next= P->next->next; (3)P->next= S->next; (4)S->next= P->next; (5)S->next= L; (6)S->next= NULL; (7)Q= P; (8)while(P->next!=Q) P=P->next; (9)while(P->next!=NULL) P=P->next; (10)P= Q; (11)P= L; (12)L= S; (13)L= P; 4.设线性表存于a(1:arrsize)的前elenum个分量中且递增有序。试写一算法,将X插入到线性表的适当位置上,以保持线性表的有序性。 5.写一算法,从顺序表中删除自第i个元素开始的k个元素。 6.已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值为任意的整数)。 7.试分别以不同的存储结构实现线性表的就地逆置算法,即在原表的存储空间将线性表(a1, a2..., an)逆置为(an, an-1,..., a1)。 (1)以一维数组作存储结构,设线性表存于a(1:arrsize)的前elenum个分量中。 (2)以单链表作存储结构。 8.假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编写算法,将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A 表和B表的)结点空间存放表C。

sizeof()用法汇总

sizeof()功能:计算数据空间的字节数 1.与strlen()比较 strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素。 而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间,用字节数表示。 2.指针与静态数组的sizeof操作 指针均可看为变量类型的一种。所有指针变量的sizeof 操作结果均为4。 注意:int *p; sizeof(p)=4; 但sizeof(*p)相当于sizeof(int); 对于静态数组,sizeof可直接计算数组大小; 例:int a[10];char b[]="hello"; sizeof(a)等于4*10=40; sizeof(b)等于6; 注意:数组做型参时,数组名称当作指针使用!! void fun(char p[]) {sizeof(p)等于4} 经典问题: double* (*a)[3][6]; cout<

sizeof详细分析以及陷阱

1、什么是sizeof 首先看一下sizeof在msdn上的定义: The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of type size_t. 看到return这个字眼,是不是想到了函数?错了,sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以sizeof不是函数。网上有人说sizeof是一元操作符,但是我并不这么认为,因为sizeof更像一个特殊的宏,它是在编译阶段求值的。举个例子: cout<

CString用法

需要强制类型转化时,C++规则容许这种选择。比如,你可以将(浮点数)定义为将某个复数(有一对浮点数)进行强制类型转换后只返回该复数的第一个浮点数(也就是其实部)。可以象下面这样:Complex c(1.2f,4.8f);float realpart=c;如果(float)操作符定义正确的话,那么实部的的值应该是1.2。这种强制转化适合所有这种情况,例如,任何带有LPCTSTR类型参数的函数都会强制执行这种转换。于是,你可能有这样一个函数(也许在某个你买来的DLL中):BOOL DoSomethingCool(LPCTSTR s);你象下面这样调用它:CString file("c:¥¥myfiles¥¥coolstuff")BOOL result=DoSomethingCool(file);它能正确运行。因为DoSomethingCool函数已经说明了需要一个LPCTSTR类型的参数,因此LPCTSTR被应用于该参数,在MFC 中就是返回的串地址。如果你要格式化字符串怎么办呢?CString graycat("GrayCat");CString s;s.Format("Mew!I love%s",graycat);注意由于在可变参数列表中的值(在函数说明中是以"..."表示的)并没有隐含一个强制类型转换操作符。你会得到什么结果呢?一个令人惊讶的结果,我们得到的实际结果串是:"Mew!I love GrayCat"。因为MFC的设计者们在设计CString数据类型时非常小心,CString类型表达式求值后指向了字符串,所以这里看不到任何象Format或sprintf中的强制类型转换,你仍然可以得到正确的行为。描述CString的附加数据实际上在CString名义地址之后。有一件事情你是不能做的,那就是修改字符串。比如,你可能会尝试用","代替"."(不要做这样的,如果你在乎国际化问题,你应该使用十进制转换的National Language Support特性,),下面是个简单的例子:CString v("1.00");//货币金额,两位小数LPCTSTR p=v;p[lstrlen(p)-3]=,;这时编译器会报错,因为你赋值了一个常量串。如果你做如下尝试,编译器也会错:strcat(p,"each");因为strcat的第一个参数应该是LPTSTR类型的数据,而你却给了一个LPCTSTR。不要试图钻这个错误消息的牛角尖,这只会使你自己陷入麻烦!原因是缓冲有一个计数,它是不可存取的(它位于CString地址之下的一个隐藏区域),如果你改变这个串,缓冲中的字符计数不会反映所做的修改。此外,如果字符串长度恰好是该字符串物理限制的长度(梢后还会讲到这个问题),那么扩展该字符串将改写缓冲以外的任何数据,那是你无权进行写操作的内存(不对吗?),你会毁换坏不属于你的内存。这是应用程序真正的死亡处方。CString转化成char*之二:使用CString对象的GetBuffer方法;如果你需要修改CString中的内容,它有一个特殊的方法可以使用,那就是GetBuffer,它的作用是返回一个可写的缓冲指针。如果你只是打算修改字符或者截短字符串,你完全可以这样做:CString s(_T("File.ext"));LPTSTR p=s.GetBuffer();LPTSTR dot=strchr(p,.);//OK, should have used s.Find...if(p!=NULL)*p=_T(¥0);s.ReleaseBuffer();这是GetBuffer的第一种用法,也是最简单的一种,不用给它传递参数,它使用默认值0,意思是:"给我这个字符串的指针,我保证不加长它"。当你调用ReleaseBuffer时,字符串的实际长度会被重新计算,然后存入CString对象中。必须强调一点,在

C语言32个关键字九种控制语句34种运算符

总结归纳了C语言的32个关键字 第一个关键字:auto 用来声明自动变量。可以显式的声明变量为自动变量。只要不是声明在所有函数之前的变量,即使没加auto关键字,也默认为自动变量。并且只在声明它的函数内有效。而且当使用完毕后,它的值会自动还原为最初所赋的值。自动变量使用时要先赋值,因为其中包含的是未知的值。 例:auto int name=1; 第二个关键字:static 用来声明静态变量。可以显式的声明变量为静态变量。也为局部变量。只在声明它的函数内有效。它的生命周期从程序开始起一直到程序结束。而且即使使用完毕后,它的值仍旧不还原。即使没有给静态变量赋值,它也会自动初始化为0. 例:static int name=1. 第三个关键字:extern 用来声明全局变量。同时声明在main函数之前的变量也叫全局变量。它可以在程序的任何地方使用。程序运行期间它是一直存在的。全局变量也会初始化为0. 例:extern int name; 第四个关键字:register 用来声明为寄存器变量。也为局部变量,只在声明它的函数内有效。它是保存在寄存器之中的。速度要快很多。对于需要频繁使用的变量使用它来声明会提高程序运行速度。 例:register int name=1; 第五个关键字:int 用来声明变量的类型。int为整型。注意在16位和32位系统中它的范围是不同的。16位中占用2个字节。32位中占用4个字节。还可以显式的声明为无符号或有符号: unsigned int或signed int .有符号和无符号的区别就是把符号位也当作数字位来存储。也可用short和long来声明为短整型,或长整行。 例:int num; 第六个关键字:float 用来声明变量的类型。float为浮点型,也叫实型。它的范围固定为4个字节。其中6位为小数位。其他为整数位。 例:float name;

C语言中的sizeof的理解

C语言中的sizeof的理解。。 一、sizeof的概念 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、--等。它并不是函数。sizeof操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 二、sizeof的使用方法 1、用于数据类型sizeof使用形式:sizeof(type) 数据类型必须用括号括住。如sizeof(int)。 2、用于变量sizeof使用形式:sizeof(var_name)或sizeof var_name 变量名可以不用括号括住。如sizeof(var_name),sizeof var_name等都是正确形式。带括号的用法更普遍,大多数程序员采用这种形式。 注意:sizeof操作符不能用于函数类型,不完全类型或位字段。不完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类型、未知内容的结构或联合类型、void类型等。 如sizeof(max)若此时变量max定义为int max(),sizeof(char_v)若此时char_v定义为char char_v[MAX]且MAX未知,sizeof(void)都不是正确形式。 三、sizeof的结果 sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 1、若操作数具有类型char、unsigned char或signed char,其结果等于1。 ANSI C正式规定字符类型为1字节。 2、int、unsigned int、short int、unsigned short、long int、unsigned long、float、double、long double类型的sizeof在ANSI C中没有具体规定,大小依赖于实现,一般可能分别为2、2、2、2、4、4、4、8、10。 3、当操作数是指针时,sizeof依赖于编译器。例如Microsoft C/C++7.0中,near类指针字节数为2,far、huge类指针字节数为4。一般Unix的指针字节数为4。 4、当操作数具有数组类型时,其结果是数组的总字节数。 5、共用体类型操作数的sizeof是其最大字节成员的字节数。结构类型操作数的sizeof 是这种类型对象的总字节数。 让我们看如下结构: struct{char b;double x;}a; 在某些机器上sizeof(a)=12,而一般sizeof(char)+sizeof(double)=9。 这是因为编译器在考虑对齐问题时,在结构中插入空位以控制各成员对象的地址对齐。如double类型的结构成员x要放在被4整除的地址。 6、如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 四、sizeof与其他操作符的关系 sizeof的优先级为2级,比/、%等3级运算符优先级高。它可以与其他操作符一起组成表达式。如i*sizeof(int);其中i为int类型变量。 五、sizeof的主要用途 1、sizeof操作符的一个主要用途是与存储分配和I/O系统那样的例程进行通信。例如: void*malloc(size_t size), size_t fread(void*ptr, size_t size, size_t nmemb, FILE*stream)。 2、sizeof的另一个的主要用途是计算数组中元素的个数。例如: void*memset(void*s, int c, sizeof(s))。

算法设计与分析(详细解析(含源代码)

常用算法设计方法 要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。算法数据结构是程序的两个重要方面。 算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。指令正确地描述了要完成的任务和它们被执行的顺序。计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。 通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。其次是算法所需要的存储空间少和执行更快等。 算法设计是一件非常困难的工作,经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。另外,为了更简洁的形式设计和藐视算法,在算法设计时又常常采用递归技术,用递归描述算法。 一、迭代法 迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行: (1)选一个方程的近似根,赋给变量x0; (2)将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0; (3)当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。 若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为: 【算法】迭代法求方程的根 { x0=初始近似根; do { x1=x0; x0=g(x1);/*按特定的方程计算新的近似根*/ } while ( fabs(x0-x1)>Epsilon);

C语言二级考前一个月复习概况

整数的三种表示形式 表示形式 组成 开头部分 十进制 D,或不加表示 0-9 以1-9开头 八进制 O 0-7 以0开头 十六进制 H 0-9,A-F 以0x 开头 int a[100],*p; 等价语句 p=a; P=&a[0]; 等价语句 p=a+1; P=&a[1]; 文本文件 二进制文件 使用方式 含义 使用方式 含义 r 打开文本文件进 行只读 rb 打开二进制文件进行只读 w 建立新的文本文件进行只写 wb 建立二进制文件进行只写 a 打开文本文件进 行追加 ab 打开二进制文件进行追加/写 R+ 打开文本文件进 行读/写 Rb+ 打开二进制文件进行读/写 W+ 建立新的文本文件进行读/写 Wb+ 建立二进制文件进行读/写 A+ 打开文本文件进行读/写/追加 Ab+ 打开二进制文件进行读/写/追加

指针是以地址作为其值的变量,数组名的值是一个特殊的固定地址,可以作为常量指针。 类型 名称 类型名 数据长度 整型 整型 Int 32位 短整型 Short int 16位 长整型 Long int 32位 字符型 字符型 Char 8位 实型(浮点型) 单精度浮点型 float 32位 双精度浮点型 double 64位 函数 数据类型 格式 printf float %f double %e scanf float %f %e double %lf %le 字符串的输入和输出 输入 Scanf() 该函数遇到空格或回车输入结束 Gets() 该函数遇到回车符输入结束 输出 Printf() 输出时遇到’\0’输出结束 Puts() 输出时遇到’\0’输出结束 运算符 优先级 结合方式 优先级:高->低 逻辑运算符 ! 右->左 算术运算符 ++ -- + - * 右->左 * / % + - 左->右 关系运算符 <= < >= > == != 左->右 逻辑运算符 && || 左-> 右 条件表达式 ?: 右->左 赋值运算符 *= /= %= += - = = 右->左

枚举大小sizeof中枚举的大小详解

至从语言开始类型就被作为用户自定义分类有限集合常量地方法被引入到了语言当中,而且一度成为中定义编译期常量地唯一方法(后来在类中引入了静态整型常量). 根据上面对类型地描述,有以下几个问题: .到底所定义出来地类型是一个什么样地类型呢? .作为一个用户自定义地类型其所占用地内存空间是多少呢? .使用类型是否真地能够起到有限集合常量地边界约束呢? .大家可能都知道类型和类型具有隐示(自动)转换地规则,那么是否真地在任何地方都可以使用类型地变量来代替类型地变量呢? . 到底所定义出来地类型是一个什么样地类型呢? 在中大家都知道仅仅有两种大地类型分类:类型(注())和类类型. 所定义地类型其实属于类型,也就是说它会参与到类型地隐示转换规则当中去,所以才会出现类型与类型之间地隐示转换现象. 那么也就是说所定义地类型不具备名字空间限定能力(因为不属于类类型),其所定义地常量子具备和类型所在名字空间相同地可见性,由于自身没有名字限定能力,所以会出现名字冲突现象. 如: { { , }; { , }; }; 上面地例子会出现、名字冲突编译时错误,原因就在于枚举子(、)是名字空间中地名字,同样在引用该中地枚举子时必须采用这样地方式进行,而不是来进行引用. 注()类型: 你可以将类型看作是一种来自外太空地用绿色保护层包装地数据类型,意为“”(译者:如果一定要译成中文,那就叫“彻头彻尾地老数据”怎么样!)这就是类型地含义. 其确切定义相当粗糙(参见标准),其基本意思是类型包含与兼容地原始数据. 例如,结构和整型是类型,但带有构造函数或虚拟函数地类则不是. 类型没有虚拟函数,基类,用户定义地构造函数,拷贝构造,赋值操作符或析构函数. 为了将类型概念化,你可以通过拷贝其比特来拷贝它们.此外,类型可以是非初始化地.b5E2R。 . 作为一个用户自定义地类型其所占用地内存空间是多少呢? 该问题就是( )等于多少地问题,是不是每一个用户自定义地枚举类型都具有相同地尺寸呢? 在大多数地位编译器下(如:、等)一个枚举类型地尺寸其实就是一个( )地大小,难道枚举类型地尺寸真地就应该是类型地尺寸吗? 其实不是这样地,在标准文档()中并没有这样来定义, 标准中是这样说明地:“枚举类型地尺寸是以能够容纳最大枚举子地值地整数地尺寸”, 同时标准中也说名了:“枚举类型中地枚举子地值必须要能够用一个类型表述”, 也就是说,枚举类型地尺寸不能够超过类型地尺寸,但是是不是必须和类型具有相同地尺寸呢?上面地标准已经说得很清楚了,只要能够容纳最大地枚举子地值地整数就可以了,那么就是说可以是、和. 例如:

最新sort函数的用法

sort函数的用法 做ACM题的时候,排序是一种经常要用到的操作。如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错。STL里面有个sort 函数,可以直接对数组排序,复杂度为n*log2(n)。使用这个函数,需要包含头文件。 做ACM题的时候,排序是一种经常要用到的操作。如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的比赛时间,还很有可能写错。STL里面有个sort 函数,可以直接对数组排序,复杂度为n*log2(n)。使用这个函数,需要包含头文件。 这个函数可以传两个参数或三个参数。第一个参数是要排序的区间首地址,第二个参数是区间尾地址的下一地址。也就是说,排序的区间是[a,b)。简单来说,有一个数组int a[100],要对从a[0]到a[99]的元素进行排序,只要写sort(a,a+100)就行了,默认的排序方式是升序。 拿我出的“AC的策略”这题来说,需要对数组t的第0到len-1的元素排序,就写sort(t,t+len); 对向量v排序也差不多,sort(v.begin(),v.end()); 排序的数据类型不局限于整数,只要是定义了小于运算的类型都可以,比如字符串类string。 如果是没有定义小于运算的数据类型,或者想改变排序的顺序,就要用到第三参数——比较函数。比较函数是一个自己定义的函数,返回值是bool型,它规定了什么样的关系才是“小于”。想把刚才的整数数组按降序排列,可以先定义一个比较函数cmp bool cmp(int a,int b) { return a>b; } 排序的时候就写sort(a,a+100,cmp); 假设自己定义了一个结构体node struct node{ int a; int b; double c;

C语言中sizeof()的用法

C语言中sizeof()的用法 2008-12-31 09:45:35.0 来源:51CTO 关键词:C语言 要参加软件研发的笔试(C/C++)几乎都会涉及到sizeof()的用法,我昨天也遇到了,有的也会,但是真正sizeof()的核心还是没有领会,今天上网,无聊中就看到了详细的sizeof()的阐述,现在分享给大家。 ------------sizeof---------------- sizeof 一般形式为:sizeof(object),也可以sizeof var_char,不过大部分programer 习惯用sizeof()。 对象可以是表达式或者数据类型名,当对象是表达式时,括号可省略。sizeof是单目运算符,其运算符的含义是:求出对象在计算机内存中所占用的字节数。一般来讲,不同的机器,运行不同的对象是不一样的,当目前几乎所有的机器都是32位,很少16位的,所以一般考试都是基于32位的window和linux的。 C语言中数据类型不多。 1.整数型的: short,int,long(我没有考虑符号问题),一般c语言书上讲,int是2个字节的,即16位,范围是-32768-32767,long是4个字节,范围是-2^32---2^32-1。当时在xp上运行sizeof(int)的时候,会output 4.这就是32位的原因。sizeof(long)也是4. 如下:#include "stdio.h" #include "string.h" #include "stdlib.h" int main() { short int sa=10; int a=10; long la=10; float f = 20; double d=20; char ch=''c''; char str[]="ABC"; char *p=str; struct str{ double d; char ch; int data; }str_wu; struct str1{ char ch; double d; int data; }str_wu1; printf("sizeof(short):%d\n",sizeof(sa)); printf("sizeof(int):%d\n",sizeof(a));

枚举大小sizeof 中枚举的大小详解

至从C语言开始enum类型就被作为用户自定义分类有限集合常量的方法被引入到了语言当中,而且一度成为C++中定义编译期常量的唯一方法(后来在类中引入了静态整型常量)。 根据上面对enum类型的描述,有以下几个问题: 1.到底enum所定义出来的类型是一个什么样的类型呢? 2.作为一个用户自定义的类型其所占用的内存空间是多少呢? 3.使用enum类型是否真的能够起到有限集合常量的边界约束呢? 4.大家可能都知道enum类型和int类型具有隐示(自动)转换的规则,那么是否真的在任何地方都可以使用enum类型的变量来代替int类型的变量呢? 1. 到底enum所定义出来的类型是一个什么样的类型呢? 在C++中大家都知道仅仅有两种大的类型分类:POD类型(注(1))和类类型。 enum所定义的类型其实属于POD类型,也就是说它会参与到POD类型的隐示转换规则当中去,所以才会出现enum类型与int类型之间的隐示转换现象。 那么也就是说enum所定义的类型不具备名字空间限定能力(因为不属于类类型),其所定义的常量子具备和enum类型所在名字空间相同的可见性,由于自身没有名字限定能力,所以会出现名字冲突现象。 如: struct CEType { enum EType1 { e1, e2 }; enum EType2 { e1, e2 }; }; 上面的例子会出现e1、e2名字冲突编译时错误,原因就在于枚举子(e1、e2)是CEType 名字空间中的名字,同样在引用该CEType中的枚举子时必须采用CEType::e1这样的方式进行,而不是CEType::EType1::e1来进行引用。 注(1)POD类型: 你可以将POD 类型看作是一种来自外太空的用绿色保护层包装的数据类型,POD 意为“Plain Old Data”(译者:如果一定要译成中文,那就叫“彻头彻尾的老数据”怎么样!)这就是POD 类型的含义。 其确切定义相当粗糙(参见C++ ISO 标准),其基本意思是POD 类型包含与C 兼容的原始数据。 例如,结构和整型是POD 类型,但带有构造函数或虚拟函数的类则不是。 POD 类型没有虚拟函数,基类,用户定义的构造函数,拷贝构造,赋值操作符或析构函数。 为了将POD 类型概念化,你可以通过拷贝其比特来拷贝它们。此外,POD 类型可以是非初始化的。 2. 作为一个用户自定义的类型其所占用的内存空间是多少呢? 该问题就是sizeof( EType1 )等于多少的问题,是不是每一个用户自定义的枚举类型都具有相同的尺寸呢? 在大多数的32位编译器下(如:VC++、gcc等)一个枚举类型的尺寸其实就是一个sizeof( int )的大小,难道枚举类型的尺寸真的就应该是int类型的尺寸吗? 其实不是这样的,在C++标准文档(ISO14882)中并没有这样来定义, 标准中是这样说明的:“枚举类型的尺寸是以能够容纳最大枚举子的值的整数的尺寸”, 同时标准中也说名了:“枚举类型中的枚举子的值必须要能够用一个int类型表述”,

数据结构课后习题及解析第二章word版本

第二章习题 1. 描述以下三个概念的区别:头指针,头结点,首元素结点。 2. 填空: (1)在顺序表中插入或删除一个元素,需要平均移动元素,具体移动的元素个数与有关。 (2)在顺序表中,逻辑上相邻的元素,其物理位置相邻。在单链表中,逻辑上相邻的元素,其物理位置相邻。 (3)在带头结点的非空单链表中,头结点的存储位置由指示,首元素结点的存储位置由指示,除首元素结点外,其它任一元素结点的存储位置由指示。3.已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。按要求从下列语句中选择合适的语句序列。 a. 在P结点后插入S结点的语句序列是:。 b. 在P结点前插入S结点的语句序列是:。 c. 在表首插入S结点的语句序列是:。 d. 在表尾插入S结点的语句序列是:。 供选择的语句有: (1)P->next=S; (2)P->next= P->next->next; (3)P->next= S->next; (4)S->next= P->next; (5)S->next= L; (6)S->next= NULL; (7)Q= P; (8)while(P->next!=Q) P=P->next; (9)while(P->next!=NULL) P=P->next; (10)P= Q; (11)P= L; (12)L= S; (13)L= P; 4. 设线性表存于a(1:arrsize)的前elenum个分量中且递增有序。试写一算法,将X插入到线性表的适当位置上,以保持线性表的有序性。 5. 写一算法,从顺序表中删除自第i个元素开始的k个元素。 6. 已知线性表中的元素(整数)以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有大于mink且小于maxk的元素(若表中存在这样的元素),分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值为任意的整数)。 7. 试分别以不同的存储结构实现线性表的就地逆置算法,即在原表的存储空间将线性表(a1, a2..., an)逆置为(an, an-1,..., a1)。 (1)以一维数组作存储结构,设线性表存于a(1:arrsize)的前elenum个分量中。 (2)以单链表作存储结构。 8. 假设两个按元素值递增有序排列的线性表A和B,均以单链表作为存储结构,请编写算法,将A表和B表归并成一个按元素值递减有序排列的线性表C,并要求利用原表(即A 表和B表的)结点空间存放表C。

C语言习题九数组的定义和使用

习题九数组的定义和使用 1. 有以下程序 void f (int b[]) { int i; for(i=2;i<6;i++) b[i]* =2;} main() { int a[10]={1,2,3,4,5,6,7,8,9,10},i; f(a); for(i=0;i<10;i++) printf("%d,",a[i]);} 程序运行后的输出结果是______。 A、1,2,3,4,5,6,7,8,9,10, B、1,2,6,8,10,12,7,8,9,10, C、1,2,3,4,10,12,14,16,9,10, D、1,2,6,8,10,12,14,16,9,10, 解析:本题在调用函数时,实参是&a[0]的地址,即把a[0]的地址传给形参,由条件i=2且i<6得出函数将对a[2]开始的4个元素(3,4,5,6)进行乘以2操作,结果分别为:a[2]=6,a[3]=8,a[4]=10,a[5]=12。a[0]、a[1]、a[6]、a[7]、a[8]、a[9]的值并没有发生变化,所以最后的输出结果为:1,2,6,8,10,12,7,8,9,10,。故本题答案选B。 2. 有以下程序 main() { int a[4][4]={{1,4,3,2},{8,6,5,7},{3,7,2,5},{4,8,6,1}},i,j,k,t; for(i=0;i<4;i++) for(j=0;j<3;j++) for(k=j+1;k<4;k++) if(a[j][i]>a[k][i]) {t=a[j][i];a[j][i]=a[k][i];a[k][i]=t;} /*按列排序*/ for(i=0;i<4;i++) printf("%d,",a[i][i]); } 程序运行后的输出结果是______。 A、1,6,5,7, B、8,7,3,1, C、4,7,5,2, D、1,6,2,1, 解析:本题首先定义了一个4行4列的二维数组a,并用了三层循环来进行按列由小到大排序操作。外层循环变量i表示数组的列,第二层循环变量j表示数组的行,第三层循环用于求第i列第j行的最小值,其中通过if语句对相关数值进行比较和交换。然后再通过for语句对排序数组对角线上的值进行输出,即输出a[0][0]、a[1][1]、a[2][2]、a[3][3]。故本题答案选A。 3. 有以下程序 main() { int i,t[][3]={9,8,7,6,5,4,3,2,1}; for(i=0;i<3;i++) printf("%d ",t[2-i][i]); } 程序执行后的输出结果是______。 A、7 5 3 B、3 5 7 C、3 6 9 D、7 5 1 解析:本题考查的是二维数组的应用。将初始值放在一对大括号内,按数组元素排列的顺序对各元素赋值,二维数组中行下标可以省略,但列下标必须要指定,由此题可以看出数组t是一个三行三列的二维数组,执行for循环语句t[2-i][i]分别为t[2][0],t[1][1],t[0][2],得出输出结果为3 5 7。故本题答案为B。

类的大小解析 sizeof()中类的大小详解

1、空类的sizeof是1。空类是指没有成员的类,类中的函数不占空间,除非是虚函数。 如:class A { public: A(){} ~A(){} void fun(){} }; sizeof(A)是1. 注:class A1 { public: A1(){} ~A1(){} void fun(){} char a[0]; }; sizeof(A1)也是1.(VC6.0下编译)

2、若类中包含成员,则类对象的大小只包括其中非静态成员经过对齐所占的空间,对齐方式和结构体相同。如: class A { public: int b; float c; char d; }; sizeof(A)是12. class A { public: static int a; int b; float c; char d; }; sizeof(A)是12. class A { public: static int a; int b; float c; char d; int add(int x,int y) { return x+y; }

sizeof(A)也是12. 3、若类中包含虚函数,则无论有几个虚函数,sizeof类都等于sizeof(数据成员)的和+sizeof(V表指针,为4),如: class Base { public: Base(){cout<<"Base-ctor"<

宏#,##的用法

C/C++ 宏中“#"和"##”的用法 ●一般用法 通常情况我们一般把宏#参数变为一个字符串,形如:123--->”123”,当然这种转换方法很多譬如:itoa,sprintf等函数都可以完成,但是如果频繁的调用这些系统调用的话,会造成较大的系统开销,使用宏#不失为一种高效便捷的手段, 用##把两个宏参数贴合在一起. 简单的方法。 #include #define STR(s) #s #define CONS(x,y) (int)(x##e##y) int main() { printf("%s\n",STR(123)); Printf(“%d\n”,CONS(3,3)); return 0; } --------下面是执行结果 ./a.out 123 3000 ●'#'和'##'的一些应用特例 1.合并匿名变量名 #define ___ANONYMOUS1(type, var, line) type var##line #define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line) #define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__) 例: ANONYMOUS(static int); 即: static int _anonymous70; 70表示该行行号; 第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__); 第二层:--> ___ANONYMOUS1(static int, _anonymous, 70); 第三层:--> static int _anonymous70;

sizeof用法总结

sizeof用法总结 本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主要用法。 1、sizeof应用在结构上的情况 请看下面的结构: struct MyStruct { double dda1; char dda; int type }; 对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求: sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13 但是当在VC中测试上面结构的大小时,你会发现sizeof(MyStruct)为16。你知道为什么在VC中会得出这样一个结果吗? 其实,这是VC对变量存储的一个特殊处理。为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。 类型 对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量) Char 偏移量必须为sizeof(char)即1的倍数 int 偏移量必须为sizeof(int)即4的倍数 float 偏移量必须为sizeof(float)即4的倍数 double 偏移量必须为sizeof(double)即8的倍数

Short 偏移量必须为sizeof(short)即2的倍数 各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 下面用前面的例子来说明VC到底怎么样来存放结构的。 struct MyStruct { double dda1; char dda; int type }; 为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为: sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。 下面再举个例子,交换一下上面的MyStruct的成员变量的位置,使它变成下面的情况: struct MyStruct { char dda; double dda1;

相关文档
最新文档