sizeof陷阱分析

sizeof陷阱分析
sizeof陷阱分析

C++ 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更像一个特殊的宏,它是在编译阶段求值的。举个例子:

在编译阶段已经被翻译为:

这里有个陷阱,看下面的程序:

输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码,所以sizeof作用范围内,也就是()里面的内容也不能被编译,而是被替换成类型。=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:

所以,sizeof是不可能支持链式表达式的,这也是和一元操作符不一样的地方。

结论:不要把sizeof当成函数,也不要看作一元操作符,把他当成一个特殊的编译预处理。

2、sizeof的用法

sizeof有两种用法:

(1)sizeof(object)

也就是对对象使用sizeof,也可以写成sizeof object 的形式。

(2)sizeof(typename)

也就是对类型使用sizeof,注意这种情况下写成sizeof typename是非法的。下面举几个例子说明一下:

int i = 2;

cout<

cout<

cout<

cout<

cout<

cout<

可以看出,加()是永远正确的选择。

结论:不论sizeof要对谁取值,最好都加上()。

3、数据类型的sizeof

(1)C++固有数据类型

32位C++中的基本数据类型,也就char,short int(short),int,long int(long),float,double, long double 大小分别是:1,2,4,4,4,8, 10。

考虑下面的代码:

unsigned影响的只是最高位bit的意义,数据长度不会被改变的。

结论:unsigned不能影响sizeof的取值。

(2)自定义数据类型

typedef可以用来定义C++自定义类型。考虑下面的问题:

结论:自定义类型的sizeof取值等同于它的类型原形。

(3)函数类型

考虑下面的问题:

int f1(){return 0;};

double f2(){return 0.0;}

void f3(){}

cout<

cout<

cout<

cout<

cout<

为是double

结论:对函数使用sizeof,在编译阶段会被函数返回值的类型取代,

4、指针问题

考虑下面问题:

可以看到,不管是什么类型的指针,大小都是4的,因为指针就是32位的物理地址。

结论:只要是指针,大小就是4。(64位机上要变成8也不一定)。

顺便唧唧歪歪几句,C++中的指针表示实际内存的地址。和C不一样的是,C++中取消了模式之分,也就是不再有small,middle,big,取而代之的是统一的flat。flat模式采用32位实地址寻址,而不再是c中的segment:offset模式。举个例子,假如有一个指向地址f000:8888的指针,如果是C类型则是8888(16位, 只存储位移,省略段),far类型的C指针是f0008888(32位,高位保留段地址,地位保留位移),C++类型的

指针是f8888(32位,相当于段地址*16 + 位移,但寻址范围要更大)。

5、数组问题

考虑下面问题:

char a[] = "abcdef";

int b[20] = {3, 4};

char c[2][3] = {"aa", "bb"};

cout<

cout<

cout<

数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是7。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。

结论:数组的大小是各维数的乘积*数组元素的大小。

这里有一个陷阱:

int *d = new int[10];

cout<

d是我们常说的动态数组,但是他实质上还是一个指针,所以sizeof(d)的值是4。

再考虑下面的问题:

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

cout<

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。??

6、向函数传递数组的问题

考虑下面的问题:

#include

using namespace std;

int Sum(int i[])

{

int sumofi = 0;

for (int j = 0; j < sizeof(i)/sizeof(int); j++) //实际上,sizeof(i) = 4

{

sumofi += i[j];

}

return sumofi;

}

int main()

{

int allAges[6] = {21, 22, 22, 19, 34, 12};

cout<

system("pause");

return 0;

}

Sum的本意是用sizeof得到数组的大小,然后求和。但是实际上,传入自函数Sum的,只是一个int 类型的指针,所以sizeof(i)=4,而不是24,所以会产生错误的结果。解决这个问题的方法使是用指针或者引用。

使用指针的情况:

int Sum(int (*i)[6])

{

int sumofi = 0;

for (int j = 0; j < sizeof(*i)/sizeof(int); j++) //sizeof(*i) = 24

{

sumofi += (*i)[j];

}

return sumofi;

}

int main()

{

int allAges[] = {21, 22, 22, 19, 34, 12};

cout<

system("pause");

return 0;

}

在这个Sum里,i是一个指向i[6]类型的指针,注意,这里不能用int Sum(int (*i)[])声明函数,而是必须指明要传入的数组的大小,不然sizeof(*i)无法计算。但是在这种情况下,再通过sizeof来计算数组大小已经没有意义了,因为此时大小是指定为6的。

使用引用的情况和指针相似:

for (int j = 0; j < sizeof(i)/sizeof(int); j++)

{

sumofi += i[j];

}

return sumofi;

}

int main()

{

int allAges[] = {21, 22, 22, 19, 34, 12};

cout<

system("pause");

return 0;

}

这种情况下sizeof的计算同样无意义,所以用数组做参数,而且需要遍历的时候,函数应该有一个参数来说明数组的大小,而数组的大小在数组定义的作用域内通过sizeof求值。因此上面的函数正确形式应该是:

#include

using namespace std;

int Sum(int *i, unsigned int n)

{

int sumofi = 0;

for (int j = 0; j < n; j++)

{

sumofi += i[j];

}

return sumofi;

}

int main()

{

int allAges[] = {21, 22, 22, 19, 34, 12};

cout<

system("pause");

return 0;

}

7、字符串的sizeof和strlen

考虑下面的问题:

cout<

cout<

cout<

cout<

cout<

cout<

a[1] = '\0';

cout<

cout<

strlen是寻找从指定地址开始,到出现的第一个0之间的字符个数,他是在运行阶段执行的,而sizeof 是得到数据的大小,在这里是得到字符串的容量。所以对同一个对象而言,sizeof的值是恒定的。string 是C++类型的字符串,他是一个类,所以sizeof(s)表示的并不是字符串的长度,而是类string的大小。strlen(s)根本就是错误的,因为strlen的参数是一个字符指针,如果想用strlen得到s字符串的长度,应该使用sizeof(s.c_str()),因为string的成员函数c_str()返回的是字符串的首地址。实际上,string类提供了自己的成员函数来得到字符串的容量和长度,分别是Capacity()和Length()。string封装了常用了字符串操作,所以在C++开发过程中,最好使用string代替C类型的字符串。

我注:关于sizeof(string),好像不同的实现返回的结果不一样:

DevCPP:4

VS2005:32

8、从union的sizeof问题看cpu的对界

考虑下面问题:(默认对齐方式)

union u

{

double a;

int b;

};

union u2

{

char a[13];

int b;

};

union u3

{

char a[13];

char b;

};

cout<

cout<

都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u来说,大小就是最大的double类型成员a了,所以sizeof(u)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4,也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。

结论:复合数据类型,如union,struct,class的对齐方式为成员中对齐方式最大的成员的对齐方式。

顺便提一下CPU对界问题,32的C++采用8位对界来提高运行速度,所以编译器会尽量把数据放在它的对界上以提高内存命中率。对界是可以更改的,使用#pragma pack(x)宏可以改变编译器的对界方式,默认是8。C++固有类型的对界取编译器对界方式与自身大小中较小的一个。例如,指定编译器按2对界,int类型的大小是4,则int的对界为2和4中较小的2。在默认的对界方式下,因为几乎所有的数据类型都不大于默认的对界方式8(除了long double),所以所有的固有类型的对界方式可以认为就是类型自身的大小。更改一下上面的程序:

#pragma pack(2)

union u2

{

char a[13];

int b;

};

union u3

{

char a[13];

char b;

};

#pragma pack(8)

cout<

cout<

由于手动更改对界方式为2,所以int的对界也变成了2,u2的对界取成员中最大的对界,也是2了,所以此时sizeof(u2)=14。

结论:C++固有类型的对界取编译器对界方式与自身大小中较小的一个。

9、struct的sizeof问题

因为对齐问题使结构体的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;

};

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

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

10、不要让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 用法介绍

sizeof使用介绍

本文主要包括二个部分,第一部分重点介绍在VC中,怎么样采用sizeof来求结构的大小,以及容易出现的问题,并给出解决问题的方法,第二部分总结出VC中sizeof的主

要用法。

1、sizeof应用在结构上的情况

请看下面的结构:

struct MyStruct

{

double d1;

char d2;

int in

};

对结构MyStruct采用sizeof会出现什么结果呢?

sizeof(MyStruct)为多少呢?也许你会这样求:

sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

但是当在VC中测试上面结构的大小时,会发现sizeof(MyStruct)为16。

其实,这是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 d1;

char d2;

int in;

};

为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个

成员d1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double )的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员d1分配

空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char

)的倍数,所以把d1存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof( char)=1个字节;接下来为第三个成员in分配空间,这时下一个可以分配的地址对于

结构的起始地址的偏移量为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自动填充的,没有放任何有意义的东西。

VC对结构的存储的特殊处理确实提高CPU存储变量的速度,但是有时候也带来了一些

麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以设定变量的对齐方式。

VC中提供了#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量

存放的起始地址的偏移量有两种情况:

第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式

第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默

认的对齐方式。//也就是取其中较小者作为对齐方式

结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占

用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数; 否

则必须为n的倍数。

下面举例说明其用法。

#pragma pack(push) //保存对齐状态

#pragma pack(4)//设定为4字节对齐

struct test

{

char m1;

double m4;

int m3;

};

#pragma pack(pop)//恢复对齐状态

以上结构的大小为16,下面分析其存储情况,首先为m1分配空间,其偏移量为0,满

足我们自己设定的对齐方式(4字节对齐),m1占用1个字节。接着开始为m4分配空间,这时其偏移量为1,需要补足3个字节,这样使偏移量满足为n=4的倍数(因为sizeof (double)大于n),m4占用8个字节。接着为m3分配空间,这时其偏移量为12,满足为

4的倍数,m3占用4个字节。这时已经为所有成员变量分配了空间,共分配了16个字节,满足为n的倍数。如果把上面的#pragma pack(4)改为#pragma pack(16),那么

我们可以得到结构的大小为24。

2、 sizeof用法总结

在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个总结。

A.参数为数据类型或者为一般变量。例如sizeof(int),sizeof(long)等等。这种

情况要注意的是不同系统系统或者不同编译器得到的结果可能是不同的。例如int类型在16位系统中占2个字节,在32位系统中占4个字节。

B.参数为数组或指针。下面举例说明.

int a[50]; //sizeof(a)=4*50=200; 求数组所占的空间大小

int *a=new int[50];// sizeof(a)=4; a为一个指针,sizeof(a)是求指针

//的大小,在32位系统中,当然是占4个字节。

C.参数为结构或类。Sizeof应用在类和结构的处理情况是相同的。但有两点需要

注意,第一、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关。

第二、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。

下面举例说明,

Class Test{int a;static double c};//sizeof(Test)=4.

Test *s;//sizeof(s)=4,s为一个指针。

Class test1{ };//sizeof(test1)=1;

D.参数为其他。下面举例说明。

int func(char s[5]);

{

cout<

//数的参数在传递的时候系统处理为一个指针,所

//以sizeof(s)实际上为求指针的大小。

return 1;

}

sizeof(func(“1234”))=4//因为func的返回类型为int,所以相当于

//求sizeof(int).

sizeof Operator Operators .

sizeof expression

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 .

The expression is either an identifier or a type-cast expression (a type specifier enclosed in parentheses).

When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment. When applied to a statically dimensioned array, sizeof returns the size of the entire array. The sizeof operator cannot return the size of dynamically allocated arrays or external arrays.

1.// Example of the sizeof keyword

2.size_t i = sizeof( int );

3.

