#include <iostream>
using namespace std;
#define TRACE(S) cout << #S" : " << sizeof(S) <<endl;
int main()
{
TRACE(int); //4
TRACE(unsigned int); //4
TRACE(long); //4
TRACE(unsigned long); //4
cout << endl;
TRACE(float); //4
TRACE(unsigned float); //4
TRACE(long float); //8
cout << endl;
TRACE(double); //8
TRACE(unsigned double); //4
TRACE(long double); //8
cout << endl;
TRACE(char); //1
TRACE(bool); //1
cout << endl;
double i = 123;
double *p = &i;
TRACE(i); //8
TRACE(p); //4 (what's p point to(address of i) )
TRACE(*p); //8
TRACE(&p); //4 (address of p)
cout << endl;
double array[3] = {1.2, 2.2, 3.2};
double *q = array;
TRACE(array); // 24 ( 3 * 8)
TRACE(array[1]); //8
TRACE(q); //4
TRACE(*q); //8
TRACE(&q); //4
cout << endl;
cout << " Done" << endl;
cin.get();
cin.get();
return 0;
}
//测试机器 :P4 32位
//操作系统 :windows 2003
///
sizeof(long) >= sizeof(int) >= sizeof(short)
16位机器: int 2, long 4;
32位机器: int 4, long 4;
TRACE(double); //8
TRACE(unsigned double); //4
TRACE(long double); //8
浮点型(float和double)的内存布局中第一位是符号位,这是固定的,不像整型那样需要unsigned修饰. 浮点类型是不存在unsigned修饰的.其实这样写, double 就被忽略了,而 unsigned double 就被编译成为 unsigned int 成为4个字节了
这段程序复习了另一个要点:就是预处理器的3个重要特征之一的"字符串定义",即
#define TRACE(S) cout << #S" : " << sizeof(S) <<endl;
另外两个是字符串串联和标志粘贴,
下面是ANSI C的解释:
The # operator
Constraints
1 Each # preprocessing token in the replacement list for a function-like macro shall be followed by a parameter as the next preprocessing token in the replacement list.
Semantics
2 If, in the replacement list, a parameter is immediately preceded by a # preprocessing token, both are replaced by a single character string literal preprocessing token that contains the spelling of the preprocessing token sequence for the corresponding argument. Each occurrence of white space between the argument’s preprocessing tokens becomes a single space character in the character string literal. White space before the first preprocessing token and after the last preprocessing token composing the argument is deleted. Otherwise, the original spelling of each preprocessing token in the argument is retained in the character string literal, except for special handling for producing the spelling of string literals and character constants: a / character is inserted before each " and / character of a character constant or string literal (including the delimiting " characters), except that it is unspecified whether a / character is inserted before the / character beginning a universal character name. If the replacement that results is not a valid character string literal, the behavior is undefined. The character string literal corresponding to an empty argument is "". The order of evaluation of # and ## operators
is unspecified.
6.10.3.3 The ## operator
Constraints
1 A## preprocessing token shall not occur at the beginning or at the end of a replacement list for either form of macro definition.
Semantics
2 If, in the replacement list of a function-like macro, a parameter is immediately preceded or followed by a ## preprocessing token, the parameter is replaced by the corresponding argument’s preprocessing token sequence; however, if an argument consists of no preprocessing tokens, the parameter is replaced by a placemarker preprocessing token instead.
3 For both object-like and function-like macro invocations, before the replacement list is reexamined for more macro names to replace, each instance of a ## preprocessing token in the replacement list (not from an argument) is deleted and the preceding preprocessing token is concatenated with the following preprocessing token. Placemarker preprocessing tokens are handled specially: concatenation of two placemarkers results in a single placemarker preprocessing token, and concatenation of a placemarker with a non−placemarker preprocessing token results in the non−placemarker preprocessing token. If the result is not a valid preprocessing token, the behavior is undefined. The resulting token is available for further macro replacement. The order of evaluation of ## operators is unspecified.
4 EXAMPLE In the following fragment:
#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)
char p[] = join(x, y); // equivalent to
// char p[] = "x ## y";
The expansion produces, at various stages:
join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"
In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but this new token is not the ## operator.
-------------------------------------------------------------------------------------