Details that are easy to be ignored in C language (article 3), ignore Article 3

Source: Internet
Author: User

Details that are easy to be ignored in C language (article 3), ignore Article 3

Preface:The purpose of this article is to record the details that are easy to ignore in the C language. I plan to take some time every day to read books and stick to it. Today is the first article, maybe next month's today is the second article, and next year's today is the first article ?...... I firmly believe that good memory is not as bad as writing. Article 3, fight ~...


Article 1: details easily overlooked in C language (article 1)

Link to article 2: details easily overlooked in C language (article 2)


1,_ Attribute _ (noreturn ))

_ Attribute _ function attributes, variable attributes, and type attributes can be set. _ Attribute _ (noreturn) sets the function attribute. noreturn notifies the compiler function to never return a value. When a function needs to return a value but has not yet run it to the return value, it is returned, this attribute can avoid errors. For example:

void Test();int main(void){    int x;    scanf("%d", &x);    if (x > 0)        Test();    else        return 0;}
The above code prompts a warning during compilation: warning: control reaches end of non-voidfunction. The cause of the warning is that the Test () function does not return values, so the main () function may not return values and the program does not know how to handle them.

void Test() __attribute__((noreturn));
If you change the declaration of Test () to the above, it is equivalent to notifying the compiler that the Test () function never returns a value, so there will be no warning.

Note: (1)The underline before and after attribute is entered by Shift + minus sign (twice );(2)The _ attribute _ mechanism has many other functions and is a special feature of gnu c. It is recommended that you summarize it when you read the relevant content to make it targeted.

2,If the compiler allocates memory to the variable in descending mode of the memory address, what is the problem with the following code?

int i, a[10];    for (i = 0; i <= 10; i++)        a[i] = 0;

Resolution: The array is out of bounds and the program is in an endless loop. The four bytes after array a in the memory are actually allocated to the integer variable I. The value of a [10] to 0 is actually to set the counter I value to 0.


3,In the if/else structure, we should try to put the condition with a higher probability of TRUE in front, which can improve the performance of the program. The switch is more efficient than the if/else structure. Even if the program does not need to be processed by default, the default: break statement should be retained;


4,The correct method for comparison with zero value
(1)Comparison between Boolean variables and zero values

The if statement judges whether the conditional expression is true or false. Instead of converting its calculation result to a Boolean temporary variable, it compares the result directly with 0, if the value is not equal to 0, it indicates true. Otherwise, it indicates false. Do not compare Boolean variables directly with true, 1,-1, and 0.

Bool flag; if (flag) // indicates that flag is true if (! Flag) // indicates that the flag is false.
(2)Comparison between Integer Variables and zero values
int value;  if (value == 0)  if (value != 0)  

(3)Comparison between floating point variables and zero values