4.struct align_depends {

5.char c;

6.int i;

7.};

8.size_t size = sizeof(align_depends); // The value of size depends on

9.// the value set with /Zp or

10.// #pragma pack

11.

12.int array[] = { 1, 2, 3, 4, 5 }; // sizeof( array ) is 20

13.// sizeof( array[0] ) is 4

14.size_t sizearr = // Count of items in array

15.sizeof( array ) / sizeof( array[0] );

1. 用法

1.1 sizeof和new、delete等一样,是关键字,不是函数或者宏。

1.2 sizeof返回内存中分配的字节数,它和操作系统的位数有关。例如在常见的32位系统中,int类型占4个字节;但是在16位系统中,int类型占2个字节。

1.3 sizeof的参数可以是类型,也可以是变量,还可以是常量。对于相同类型,以上3中形式参数的sizeof返回值相同。

Cpp代码

1.int a;

2.sizeof(a); // = 4

3.sizeof(int); // = 4

4.sizeof(1); // = 4

1.4 C99标准规定,函数、不能确定类型的表达式以及位域(bit-field)成员不能被计算sizeof值,即下面这些写法都是错误的。

Cpp代码

1.void fn() { }

2.sizeof(fn); // error:函数

3.sizeof(fn()); // error:不能确定类型

4.struct S

5.{

6.int a : 3;

7.};

8.S sa;

9.sizeof( sa.a ); // error:位域成员

1.5 sizeof在编译阶段处理。由于sizeof不能被编译成机器码,所以sizeof的参数不能被编译,而是被替换成类型。

Cpp代码

1.int a = -1;

2.sizeof(a=3); // = sizeof(a) = sizeof(int) = 4

3.cout<

2. 在32位系统中不同类型的内存分配

2.1 基本类型

Cpp代码

1.sizeof(int); // = 4

2.sizeof(double); // = 8

3.sizeof(char); // = 1

4.sizeof(bool); // = 1

5.sizeof(short); // = 2

6.sizeof(float); // = 4

7.sizeof(long); // = 4

2.2 指针

指针在32位系统中占4个字节。

Cpp代码

1.sizeof(int *); // = 4

2.sizeof(double *); // = 4

3.sizeof(char *); // = 4

2.3 数组

2.3.1 数组的sizeof返回整个数组所占的字节数,即(数组元素个数×每个元素所占字节)。

Cpp代码

1.int ai[] = {1, 2};

2.sizeof(ai); // = 2*4 = 8

2.3.2 常量字符串与字符数组的内存分配方式相同。

Cpp代码

1.char ac[] = "abcd"; //注意数组末尾的字符串终结符'\0'

2.sizeof(ac); // = 5*1 = 5

3.sizeof("abcd"); // = 5*1 = 5

2.3.3 数组和指针所占的字节数不同,应注意区分。

1.int *pi = new int[10]; //这是指针

2.sizeof(pi); // = 4

3.

4.int ai[10];

5.int *p = ai; //这还是指针

6.sizeof(p); // = 4

7.

8.double* (*a)[3][6]; //看成(double *) (*a)[3][6],即一个3×6的二维数组,数组元素

为指针,指向double类型。

9.sizeof(a); // = 4,a为指向上述二维数组的指针

10.sizeof(*a); // = sizeof(double *)*3*6 = 72,*a表示上述二维数组

11.sizeof(**a); // = sizeof(double *)*6 = 24,**a即*(*a),表示double*[6],是元素

为double指针的一维数组。

12.sizeof(***a); // = sizeof(double *) = 4,表示上述一维数组中的第一个元素,元素

类型为double指针。

13.sizeof(****a); // = sizeof(double) = 8,表示上述数组首元素指向的double类型。

2.3.4 函数形式参数中的数组会蜕变为指针,原因是数组参数“传址调用”,调用者只需将实参的地址传递过去。有一种情况例外,那就是参数是指向数组的指针。

1.void acf(char p[3]) //参数类型是int[],表示指向int的指针

2.{

3.sizeof( p ); // = 4

4.}

5.void aif(int p[]) //参数类型是int[],表示指向int的指针

6.{

7.sizeof( p ); // = 4

8.}

9.void pif(int (*p)[6]) //参数类型是int (*)[6],表示指向int数组的指针

10.{

11.sizeof( p); // = 4

12.sizeof( *p ); // = sizeof(int)*6 = 24

13.}

14.void ppf(int *p[6]) //参数类型是int *[],表示指向int指针的指针

15.{

16.sizeof( p ); // = 4

17.sizeof( *p ); // = 4

18.}

2.4. 类和结构体的内存分配。

2.4.1 空类或空结构体占一个字节。

Cpp代码

1.class CEmpty { };

2.sizeof(CEmpty); // = 1

3.

4.struct SEmpty { };

5.sizeof(SEmpty); // = 1

2.4.2 非空类和结构体所占字节为所有成员占字节的和,但是不包括成员函数和静态成员所占的空间。

Cpp代码

1.class CInt : public CEmpty {

2.int i;

3.};

4.sizeof(CInt); // = 4;

5.

6.class CFunc {

7.void f() {}

8.};

9.sizeof(CFunc); // = 1;

10.

11.struct SInt : SEmpty {

12.static int i;

13.};

14.sizeof(SInt); // = 1;

2.4.3 字节对齐

为了加快计算机的取数速度,编译器默认对内存进行字节对齐。对结构体(包括类)进行字节对齐的原则是:

1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

2)结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

3)结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

Cpp代码

1.struct SByte1

2.{

3.double d; // 偏移量0~7

4.char j; // 偏移量8

5.int a; // 偏移量12~15,由于9不能整除4,故先填充9~11

6.};

7.sizeof(SByte1); // = 16

8.

9.struct SByte2

10.{

11.char j; // 偏移量0

12.double d; // 偏移量8~15,由于1不能整除8,故先填充1~7

13.int a; // 偏移量16~19

14.};

