Addendum introduction based on c language knowledge

  • 2020-04-01 23:38:01
  • OfStack

It takes a long time to use C, but it is difficult to be very thorough in every point of C. Although c is not as complex as c++, it has many nooks and crcorners: not that they are difficult, but that they are not often used, or contrary to your first instinct, or that they are simply not remembered because of their limited learning experience.
Here are some of the things that might come from expert programming c or the web. The recent discovery of the basis of classic books is often read often new, for two possible reasons:
1. As you gain experience, your perceptions may change, your ways of thinking may change, and the results will be new.
2. Earlier experience was limited, and some points may not be fully understood at all. Now you can understand more deeply.
The book of this respect again is like "code daqo", a few days ago looked through, again have different understanding.
Getting to the point:
1. Comparison between signed and unsigned:
Printf ("%d\n", sizeof('A')): the printed value is 4 (or the length of an int) instead of 1. Because c has A type promotion, it will first raise 'A' to int and then pass it to sizeof. The argument in the expression is raised to an int or double, then evaluated, and then clipped to get the value of the specified type.
If (1 < = sizeof(int)): the return value of sizeof is unsignedint, -1 will be cast to unsignedint and then compared.
What's involved here is type promotion, implicit type conversion. It happens in expressions, it happens in function arguments.
2, the size of the enumeration in memory: four bytes.
3. Local variables are also byte aligned:
              E_T g;
              E_T f;
              E_T e = false;
              Char c1;
              Char c2.
              Int i1.
              Char c3.
              Int i2.
Printf (" % % % % p, p, p, p, p %, % p % p, p \ % n ", & g, & f, & e, & c1, and c2, & i1, & c3, & i2);

< img Alt = "" border = 0 SRC =" / / files.jb51.net/file_images/article/201305/2013052315380710.png ">

-- indicates the complementary bits.
4. The function of the # and ## : # in the macro definition is to stringfy the macro parameter behind it, which simply means to replace the macro variable it refers to with a double quotation mark.
The ## is called the concatenator and is used to join two tokens into one.
5. Floating point Numbers cannot be compared with equals.
6. Void foobar2() means that there are more than one arguments in the function. Void foobar2(void)
7. Global variables are initialized to 0, but local variables in the stack are not initialized.
Inline and macros: inline functions are real functions, but they are optimizations at compile time.
9,       Int a, [5].       Printf (" % x \ n ", a);       Printf (" % x \ n ", a + 1);       Printf (" % x \ n ", & a);       Printf (" % x \ n ", & a + 1);
The last one, &a+1, &a, represents an array, so it should be an increase in the array size: 4*5 bytes.
10, 10U represents the number 10 of an unsigned type.
11. The priority of shift operation is lower than four operations.
Moving n to the left is the same thing as multiplying by 2 to the n. To the right is the same thing as being 2 to the n.
13. Pointer and array:
1) void fun(char buf[100])
{
Printf (" % d, \ n ", sizeof (buf));
}
The printed value is 4, not 100.
2) char p[10] = "" in a file;
Declare: extern char *p;
Then, in the declared file sizeof(p), the answer is 4. That is, sizeof calculates the declared type.
3) to the compiler, an array is an address, and a pointer is the address of an address.
4) all the array names as function parameters will be converted to Pointers by the compiler. In all other cases, the declaration of the array is an array and what the pointer is is a pointer.
The same rule for arrays and Pointers:
1. The array name in the expression (as opposed to the declaration) is used by the compiler as a pointer to the first element of the array.
2. The index is always the same as the offset of the pointer.
3. In the declaration of a function, the array name is used by the compiler as a pointer to the first element of the array. This operation is done by the compiler. The reason is efficiency. Because that's reference passing, not value passing. value   Delivery requires copying. This also shows that sizeof operates in assembly.
The behavior of arry[-1] is undefined.
Conclusion:
1) access to a in the form a[I] is always overwritten by the compiler as *(a+ I).
2) a pointer is always a pointer. You can't rewrite it as an array, but you can access it as an array.
3) the array will be overwritten as a pointer by the compiler as an argument to a function.
4) pointer and what of the array must be paired.
Declaration and definition: declaration can be more than one, only one definition. A definition is a special declaration that allocates memory to an object. Declarations, on the other hand, are plain declarations that describe objects created elsewhere.
Declared priority rules:
A: read from his name in order of priority:
B: priority level:
1. The part of the declaration enclosed in parentheses.
2. Suffix operator:
Parenthesis () indicates a function;
Square brackets [] indicate an array;
3, prefix operator: * refers to what pointer;
4. If const is followed by a variable, the modified variable cannot be modified, and if const is followed by a type, what it points to cannot be modified.
15. Multidimensional array:
A [2][3]:a is an array with two elements. Each element is another array, with three elements.
Memory layout: a[0][0],a[0][1],a[0][2],a[1][0]... The address keeps getting bigger.
The multidimensional array, the array of the array as a parameter of the function, is converted into an array pointer, and the pointer to the array is also a row pointer. It's essentially a pointer.
16. The default byte alignment of a structure generally meets three criteria:
1) the first address of a structure variable can be divisible by the size of its widest base type member;
2) the offset of each member of the structure relative to the first address of the structure is an integer multiple of the size of the member itself. If necessary, the compiler will add internal bytes between the members.
3) the total size of the structure is an integer multiple of the size of the structure's widest base type member, and the compiler USES trailing padding after the last member if necessary.


Related articles: