Do you master on Array in C?

Source: Internet
Author: User
Do you master on Array in C?


Because the new c99 standard supports variable-length arrays, the standard feature of almost C is to look at GCC (the Linux kernel is heavily dependent on GCC)


int mani(){             const int a = 10;             int array[a];             return 0;}

Can this code be compiled?

It won't last in 2012, and it will be enough in 2014 (Time Changes Everything ~)


Test results on the VC ++ 6.0

Sdev98 \ bin \ hello. C (7): Error c2057: Expected constant expressionf: \ Vc ++ 6.0 \ Microsoft Visual Studio \ common \ msdev98 \ bin \ hello. C (7): Error c2466: cannot allocate an array of constant size 0f: \ Vc ++ 6.0 \ Microsoft Visual Studio \ common \ msdev98 \ bin \ hello. C (7): Error c2133: 'array': Unknown sizeerror executing cl.exe.

No. The reason for choosing vc6.0 is that the compiler specification of this guy and the early ANSI are in line with well. The early ANSI standard does not support the feature of variable length arrays.


But! C99 plaintext specifies that the C language adds the variable length array feature



#include <stdio.h>#include <stdlib.h>int main(){        int a = 10;char b[a];int *p = &a;(*p)++;printf("%d %d\n", sizeof(b), a);return 0;}

Can this happen? Yes!


Can the following be passed? No!

int a = 10;int array[a] ;int main(){            return 0l}


It doesn't matter whether the above three questions can be answered correctly. It's time to solve the array below, so we can't escape the new features-the array gets longer



There are two types of Variable Length: VLA (varible length array) & VM (varible modified, that is, a pointer to a VLA type)


Excerpted from the c99 standard (the following part of the array)

Array declarators



Constraints

Answer: What is an array?

1 In addition to optional type qualifiers and the keyword static, the [and] may delimit an expression or *.

The following if will start to analyze the situation...

If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero.

If the length of the array is limited, the exp in array [Exp] should be an integer.