15.sizeof(SByte2); // = 24,为了凑成8的倍数,填充20~23

另外,可以通过#pragma pack(n)来设定变量以n字节对齐方式。

/*如何使用c/c++中的对齐选项

vc6中的编译选项有/Zp[1|2|4|8|16] ,/Zp1表示以1字节边界对齐,相应的,/Zpn表示以n字节边界对齐。

n字节边界对齐的意思是说,一个成员的地址必须安排在成员的尺寸的整数倍地址上或者是n的整数倍地址上,取它们中的最小值。

也就是:

min ( sizeof ( member ), n)

实际上,1字节边界对齐也就表示了结构成员之间没有空洞。*/

Cpp代码

1.#pragma pack(push) //保存对齐状态

2.#pragma pack(4) //设定为4字节对齐

3.class CByte

4.{

5.char c; //偏移量0

6.double d; //偏移量4~11,由于1不能整除4,故先填充1~3

7.int i; //偏移量12~15

8.};

9.#pragma pack(pop) //恢复对齐状态

10.sizeof(CByte); // = 16

2.4.4 位域

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可。

为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。

2.4.4.1 位域以比特位作为单位,其长度不能大于一个字节。一个位域必须存储在同一个字节中,如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。??

Cpp代码

1.struct SBit1

2.{

3.

4.char a : 3;

5.char b : 4;

6.char c : 5;

7.};

8.sizeof(SBit1); // = (3+4+1+5+3) bits = 2 bytes

SBit1:| a×3+b× 4 + #×1|c× 5 + #×3|

2.4.4.2 使用空域可以有意使某位域从下一单元开始,但是空域不能使用。

Cpp代码

1.struct SBit2

2.{

3.char a : 3;

4.char: 0; // 空域

5.char b : 4;

6.char c : 5;

7.};

8.sizeof(SBit2); // = (3+4+1+5+3) bits = 3 bytes

SBit2:| a×3 +#× 5| b× 4 +#× 4|c× 5 +#× 3|

2.4.4.3 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式。

Cpp代码

1.struct SBit3

2.{

3.char a : 3;

4.short b : 4;

5.char c : 5;

6.};

7.sizeof(SBit3); // = 6 bytes,由于相邻位域类型不同,在VC6中其sizeof为6,在

Dev-C++中为2。

SBit3(不压缩):| a×3 |#×8|b× 4 +#×4| #×8| c ×5+#×3 | #×8|

SBit3(压缩):| a×3 +b×4+#×1|c×5+#×3|

2.4.4.4 如果位域字段之间穿插着非位域字段,则不进行压缩。

Cpp代码

1.struct SBit4

2.{

3.int a : 3;

4.int b : 4;

5.int c;

6.};

7.sizeof(SBit4); // = 8 bytes

SBit4:| a×3 +b×4+#×1| #×8| #×8| #×8| c×8| c×8 | c×8| c×8|

2.4.4.5 整个结构体的总大小为最宽基本类型成员大小的整数倍。

Cpp代码

1.struct SBit5

2.{

3.int a : 3;

4.int b;

5.int c : 5;

6.};

7.sizeof(SBit5); // = 12 bytes

SBit5:| a×3 +#×5| #×8| #×8| #×8| b×8| b×8| b×8 | b×8| c×5+#×3| #×8| #×8| #×8|

2.5 联合

联合表示若干数据成员取其一,故以叠加方式分配内存,所占字节数为最大数据成员所占的字节数。

行测资料分析技巧:你掉进易错陷阱里了吗.doc

行测资料分析技巧:你掉进易错陷阱里了吗公务员行测考试主要是考量大家的数学推理能力和逻辑分析能力,下面由我为你精心准备了“行测资料分析技巧:你掉进易错陷阱里了吗”,持续关注本站将可以持续获取更多的考试资讯! 行测资料分析技巧:你掉进易错陷阱里了吗 资料分析这种题型复习过的同学都知道不难,但还是总是出错,正确率提升不上去,大部分原因都是因为掉入了资料分析的易错陷阱了,所以每次做完题后对错误的总结是非常重要的,而且你发现了这些易错陷阱后,反而能利用它快速把题目正确答案选出来,这里通过例题给大家做一下介绍。 一、多几倍/是几倍 【例1】202X年,全国房地产开发总投资额为120264亿元,同比增长9.5%。其中,东部地区投资额占比53.5%,西部地区投资额占比 21.6%,中部地区投资额占比20.9%,东北地区投资额占比4.0%。 问题:202X年,东部地区房地产开发投资额比中部地区多多少倍? A.2.56 B.2.33 C.1.56 D.1.42 【答案】C。根据“东部地区投资额占比53.5%,中部地区投资额占比20.9%”,可得东部地区比中部地区多 所以正确答案为C项。但很多同学会看错问题“多几倍”,而求成了“是几倍”,导致误选A项。这就提醒大家在做倍数的题目时看清“多几倍”或“是几倍”再去求解。如果有细心的同学也能发现出题人正是想在这里设置陷阱,所以设置了A项,如果看出“A项-1=C项”的情况下,又知道所求为“多几倍”的前提下,可直接大胆选C项。 区分:多几倍=是几倍-1 二、增长最快最慢/增长最多最少 【例2】