The computer indicates that float (float or double) has a precision limit. For floating-point numbers that exceed the precision limit, the computer truncates decimal parts beyond their precision. Therefore, the two floating point numbers that are originally not equal may become equal in the computer. For example, float a = 10.222222225, B = 10.222222229; in mathematics, a and B are unequal, but they are equal in 32-bit computers. (Note: float can ensure 6 Valid digits, and double and long double can ensure 10 valid digits.) When programming in the actual application environment, there is always a precision requirement, compare whether a floating point number is equal to or not to another value (floating point number or integer (! =) The result may not meet the actual needs, because = and! = Compared operations often require higher accuracy than actual applications.

You can use ">" and "<" to compare floating point and integer .! (A> B )&&! (A <B) the semantics of a = B is equivalent, so it is not recommended to judge whether the floating point number is equal or not.

# Define EPSILON 1e-6 if (abs (x-y) <= EPSILON) // x equals to y if (abs (x-y)> EPSILON) // x is not equal to y if (abs (x) <= EPSILON) // x is equal to 0 if (abs (x)> EPSILON) // x is not equal to 0

(4)Comparison between pointer variables and zero values

The zero value of the pointer variable is "NULL" (recorded as NULL), that is, it does not point to any object. Although the value of NULL is the same as that of 0, they have different meanings (different types ).

if (p == NULL)  if (p != NULL) 

Note: Using if (NULL = p), if (100 = I) is better, because if = is written as = by mistake, because the compiler cannot assign values to constants, errors can be checked.


5,Va_list, va_start (), va_arg (), and va_end ()

The stdarg. h header file of the C standard function library defines the macros used by variable parameter functions. A variable va_list must be defined in the Variable Parameter function, and the macro va_start, va_arg, and va_end must be used to read the variable. The related definitions are as follows:

typedef char* va_list;void va_start ( va_list ap, prev_param ); /* ANSI version */type va_arg ( va_list ap, type ); void va_end ( va_list ap ); 

A simple example is as follows:

# Include <stdarg. h> # include <stdio. h> double average (int count ,...) {va_list ap; int j; double tot = 0; va_start (ap, count); // point va_list to the starting parameter for (j = 0; j <count; j ++) tot + = va_arg (ap, double); // The search parameter. The va_end (ap) type must be specified as needed; // release va_list return tot/count ;} int main (void) {double a [5] = {1, 0, 0, 0}; printf ("% lf \ n", average (5, a [0], a [1], a [2], a [3], a [4]); return 0 ;}

In C language, variable parameter functions may overflow when too few parameters or different types are input without length check and type check.


6,Order of Value

There are only four operators in C Language (&, || ,? : And,) There is a specified order of value. & | Evaluate the left-side operand first, and evaluate the right-side operand only when necessary. For? B: c. operand a is first evaluated, and then the value of operand B or c is obtained based on the value of a. For the comma operator, the value of the left operand is first evaluated, the value is discarded, and the right operand is evaluated. For example:

i = 0;while (i < n)    y[i] = x[i++];

The code for copying the first n elements from array x to array y is incorrect. The value assignment operator does not guarantee any order of value. The address of y [I] will be evaluated before or after the auto-increment operation of I is executed.

Note:The priority of an operator is completely different from the order of evaluation.


7,The address of the next element after the end of the array is valid. The result of reading the value of this element is undefined, and this error is rarely detected by the C compiler.

8,Character array is not necessarily a string

A character array is an array of characters whose elements are character variables. A string is an array of characters with '\ 0' (ASCII code value 0x00) as the ending character.

(1)For a character array, it does not care whether there are '\ 0' ending characters in the middle or end, because the array knows how many elements it has, '\ 0' is a legal element for it.

(2)If the character array does not contain the '\ 0' ending mark but is used as a string, it may cause "memory access conflict" or tamper with other memory units, and the strlen function results are abnormal. A simple example:

# Include <stdio. h> int main (void) {char arr1 [] = {'A', 'B', '\ 0', 'C', 'D '}; char arr2 [] = "Hello"; char * p = "Hello"; printf ("% d \ n", sizeof (arr1), strlen (arr1 )); // result 5 2 printf ("% d \ n", sizeof (arr2), strlen (arr2 )); // result 6 5 printf ("% d \ n", sizeof (p), strlen (p); // Result 4 5 return 0 ;}

9,Do not use literal constants to initialize references.

const int &a = 0;

The above semantics is not to initialize the reference to NULL, but to create a temporary int object and use 0 to initialize it, and then use it to initialize reference, the temporary object will be destroyed until a is destroyed.


10,The referenced constructor and destructor are not called. At the binary level, references are generally implemented through pointers, but the compiler helps us complete the conversion.


Common mistakes or ignored details in the Teaching of Function Application

Value Range: Independent Variable Function
Based on actual problems, writing functions and establishing equations are similar, but we need to clarify the established conditions,
 
What are the easy-to-ignore details in your life?

Things that are used to are always ignored by the brain!
 

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.