Comprehensive Analysis of sizeof (on), comprehensive analysis of sizeof (
The following code uses the Windows 7 64 bits + VS2012 platform.
Sizeof is an operator in C/C ++. It is used to return the number of memory bytes occupied by an object or type. It is frequently used and must be aligned for a comprehensive understanding.
1. Basic Syntax of sizeof
Sizeof has three syntax forms:
(1) sizeof (object); // sizeof (object );
(2) sizeof (type_name); // sizeof (type );
(3) sizeof object; // sizeof object;
Although the third syntax structure is correct and is simple and unified, both the first and second languages are used. For example:
int i;sizeof( i ); // oksizeof i; // oksizeof( int ); // oksizeof int; // error
2. sizeof calculation basic types and representations
The size of the sizeof calculation object is also converted to the calculation of the object type. That is to say, the sizeof values of different objects of the same type are consistent. Here, the object can be further extended to the expression, that is, sizeof can evaluate an expression. The Compiler determines the size based on the final result type of the expression. sizeof is an operation during compilation, it is irrelevant to the runtime and does not calculate the expression.
Test the following code:
#include <iostream>using namespace std;int main(int argc,char* argv[]){ cout<<"sizeof(char)="<<sizeof(char)<<endl; cout<<"sizeof(short)="<<sizeof(short int)<<endl; cout<<"sizeof(int)="<<sizeof(int)<<endl; cout<<"sizeof(long)="<<sizeof(long int)<<endl; cout<<"sizeof(long long)="<<sizeof(long int int)<<endl; cout<<"sizeof(float)="<<sizeof(float)<<endl; cout<<"sizeof(double)="<<sizeof(double)<<endl; int i=8; cout<<"i="<<i<<endl; cout<<"sizeof(i)="<<sizeof(i)<<endl; cout<<"sizeof(i)="<<sizeof(i=5)<<endl; cout<<"i="<<i<<endl;}
In 64 bits Windows, the running result is
Sizeof (char) = 1
Sizeof (short) = 2
Sizeof (int) = 4
Sizeof (long) = 4
Sizeof (long) = 4
Sizeof (float) = 4
Sizeof (double) = 8
I = 8
Sizeof (I) = 4
Sizeof (I) = 4
I = 8
Note,
(1) The value of I has not changed, indicating that the expression in the sizeof brackets is not executed. sizeof requires the type of calculation result of the expression during compilation. sizeof has nothing to do with runtime. Sizeof (I) is equivalent to sizeof (int), sizeof (I = 5) is equivalent to sizeof (int), that is, in executable code, it does not contain the expression I = 5, it was processed as early as the compilation phase.
(2) Whether the long int occupies 8 bytes depends on the implementation of the compiler. The Compiler used in Visual cve-20172is cl.exe. In 64 bits Windows, the long is still compiled into 4 bytes. To use an 8-byte long integer, to be safe, use the long type.
3. sizeof calculates pointer Variables
Pointer is the soul of C and C ++, which records the address of another object. Since the address is stored, it is equal to the width of the computer's internal address bus. Therefore, in a 32-bit computer, the return value of a pointer variable must be 4 (in bytes), which can be deduced. In the future 64-bit system, the sizeof result of the pointer variable is 8.
Char * pc = "abc"; int * pi = new int [10]; string * ps; char ** ppc = & pc; void (* pf )(); // function pointer char testfunc () {return 'K';} sizeof (pc); // The result is 4 sizeof (pi); // The result is 4 sizeof (ps ); // The result is 4 sizeof (ppc); // The result is 4 sizeof (pf); // The result is 4 sizeof (& testfunc ); // The result is 4 sizeof (testfunc (); // The result is 1 sizeof (* (testfunc) (); // The result is 1
Evaluate the above Code and draw the following conclusion:
(1) the sizeof value of the pointer variable has nothing to do with the object type referred to by the pointer, and has nothing to do with the amount of space requested by the pointer. All pointer variables occupy the same memory size. So why is the pointer variable size still 4 bytes in the 64bits System of the local machine, because the 32-bit compiler is used to compile the program to 32 bytes, so the pointer size is 4 bytes, you can modify the compiler version by yourself.
(2) & testfunc indicates a function pointer. the pointer size is 4, so sizeof (& testfunc) = 4. Testfunc () indicates the callback function call. The return value type is char, so sizeof (testfunc () = sizeof (char) = 1. The testfunc name itself is a function pointer, so (* testfunc) () is also a callback function call, sizeof (* testfunc) () = sizeof (char) = 1.
4. sizeof calculates the Array
When sizeof acts on an array, it obtains the size occupied by all elements of the array. Refer to the following code:
Int A [3] [5]; char c [] = "123456"; double * (* d) [3] [6]; cout <sizeof () <endl; // output 60 cout <sizeof (A [4]) <endl; // output 20 cout <sizeof (A [0] [0]) <endl; // output 4 cout <sizeof (c) <endl; // output 7 cout <sizeof (d) <endl; // output 4 cout <sizeof (* d) <endl; // output 72 cout <sizeof (** d) <endl; // output 24 cout <sizeof (*** d) <endl; // output 4 cout <sizeof (*** d) <endl; // output 8
Evaluate the above Code and draw the following conclusion:
(1) the data type of A is int [3] [5], and that of A [4] is int [5]. A [0] [0] data type is int. So
Sizeof (A) = sizeof (int [3] [5]) = 3*5 * sizeof (int) = 60, sizeof (A [4]) = sizeof (int [5]) = 5 * sizeof (int) = 20, sizeof (A [0] [0]) = sizeof (int) = 4. Although the subscript of A [4] is out of bounds, it does not cause runtime errors, because the sizeof operation only cares about the data type and has been completed in the compilation phase.
(2) because the string ends with an empty character '\ 0', the Data Type of c is char [7], so sizeof (c) = sizeof (char [7]) = 7.
(3) d is a pointer. No matter what data type it points to, its size will always be 4 ,. So sizeof (d) = 4. The data type of sizeof (* d) is double * [3] [6], so sizeof (* d) = sizeof (double * [3] [6]) = 3*6 * sizeof (double *) = 18*4 = 72. Similarly, we can calculate sizeof (** d) = sizeof (double * [6]) = 6 * sizeof (double *) = 24, sizeof (*** d) = sizeof (double *) = 4, sizeof (*** d) = sizeof (double) = 8.
When an array is used as a function parameter, what are the values of I and j below?
void foo1(char a1[3]){ int i = sizeof( a1 ); // i == ?}void foo2(char a2[]){ int j = sizeof( a2); // j == ?}
Maybe you have realized that I was wrong when trying to answer j's value. Yes, I! = 3. Here, the function parameter a1 is no longer an array type, but a pointer, equivalent to char * a1. Why? When we call the foo1 function, will the program allocate a 3 array on the stack? No! The array is "Address Transfer". The caller only needs to pass the address of the real parameter. Therefore, a1 is a pointer type (char *), and the I value is 4, and j is also 4.
Errors and deficiencies are inevitable. You are welcome to comment and correct them!
References
[1] Chen Gang. C ++ advanced tutorial [M]. Wuhan: Wuhan University Press, 2008.
[2] http://blog.csdn.net/freefalcon/article/details/54839