问题:202X年上半年,河南省规模以上工业生产主要产品中同比增长最快的产品,其6月份的产量比增长最慢的产品: A.多20.83万吨 B.少20.83万吨 C.多881.54万吨 D.少881.54万吨 【答案】B。由图2可知,202X年上半年同比增长率最低的产品为十种有色金属(-1.4%),增长率最高的产品为化学纤维(13.5%)。由图1可知,202X年6月份,十种有色金属的产量为36.64万吨,化学纤维的产量为15.81万吨。则所求为15.81-36.64=-20.83万吨。即202X年6月化学纤维比十种有色金属的产量少20.83万吨,本题选择B项。有很多同学误以为增长最快是增长量最大,增长最慢是增长量最小,算了半天误选了C项。这就提醒大家要看清楚比较的是增长量还是增长率。 区分:增长最快或最慢是找增长率的最大或最小值;增长最多或最少是找增长量的最大或最小值。 三、变化幅度/增幅 【例3】 问题:202X年7月,以下限额以上单位商品零售额变化幅度最大的是: A.汽车类 B.建筑及装潢材料类 C.通讯器材类 D.金银珠宝类 【答案】A。由表格可知,202X年7月,限额以上单位商品零售额中,汽车类下降2.6%,建筑及装潢材料类上升0.4%,通讯器材类上升1.0%,金银珠宝类下降1.6%,变化幅度最大的为汽车类限额以上单位商品零售额,故本题选择A项。变化幅度在此题中指的是增长幅度的绝对值,即增长率的绝对值,不看正负,很多同学容易误选C项,就是因为没有区分清楚变化幅度和增长幅度的区别。 四、百分数/百分点

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

第二章习题 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<

资料分析解题中常见的陷阱有一类为时间表述陷阱

资料分析解题中常见的陷阱有一类为时间表述陷阱。在此中公教育专家为大家讲解时间表述陷阱,在深入分析命题人所设陷阱的特点的基础上,提出应对策略,帮助考生走出误区,提高正确率。 1.时间点陷阱 陷阱设置 1、题干中的时间与材料中涉及的时间相关但不相同; 2、选项中给出相关时间点的数据混淆视听。 示例:材料中给出的是“2005年”的相关数据,题干要求的是“2004年”或“2003年”的相关问题,选项当中设置了“2005年”的相关数据作为干扰选项。 例题1: 国家统计局对全国31个省(区、市)6.8万个农村住户的抽样调查结果显示,2005年上半年农民现金收入人均1586元,扣除价格因素影响,实际增长12.5%,增速比去年同期提高1.6个百分点。 2004年上半年农民人均现金收入,扣除价格因素影响,实际增长()。 A.12.5% B.13.1% C.14.1% D.10.9% 中公解析:此题答案为D。方法一,因为2005年的实际增长率比2004年高,那么2004年的实际增长率肯定要低于12.5%,选项中只有D符合条件,所以可以直接选择D。 方法二,因为2005年的“实际增长12.5%,增速比去年同期提高1.6个百分点”,所以2004年实际增长12.5%-1.6%=10.9%。 陷阱分析:注意时间点混淆。题干所问的是“2004年上半年”,而材料中所给的是2005年上半年,很可能会混淆而误选A。 2.时间段陷阱 陷阱设置 1、题干中的时间段与材料中涉及的时间段相关但不相同; 2、选项中给出原文时间段的相关数据混淆视听。 示例:材料中给出的是“2004-2010年”相关数据,题干要求的是“2005-2010年”的相关问题,选项当中给出了“2004-2010年”的相关数据作为干扰选项。 例题2: 全国1998年至2006年地质灾害造成直接经济损失情况图

案例名称:天堂里的烦恼

案例名称:天堂里的烦恼 内容: 作者:忻榕(Katherine Xin)弗拉迪米尔·普奇克(Vladimir Pucik) 中美合资企业众联针织有限公司成立10周年的庆典即将举行,总经理迈克·格里夫打电话给美国总部的老板比尔汇报发言提纲,并希望借机能得到比尔的祝贺。不想比尔对合资公司的现有业绩根本不满意,在他看来,一个成立了10年的合资公司却只有4%的投资回报率委实令人失望,他的期望值是20%。为了达到这一目标,他建议比尔要大刀阔斧地裁员,推行生产自动化,提高产品质量。而恰恰在这个时候,中方常务副总经理李勤林交给迈克一份新提案,建议众联收购一家亏损的乡镇企业华缨公司,以扩大公司规模,创立新品牌。虽然在此之前的10年中,合资公司已经收购了3个亏损的企业,并使它们扭亏为盈;但是,迈克断定比尔不会再同意这次收购,比尔对扩张根本没兴趣,他要的是尽快提高投资回报率。左右为难的迈克意识到,如果双方谈不拢,自己在中国的经理生涯可能会黯然收场。 忧心忡忡的迈克强作欢颜出现在庆典会场。中方将这次庆典当成是一个总结过去、开拓未来、鼓舞员工士气的大好机会,他们还请来了合资公司所在地的昆海市市府领导。在庆典上,无论是公司中方代表还是当地政府的致辞都盛赞众联公司10年来取得的辉煌成就,尤其是副市长,对合资公司10年来为推动当地经济发展和就业形势所做的巨大贡献褒扬有加。迈克的中方老搭档李勤林也在庆典上向大家公布了酝酿之中的新收购计划和树立众联品牌的宏伟目标,迈克认为李勤林这样在公开场合给大家一种期许让他陷入非常被动的境地。 回到家的迈克向妻子琳达吐苦水,琳达对丈夫的处境非常理解,她认为美国总部的人根本不了解中国的国情。在中国生活了几年的他们已经对这个文明古国的文化有了初步了解,由此对中国人的某些观念和行为方式也持理解态度。更重要的是,因为丈夫是外籍经理,他们一家在中国过着优裕的生活,而这是他们在美国无法享受到的。迈克希望他们即将考察的华缨公司不至于太糟,这样他在中国的幸福生活还有可能继续下去。 华缨公司对被收购表现出极大的热忱。在迈克一行人考察华缨公司时,面对着传统和现代、先进和落后交织在一起的场景,迈克再次陷入困惑。公司高管人员对新技术的学习热情以及对市场的熟悉程度令他叹服,但车间中陈旧的机器和落后的生产管理流程又令他失望。 迈克是应该向比尔力荐这桩收购,还是将比尔的态度向中方摊牌? 专家观点

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对象中。必须强调一点,在

