Dissection C Chapter 1_2

Source: Internet
Author: User
Tags bitset case statement ranges switch case

Wcdj

This article is followed:Dissection C Chapter 1_1

Http://blog.csdn.net/delphiwcdj/archive/2010/10/06/5923540.aspx

 

[1] How many keywords does C have? How to Use sizeof? Is it a function?
[2] what is definition? What is declaration? What are their differences?
[3] Analysis of keyword roles one by one

(1) Auto
(2) Register
(3) static
(4) Basic Data Types
(5) sizeof
(6) signed, unsigned
(7) If, else
(8) switch, Case
(9) do, while,
(10) GOTO
(11) void
(12) Return


(6) signed and unsigned keywords


At the bottom of the computer, you only know 0, 1. How can negative numbers be stored? The negative "-" cannot be stored in the memory. What should I do? It's easy to do. Make a mark.
The highest bit of the basic data type is used to store symbols. The conventions are as follows:
If the highest bit is 1, it indicates that this number is a negative number, and its value is the "-" number added to the value of the remaining bit except the highest bit. If the highest bit is 0, it indicates that this number is a positive number, the value is the value of the remaining bits except the highest bits.
The number of 8-bit char types. The value range is-2 ^ 7 ~ 2 ^ 7-1
A 32-Bit Signed int integer whose value ranges from-2 ^ 31 ~ 2 ^ 31-1
A 32-bit unsigned int integer whose value ranges from 0 ~ 2 ^ 32-1
Note: by default, the Data Type of the compiler is signed.

[Question] What is the output result of the following code?
# Include <cstdio> <br/> # include <cstring> <br/> int main () <br/>{< br/> char a [1000]; <br/> int I; <br/> for (I = 0; I <1000; ++ I) <br/>{< br/> A [I] =-1-I; <br/>}< br/> printf ("% d/N ", strlen (a); // 255 <br/> return 0; <br/>}

[Analysis]
In a computer system, all values are represented (stored) by supplementary codes ). The main reason is that the complement code can be used to process the symbol bit and other bits in a unified manner. The purpose is to perform subtraction or addition. In addition, when two numbers are added, if the highest bit (symbol bit) has an incoming bit, the carry is discarded.
For example:
-1-1 = (-1) + (-1) = 1111 1111 1111 + 1111 1111 = 1110 (Supplemental code) =-2 (-(Supplemental code minus 1 and then reverse Code ))
The positive complement is the same as the original code.
Complement of a negative number: the sign bit is 1, and the rest is the original code of the absolute value of the number is reversed by bit, and then the whole number is added to 1.

According to the rules of negative number complement, you can know:
-1 is 0xff, and-2 is 0xfe .......
When the value of I is 127, the value of a [127] is-128, and-128 is the smallest negative number that can be expressed by char data (-128 ~ 127 ).
When I continues to increase, the value of a [128] is certainly not-129. Because of this overflow,-129 requires 9 bits to be stored, while char data only has 8 bits, therefore, the highest bit is discarded.
That is,-128-1 = 1000 0000 + 1111 1111 = 0111 1111 = 127
The remaining 8 bits are the low 8 bits of the 9-bit complement code, that is, 0x7f = 127.
When I continues to increase to 255, the low 8 bits of-256 are 0 = 0.
Then, when I is increased to 256, the low 8 bits of-257 are all 1 =-1, that is, the low 8 bits are 0xff.
So, another round of new loop ......
That is:-1,-2 ,......, -128,127,126 ,......, 1, 0

,-1,-2 ......
According to the above analysis, the values from a [0] to a [254] are not 0, while those from a [255] are 0.
The strlen function calculates the string length and does not contain the '/0' at the end of the string '. The flag for judging whether a string ends is to check whether '/0' is encountered. If yes, the string ends.
Therefore, the value of strlen (a) should be 255.
The key to this problem is to understand:

(1) the char type is signed by default, and its value range is [-128,127]. A value out of this range will overflow.
(2) In addition, it should be clear how the complement code of a negative number is expressed.
The following code is used to verify the above analysis:
# Include <cstdio> <br/> int main () <br/> {<br/> char a =-1-127; <br/> printf ("% d/N", a); //-128 <br/> A = (char) (-1-128 ); <br/> printf ("% d/N", a); // 127 <br/> A = (char) (-1-255 ); <br/> printf ("% d/N", a); // 0 <br/> A = (char) (-1-256 ); <br/> printf ("% d/N", a); //-1 <br/> return 0; <br/>}

 

[Problem extension]
(1) According to the above explanation, how are-0 and + 0 stored in the memory respectively?
# Include <iostream> <br/> # include <bitset> <br/> Using STD: bitset; <br/> Using STD: cout; <br/> Using STD: Endl; <br/> int main () <br/> {<br/> int I =-0, j = + 0; <br/> unsigned K =-1; <br/> bitset <32> bitvec_ I (I); <br/> bitset <32> bitvec_j (j ); <br/> bitset <32> bitvec_k (k); <br/> cout <bitvec_ I <Endl; // [32] (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) <br/> cout <bitvec_j <Endl; // [32] (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) <br/> cout <bitvec_k <Endl; // [32, 4294967295,) <br/> cout <k <Endl; // <br/> return 0; <br/>}

(2) int I =-20; unsigned J = 10; what is the value of I + J? Why?
# Include <cstdio> <br/> int main () <br/> {<br/> int I =-20; <br/> unsigned J = 10; <br/> printf ("% d/N", sizeof (j); // 4 <br/> printf ("% d/N", I + J ); //-10 <br/> printf ("% u/N", I + J); // 4294967286 <br/> return 0; <br/>}< br/>