If it is a constant expression, the value of this expression must be greater than 0 (I know that some people will definitely say the usage of array [0] In struct, so don't rush to analyze it later)


The element type shall not be an incomplete or function type. the optional type qualifiers and the keyword static shall appear only in a declaration of a function parameter with an array type, and then only in the outermost array type derivation.


What kind of array can become longer?
2 only an ordinary identifier (as defined in 6.2.3) with both block scope or function prototype scope and no linkage shall have avariably modified type. if an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.

I still take a screenshot of 6.2.3. This is a good argument, but it is a short one.


Here, ordinary identifier is the last item "all other identifiers called ordinary identifiers". Here, note that ordinary identifier is the last item of the four options "-", excluding the first three items, it is worth noting that struct does not belong to ordinary identifier.

int a = 10;int array[a];int main(){           return 0;}
This Code cannot be compiled by GCC, And the array grows longer than block (that is, the main function,



Semantics
3 if, in the declaration 'td1', D1 has one of the forms:


D [type-qualifier-list opt assignment-expression opt]

D [static type-qualifier-list opt assignment-expression]

D [type-qualifier-list static assignment-expression]

D [type-qualifier-list opt *]


And the type specified for ident in the Declaration 'td' is ''' derived-declarator-type-list t '', then the type specified for ident is ''' derived-declarator-type-list array of t ''. 121)
 

Two types of Arrays: incomplete type and complete Type
4

What is incomplete type.

If the size is not present, the array type is anincomplete type. if the size is * instead of being an expression, the array type is a variable length array type of unspecified size, which can only be used in declarations with function prototype scope;

Note: here * is omitted, not actually written in *


Element_type name [size];

Here, the size is missing to form element_type name []; it is called the Varible length array Variable Length array. In fact, we often use

Char string [] = "Hello world! \ N ";


What is complete type?

Such arrays are nonetheless complete types. if the size is an integer constant expression and the element when several ''array of ''specifications are adjacent, A multidimen=array is declared. thus, * can be used only in function declarations that are not definitions (see 6.7.5.3 ). type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.



5If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced *;Otherwise, each time it is evaluated it shall have a value greater than zero.

If size is a value that is not an integer constant expression, if this happens when the function is declared, the size of this non-constant expression is treated as *, which is omitted, basically, the parameter passing through an array is passed in the form of a pointer, which shows the essential source of the parameter passing through an array.

If the parameter is not included in the function declaration, the size must be an integer greater than 0.


The size of each instance of a Variable Length array type does not change during its lifetime. Where a size expression is part of the operand ofSizeofOperator and changing the value of the size expression wocould not affect the result of the operator, it is unspecified whether or not the size expression is evaluated.
The size of any Varible length array does not change throughout its lifecycle.


#include <stdio.h>#include <stdlib.h>int main(){int a = 10;char b[a];int *p = &a;(*p)++;printf("%d %d\n", sizeof(b), a);return 0;}

Print what? The reason for is that the above explanation


@ Kaixuan chongfeng found a superb practice

#include <stdio.h>#include <stdlib.h>int main(){const int a = 10;char b[a];printf("%d %d\n", sizeof(b), a);int *p = &a;(*p)++;printf("%d %d\n", sizeof(b), a);return 0;}
Look! The output result is

10 10
11

Why? Why does it change? Doesn't it mean that the length of the entire lifecycle array remains unchanged? Doesn't it mean that sizeof is not affected? Wait: Look at the const and you can't like it any more. Here we have involved a forced type conversion of pointers.

Int * P = & A; here & A is the address of const int A. How can I explain this address? View its data type-const int

Similarly, char C; & C will interpret this address as a char-type variable.

Just think about it.

Int * P = & A; P points to an int type variable, and & A points to a const int variable. God, if you reference P, then you can change the value pointed to by P. Why? Because p tells you that it points to the int type. How can you change it? const int doesn't work!

To put it bluntly, it is the same memory address. You have used different methods to explain it. One method is P, and the other method is


The combination of the two will have a wonderful effect, hold it!

When you access this memory through a, it is read only (const). When you access this memory through P, it is read & write, int type.

A ++; is not allowed. You try to change the memory data of the mark in the read-only mode.

(* P) ++; yes. The access method of P is r w.


You will find that there is only one error! As I guess, warning has forced type conversion.



But you are not sure about the consequences of this practice, and have not studied its impact on other storage locations on the stack. This is almost a magic of magicians, but you need to know that it occurs on the stack, in addition, the size of the array is fixed. I suspect that this method is a "deceptive" and does not actually change the size of the array, it can be said that it is a "legal array out-of-bounds" (we can continue to discuss this, the impact of this approach on the stack memory layout)



6 For Two array types to be compatible, both shall have compatible element types, and if both size specifiers are present, and are integer constant expressions, then both size specifiers shall have the same constant value. if the two array types are used in a context which requires them to be compatible, it is undefined behavior if the two size specifiers evaluate to unequal values.

I still don't understand the Compatible problem of multi-dimensional arrays, so that I don't quite understand the demo of the image below. Please

Team mate for essential on C & Linux



The following example describes the array usage and illegal situation.
7 example 1
Float Fa [11], * AFP [17];
Declares an array of Float numbers and an array of pointers to float numbers.


8 example 2
Note the distinction between the declarations
Extern int * X;
Extern int y [];
The first declares X to be a pointer to int; the second declares y to be an array of int of unspecified size (an incomplete type), the storage for which is defined elsewhere.

9 Example 3
The following declarations demonstrate the compatibility rules for variably modified types.

Extern int N; extern int m; void fcompat (void) {int a [n] [6] [m]; int (* P) [4] [n + 1]; int C [N] [N] [6] [m]; int (* r) [N] [N] [n + 1]; P = A; // invalid: not compatible because 4! = 6r = C; // compatible, but defined behavior only if n = 6 and M = n + 1 I don't quite understand it here. I feel like R and C don't come, I always think that the dimensions are different}


10 example 4

All declarations of variably modified (VM) types have to be at either block scope or function prototype scope.

In this case, the pointer to the variable-length array is left empty. The VM is used only within the block.

Array objects declared with the static or extern storage-class specifier cannot have a variable length array (VLA) type.

No objects with static or external link features can use VLA (this is almost understandable that VLA only occurs on the stack. If my opinion is incorrect, I hope I can discuss it)

However, an object declared with the static storage-class specifier can have a VM type (that is, a pointer to a VLA type ). finally, all identifiers declared with a VM type have to be ordinary identifiers and cannot, therefore, be members of structures or unions.

The final structure of VM cannot be member.

 

The int (* s) [m] In the figure is the VM.


Finally, do not forget to discuss the array size = 0. It can only be used in struct.

This is a classic practice, so that there is a special statement in the c99 standard, not the so-called "miracle", here we have a formal explanation! Haha

The following link provides a summary of the usage.

Http://blog.csdn.net/cinmyheart/article/details/28985843

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called aflexible array member. with two exceptions, the flexible array member is ignored. first, the size of the structure shall be equal to the offset of the last element of an otherwise identical structure that replaces the flexible array member with an array of unspecified length. 106) Second, when. (or->)
Operator has a left operand that is (a pointer to) a structure with a flexible array member and the right operand names that member, it behaves as if that member were replaced with the longest array (with the same element type) That wocould not make the structure larger than the object being accessed; the offset of the array shall remain that of the flexible array Member, even if this wowould differ from that of the replacement array. if this array wowould have no elements, it behaves as if it had one element but the behavior is undefined if any attempt is made to access that element or to generate a pointer one past it.

This is flexible array member. Note the difference between VLA and VM.










The Netherlands 1689 140 × 103 oil painting London National Museum of Art
This figure shows the beautiful scenery of the countryside. the quiet countryside scenery on the screen seems dull, but it is intriguing, so that the viewer is happy. The symmetrical tree is stable and dynamic. As the trail goes forward, you can see the church on the left, the two tall huts on the right, and the ruffles are printed on the muddy Village Road, it shows a calm and difficult life that is continuing. The sky that occupies most of the pictures is steaming and charming. There is also a sad irony in this painting. The long Boulevard disappears to a point on the dark horizon. This sad irony in the painting also reflects the real life of hobima.




Do you master on Array in C?

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.