最新行测资料分析技巧:你掉进易错陷阱里了吗

资料分析这种题型复习过的同学都知道不难,但还是总是出错,正确率提升不上去,大部分原因都是因为掉入了资料分析的易错陷阱了,所以每次做完题后对错误的总结是非常重要的,而且你发现了这些易错陷阱后,反而能利用它快速把题U正确答案选出来,这里通过例题给大家做一下介绍。 一、多儿倍/是儿倍 【例112018年,全国房地产开发总投资额为120264亿元,同比增长9. 5%。其中,东部地区投资额占比53. 5%,西部地区投资额占比21.6%,中部地区投资额占比20. 9%,东北地区投资额占比4.0%0 问题:2018年,东部地区房地产开发投资额比中部地区多多少倍? A. 2. 56 B. 2. 33 C. 1. 56 D. 1. 42 【答案】C。根据“东部地区投资额占比53. 5%,中部地区投资额占比20.9%”,可得东部地区比中部地区多 所以正确答案为C项。但很多同学会看错问题“多儿倍”,而求成了“是儿倍”,导致误选A项。这就提醒大家在做倍数的题U时看清“多儿倍”或“是儿倍”再去求解。如果有细心的同学也能发现出题人正是想在这里设置陷阱,所以设置了A项,如果看出“A项-1二C项”的悄况下,乂知道所求为“多儿倍”的前提下,可直接大胆选C项。 区分:多儿倍二是儿倍-1 二.增长最快最慢/增长最多最少 【例2】 问题:2019年上半年,河南省规模以上工业生产主要产品中同比增长最快的 产品,其6月份的产量比增长最慢的产品: A.多20. 83万吨 B.少20. 83万吨 C.多881. 54万吨 D.少881. 54万吨 【答案】B。山图2可知,2019年上半年同比增长率最低的产品为十种有色金属(-1.4%),增长率最高的产品为化学纤维(13.5%)。山图1可知,2019年6 月份,十种有色金属的产量为36. 64万吨,化学纤维的产量为15. 81万吨。则所求为15. 81-36. 64-20. 83万吨。即2019年6月化学纤维比十种有色金属的产量少20. 83万吨,本题选择B项。有很多同学误以为增长最快是增长量最大,增长最慢是增长量最小,算了半天误选了C项。这就提醒大家要看清楚比较的是增长量还是增长率。

中国城市旅游集散中心模式的对比分析(20200704183947)

中国城市旅游集散中心模式的对比分析 摘要: 中国的大型城市为了解决巨量散客出游的问题,由 上海率先建立了“旅游集散中心” 的散客旅游服务模式目前已经被证明适用于中国现行体制下的特大型城市,符合 城市旅游发展之需。国内其它许多城市也跟着建设了名为“旅游集散中心”的机构,但是仔细比较可以发现,这些机构虽然表面名称一致,在体制和运行机制上却存在较大差异,实际运行效果也很是不同。文章比较分析了上海、杭州、成都、北京以及其它若干城市的旅游集散中心在体制、机制与运行效果上的异同点,并探讨了旅游集散中心的本质特征与形成机制,强调了它的准公共产品属性。 关键词: 城市旅游; 散客; 旅游集散中心; 旅游服务体系收稿日期: 2009-08-30; 修订日期: 2009-10-20 基金项目: 北京市哲学社会科学“十一五” 规划项目《北京散客旅游服务体系与管理模式》(06BaZH018) 作者简介: 徐菊凤(1965-), 女,北京联合大学旅游学院现代休闲方式与旅游发展研究所副研究员,博士。研究方向:文化旅游、休闲旅游、旅游消费行为。赵晓燕(1959-), 女,北京联合大学旅游学院休闲与旅游管理系市场营销专业负责人, 副 教授。研究方向: 旅游市场营销、旅游经济理论。 散客潮与中国城市旅游集散中心的形成

1. 巨量散客考验中国城市旅游服务体系 统计数据表明,北京和上海已经成为国际上少有的特大型旅游城市。2007 年,北京接待的国内旅游者和入境旅游者数量,分别达到9352 万人次和435万人次,如果加上本市居民在京旅游数4912 万人次,则北京接待的全部旅游者数量已达到1.4264 亿人次。上海的数字也接近于这一水平:2007 年接待的国内旅游者(含本市居民在沪旅游)1.02 亿人次,国际旅游者665.6 万人次,合计 1.0866 亿人次(注:北京和上海的旅游接待数量,分别见:人民网2008 年 2 月27 日《北京市2007 年旅游业发展概况》,以及人民网2008 年 4 月1 日《上海旅游市场2007 大盘点》两篇报道。)。这种规模的游客接待量,已经远远超过巴黎、纽约等国际著名大都市,后二者近年来每年游客接待量分别为5000 万人次左右和4500 万人次左右(注: 有关纽约的数字,见新华网2006 年12 月29 日《纽约游客人次再创新高近4400 万人次》;有关巴黎的数字,也曾出现于网上一篇报道,出自巴黎市长之口。)。因此,可以认为, 我国的北京和上海已属于世界少有的特大型旅游城市。 更值得关注的是,如此庞大的旅游客流,大多以散客的方式(个人或与亲友结伴)到访。中国国内旅游抽样调查资料显 示,2006 年城镇居民国内游客中,以散客方式出游的占 71.7%[1], 北京和上海的散客接待率也接近于这一百分比。尽管这一散客比例还未像某些欧美发达国家那样达到80%~90%, 但显而

美国电影保护局国家电影

美国国家电影保护局从1989年开始收集好莱坞经典影像作品,旨在保护曾对美国文化产生实质影响的影片。这些影片未必都是当年奖项的宠儿,也未必都是卖座影片,但其影像风格、演员在表演方法上的贡献、电影技术的创新、影片内容上的里程碑意义、放映后反响呈两极的争议电影,却都是衡量影片是否入选的判断标准。在历时21年的收藏过程中,诸多诞生于上世纪20年代的默片,都被进行了精心的修复和严格的保管,使得一些即将消失的电影资料得以流传下去。保护局目前(至2011年)已经保存了575部题材各异的电影作品。从1989年起,美国国会图书馆每年会遴选25部最能代表本国文化和电影水平的作品归档,以展现美国社会的历史沿革,被国会图书馆永久保存。 美国国家电影保护局-电影名录(一)(2006-03-10 13:18:39)转载▼ 作为资料收藏,有一定的看片指导作用。 1989 01 Best Years of Our Lives, The (1946) 黄金时代 02Casablanca (1942) 卡萨布兰卡 03 Citizen Kane (1941) 公民凯恩 04 Crowd, The (1928) 群众 05 Dr. Strangelove or: How I Learned to Stop Worrying and Love the Bomb (1964) 奇爱博士 06 General, The (1927) 将军号 07 Gone with the Wind (1939) 乱世佳人 08 Grapes of Wrath, The (1940) 愤怒的葡萄 09 High Noon (1952) 正午 10 Intolerance (1916) 党同伐异 11 Learning Tree, The (1969) 知识树 12 Maltese Falcon, The (1941) 枭巢喋血战 13 Modern Times (1936) 摩登时代 14 Mr. Smith Goes to Washington (1939) 史密斯先生游美京 15 Nanook of the North (1922) 北方的纳努克 16 On the Waterfront (1954) 码头风云 17 Searchers, The (1956) 搜索者 18 Singin'' in the Rain (1952) 雨中曲 19 Snow White and the Seven Dwarfs (1937) 白雪公主 20 Some Like It Hot (1959) 热情似火 21 Star Wars (1977) 星球大战 22 Sunrise (1927) 日出 23 Sunset Blvd. (1950) 日落大道 24 V ertigo (1958) 迷魂记 25 Wizard of Oz, The (1939) 绿野仙踪 1990 01 All About Eve (1950) 彗星美人 02 All Quiet on the Western Front (1930) 西线无战事 03 Bringing Up Baby (1938) 育婴奇谭

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;

2018国家公务员行测资料分析三大陷阱

2018国家公务员行测资料分析三大陷阱根据工作安排,中央机关及其直属机构2018年度公务员招考报名时间为10月30日至11月8日,公共科目笔试时间为12月10日,届时请广大考生关注。为帮助更多考生积极备考2018湖南省公务员考试,湖南华图为你准备2018湖南公务员考试备考资料,希望对你有所帮助!! 1.时间陷阱 这类题目往往给出与原文相近的时间、日期,并在选项中给出与原文的数据以混淆视听,扰乱考生视线。 【例题】2014年我国研究与试验发展(R&D)经费支出13312亿元,比上年增长12.4%,同比下降2.6个百分点。 问题:2012年我国研究与试验发展(R&D)经费支出为多少亿元? A.10299 B.13312 C.11843 D.12159 【陷阱解析】时间陷阱。材料给出的是2014年的数据,题目求的是2012年的量,考查求隔年的量。考生往往由于大意可能会计算2013年的量,从而误选成成C,正确答案为A。解法: ,选择最接近的A选项。 【解答】时间陷阱是资料分析中最常见的陷阱之一。考生遇

到这种题目时应本着小心谨慎的态度,答案直接显示在题干中的情况应当引起足够的重视,不可抱着捡了现成便宜的心理,草草作答。对于题干中出现的多个时间或者有百分点的情况,一定弄清楚题目所求的时间,不可掉以轻心。 2.单位陷阱 在资料分析题目中,常会出现一些单位混用的情况,如千米与里,公顷与亩,万与亿,吨与千克,;材料中给出某个单位,但在题干或选项中使用的却是另一个单位,这即是单位陷阱。 【例题】2013年,全国商品房销售面积130551万平方米,比上年增长17.3%,增速比1~11月份回落3.5个百分点,比2012年提高15.5个百分点;其中,住宅销售面增长17.5%,办公楼销售面积增长27.9%,商业营业用房销售面积增长9.1%。商品房销售额81428亿元,增长26.3%,增速比1~11 月份回落4.4个百分点,比2012年提高16.3个百分点;其中,住宅销售额增长26.6%,办公楼销售额增长35.1%,商业营业用房销售额增长18.3%。 问题:2011年全国商品房销售面积约为多少亿平方米? A.92000 B.109000 C.9.8 D.10.9 【陷阱解析】单位陷阱。材料给出的单位是万平方米,问题的单位是亿平方米,正确答案为D,学生如果没有看准单位很容易误选B选项。解法:有题干知,2012年增长率为17.3%-15.5%=1.8%,则所求为:

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))。

总裁班课件案例2:天堂里的烦恼--续