(3) What is the problem with the following code?
Unsigned I;
For (I = 9; I> = 0; -- I)
{
Printf ("% u/N", I );
}

(7) If, else combination


Compare bool variables with "zero value"
If (btestflag = true)
If (btestflag = flase)

Compare float variables with "zero value"
If (ftestval> =-epsionon & ftestval <= epsionon) // epsionon indicates the defined precision.

Compare pointer variables with "zero value"
Int * P = NULL;
If (null = P)

Q: Which if Pair does else use?
Suggestion: use braces to include independent statement blocks in the program.

Problem: semicolon after if
Suggestion:; indicates an empty statement. To facilitate viewing, use NULL; indicates an empty statement.

(8) switch and case combinations


If, else generally indicates two branches or a small number of branches are nested, but if there are many branches ...... Use the switch and case combinations.
Note]
[Point]: Do not forget to add break at the end of each case statement. Otherwise, multiple branches will overlap (unless you intentionally do this)
[2]: use the default branch. This statement should be retained even if your program does not need to be processed by default. This is not a perfect solution, so you can avoid misunderstanding and forget the default processing.
[3]: Do you have any requirements for the values after the case keyword? Remember: case can only be followed by constants or constant expressions of the integer or complex type (in fact, they are all integer ).
[4]: Order of case statements. When there are many case statements, you need to consider the order of case statements. Rule 1: Sort case statements in alphabetical order. Rule 2: place normal conditions in front of normal conditions, and leave exceptions behind. Rule 3: prefix statements with high execution frequency and facilitate debugging.
[5]: simplify operations for each scenario. Generally, the code behind the case statement should not exceed 20 lines.
[Six Points]: do not create a variable to use case statements.
[7]: use the default clause only to check the true default situation.

(9) do, while,


In C language, there are three types of loop statements: while loop, do-while loop, and for loop.
Thinking: Can I use the continue keyword in the switch case statement? Why?
Note]
[Suggestion 1] if possible, the longest cycle should be placed in the innermost layer, and the shortest cycle should be placed in the outermost layer to reduce the number of times the CPU switches across the cyclic layer.
[Suggestion 2] It is best not to modify the loop variable in the for loop to prevent the loop from getting out of control.
[Suggestion 3] The cycle should be as short as possible to make the code clear and clear at a glance.
[Suggestion 4] control nested loops within three layers.

(10) GOTO


Disable the use of the GOTO statement.
[Disadvantage 1] It will damage the structural design style of the program.
[Disadvantage 2] errors or risks often occur. It may skip variable initialization, important calculation, and other statements.
For example:
Struct student * P = NULL;
......
Goto state;
P = (struct student *) malloc (......); // Skipped by Goto without Initialization
......
State:
// Code that uses the value in the memory pointed to by P
......
If the compiler cannot detect such errors, every time a GOTO statement is used, it may leave a hidden risk.

(11) void


Void is empty
Void * is a null pointer that can point to any type of data.
Void actually plays a role in: (1) Limitation on function return. (2) Restrictions on function parameters.
Float * FP;
Int * IP address;
Fp = (float *) ip address; // when values of different types are assigned, forced type conversion is required.
Void * is different. pointers of any type can be directly assigned to it without forced type conversion.
Void * VP;
Int * IP address;
Vp = IP; // OK, no need to force type conversion
However, void * cannot be directly assigned to other types of pointers. It must be forcibly converted. That is, "null type" can tolerate "with type", while "null type" cannot ".
Void * VP;
Int * IP address;
IP = VP; // error, cannot convert from 'void * 'to 'int *'

Note]
Rule 1: If the function does not return a value, the void type should be declared.
In C language, any function without a limited return value type will be processed by the compiler as the return integer value.

[Rule 2] If the function has no parameters, the void parameter should be declared.
In C, any type of parameters can be transferred to a function without parameters.
In C ++, no parameters can be transferred to a function without parameters.
Therefore, whether in C or C ++, if the function does not accept any parameters, you must specify the parameter as void.

Rule 3: Use the void pointer type with caution.
According to the ANSI standard, you cannot perform algorithm operations on the void pointer.
The reason for this determination is that the pointer to the algorithm operation must be determined to know the data type to which it points. That is to say, you must know the exact value of the memory destination address.
However, this is not true in GNU. It specifies that the void * algorithm operation is consistent with char.

[Rule 4] If the function parameter can be of any type pointer, the parameter should be declared as void *.
Typical examples include the memory operation function memcpy and memset function prototypes:
 Void * memcpy (void * DEST, const void * SRC, size_t Len); <br/> void * memset (void * buffer, int C, size_t num ); <br/> int intarray_a [100]; <br/> memset (intarray_a, 0,100 * sizeof (INT )); // clear intarray_a to 0 <br/> int destintarray_a [100], region [100]; <br/> memcpy (destintarray_a, srcintarray_a, 100 * sizeof (INT )); // copy SRC to dest
 

Any type of pointer can be passed into memcpy and memset, which also truly reflects the significance of the memory operation function, because it operates on only one piece of memory, regardless of the memory type.
Rule 5: void cannot represent a real variable.
Void A; // Error
Function (void a); // Error
When defining variables, we must allocate memory space and define void variables. How much memory does the compiler allocate?
The emergence of void is only for an abstract need. If you have understood the concept of "abstract base class" in object orientation correctly, it is easy to understand the void data type. Just as, you cannot define an instance for an abstract base class or a void variable.

(12) Return


Return is used to terminate a function and return the value following it.
Return (VAL); // This bracket can be omitted, but is generally not omitted, especially when the value of an expression is returned.
Note]
[Rule 1] The return statement cannot return a pointer to the "stack memory" because the function body is automatically destroyed when it ends.

 

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.