案例2:天堂里的烦恼 中美合资众联针织有限公司的合作双方对企业发展各有打算,这使身为总经理的迈克心绪不安:不管他如何选择,双方合作都有可能结束,这也就意味着他要告别在中国的惬意生活了…… ■忻榕(Katherine Xin) 弗拉迪米尔·普奇克(Vladmir Pucik) 上海,外滩,迈克·格里夫的办公室。紫红色的天鹅绒窗幔在晨风中曳动着,从高大的落地窗望出去,浦江两岸的景色尽收眼底。一边是风格各异,经历了上百年风雨的磨蚀却依然巍峨屹立的西洋建筑,一边是交相辉映、鳞次栉比的摩天大楼。但是此刻,迈克却没有心思欣赏这样的景致,他在屋子里来回踱着,手里攥着中方合作伙伴递来的收购提案。如果他没记错,这应该是第四次收购了吧,怎么偏偏是在这时候?迈克有些心烦意乱,脑子里一遍又一遍地回放着一大早和美国总部打电话的情景。 早上一进办公室,迈克就给远在美国俄亥俄州(Ohio)的公司总部挂了个电话。今天中午合资公司要举行成立10周年庆典,迈克作为外方代表要发言。他希望能从总部老板比尔·温德勒那儿听到几句祝贺的话,到时也算对他的中方同事有个交待。电话里,他三言两语地汇报了一下自己的发言提纲,无非就是勉励合资公司取得的成就的话,但他感到电话那端的老板似乎没什么兴致,而且有些越来越不耐烦。通话还不到5分钟,比尔就截过他的话说:“事情没你想像得那么好,你别高兴得太早了。” 比尔提醒迈克,他希望哈特兰纺织公司在中国的投资今年能有更多的赢利。“4%的投资回报率也太可怜了吧。”他说,“我们在那儿已经呆了10年了,迈克,我们现在的回报率应该比这高得多才对。”比尔的期望值是20%,他认为只要提高自动化程度,增加生产效率,达到这个目标不成问题。在比尔看来,和合资公司目前取得的效益相比,公司着实显得有些人员过剩,他认为至少可以裁去1,200人。“这个问题得赶紧解决!”他在撂下电话前斩钉截铁地说。 迈克了解他老板的脾气——不容别人说“不”,但他也知道中方伙伴绝对不会同意裁员,他无法说服他们接受比尔这个大刀阔斧的建议。看样子,他在中国的5年总经理生涯就要黯然地画上一个句号了。俄亥俄传来的声音在迈克的脑海里盘旋着,挥之不去。他忐忑不安地揣测着:“比尔该不是在警告我6个月之后不再与我续签聘用合同了吧?” 迈克正竭力想从上午的电话阴霾中摆脱出来,更烦心的事儿来了。合资公司中方一号人物、常务副总经理李勤林派人送来了最新的收购提案。李勤林是公司元老,说话很有份量。像讨论前几次收购时一样,迈克再度感受到了一股无法抗拒的压力。这一次,中方还是给了他明确的信号——双方能否继续愉快合作全要看迈克是否支持企业扩张和增加就业岗位的计划。这个提案来得太不是时候了,迈克心里埋怨着,比尔最不赞成的就是为增长而牺牲利润了。 厚重的柚木门上传来一阵敲门声,打断了他的思绪。走进来的是冯晨,迈克的翻译兼助理。他轻声告诉迈克,司机已经开着车在外面等候了。 加强友好合作 车子飞驶在上海通往昆海市的高速公路上,不一会儿就来到了桂垅大酒店,在被称作人

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

常用算法设计方法 要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。算法数据结构是程序的两个重要方面。 算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。指令正确地描述了要完成的任务和它们被执行的顺序。计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。 通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。其次是算法所需要的存储空间少和执行更快等。 算法设计是一件非常困难的工作,经常采用的算法设计技术主要有迭代法、穷举搜索法、递推法、贪婪法、回溯法、分治法、动态规划法等等。另外,为了更简洁的形式设计和藐视算法,在算法设计时又常常采用递归技术,用递归描述算法。 一、迭代法 迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为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’输出结束 运算符 优先级 结合方式 优先级:高->低 逻辑运算符 ! 右->左 算术运算符 ++ -- + - * 右->左 * / % + - 左->右 关系运算符 <= < >= > == != 左->右 逻辑运算符 && || 左-> 右 条件表达式 ?: 右->左 赋值运算符 *= /= %= += - = = 右->左

国家影评人协会100部必看佳片

国家影评人协会100部必看佳片 Jay Carr 编辑的《The A List: The National Society of Film Critics' 100 Essential Films》一书对“国家影评人协会100部必看佳片”有深具洞察里力和尖锐的评论文章。根据该书内容,“协会基于影片的内在价值,在电影艺术发展过程中的作用以及对文化与社会的影响选出了这100部必看影片。” 1. 2001: A Space Odyssey (1968) 2001太空漫游 2. 42nd Street (1933) 第四十二街 3. Quatre cents coups, Les (1959) 四百击 4. All About Eve (1950) 彗星美人 5. Annie Hall (1977) 安妮·霍尔 6. Popiól i diament (1958) 灰烬钻石 7. Atalante, L' (1934) 亚特兰大号 8. Bank Dick, The (1940) 9.Bronenosets Potyomkin (1925) 波坦金战舰 10. Birth of a Nation, The (1915) 一个国家的诞生 11. Blowup (1966) 春光乍泄 12. Bonnie and Clyde (1967) 雌雄大盗 13. à bout de souffle (1960) 筋疲力尽 14. Bringing Up Baby (1938) 育婴奇谭 15. Casablanca (1942) 卡萨布兰卡 16. Chant of Jimmie Blacksmith, The (1978) 17. Enfants du paradis, Les (1945) 天上人间 18. Chinatown (1974) 唐人街 19. Citizen Kane (1941) 公民凯恩 20. Close Encounters of the Third Kind (1977) 第三类接触 21. Ostre sledované vlaky (1966) 严密看管的列车(已下载最低版本) 22. Nema-ye Nazdik (1990) 特写(伊朗剧情犯罪) 10.23. Dance, Girl, Dance (1940) 24. "Dekalog" (1987) (mini) 十诫 25. Journal d'un curé de campagne (1951) 乡村牧师日记(已下载最低版本) 26. Diner (1982) 餐馆 27. Do the Right Thing (1989) 为所应为(循规蹈矩) 28. Dolce vita, La (1960) 甜蜜的生活 29. Double Indemnity (1944) 双重保险 30. Duck Soup (1933) 鸭羹 31. Easy Rider (1969) 逍遥骑士 32. Enter the Dragon (1973) 龙争虎斗 33. The Entertainer, (1960) 艺人 34. Exorcist, The (1973) 驱魔人 35. Faces (1968) 面孔 36. Fargo (1996) 冰雪暴 37. Fargo (1996)

相关文档
最新文档