Lecture
An array consists of elements of the same type. The entire array can be accessed by name. In addition, you can select any element of the array. To do this, you must specify an index that indicates its relative position. The number of elements in the array is assigned when it is defined and does not change later. If an array is declared, then any element can be addressed as follows: specify the name of the array and the index of the element in square brackets. Arrays are defined in the same way as variables:
int a [100]; char b [20]; float d [50];
The first line contains an array of a of 100 elements of an integer type: a [0], and [1], ..., and [99] (indexing always starts from zero). In the second line, the elements of the array b are of type char, and in the third line - float.
A two-dimensional array is represented as one-dimensional, whose elements are also arrays. For example, the definition of char and [10] [20]; sets such an array. By analogy, you can set a larger number of measurements. Elements of a two-dimensional array are stored in rows, i.e. if you go through them in the order of their location in memory, then the rightmost index changes the fastest. For example, a call to the ninth element of the fifth line is written as: a [5] [9].
Let an array be given:
int a [2] [3];
Then the elements of array a will be placed in memory as follows: a [0] [0], a [0] [1], a [0] [2], a [1] [0], a [1] [1] , a [1] [2].
The array name is a constant that contains the address of its first element (in this example, a contains the address of the element a [0] [0]). Assume that a = 1000. Then the address of the element a [0] [1] will be 1002 (an element of type int takes 2 bytes in memory), the address of the next element a [0] [2] is 1004, etc. What happens if you select an item for which no memory is allocated? Unfortunately, the compiler does not track this situation. As a result, an error will occur and the program will not work correctly.
In C, there is a strong relationship between pointers and arrays. Any action that is achieved by indexing an array can also be performed using pointers, the latter option will work faster.
Definition
int a [5];
defines an array of five elements a [0], a [1], a [2], a [3], a [4]. If the object * y is defined as
int * y;
then the operator y = & a [0]; assigns the variable y the address of the element a [0]. If the variable y points to the next element of array a, then y + 1 points to the next element, and here the corresponding scaling is performed to increment the address taking into account the length of the object (for type int - 2 bytes, long - 4 bytes, double - 8 bytes and t .d.)
Since the array name itself is the address of its zero element, the operator y = & a [0]; can be written in another form: y = a. Then the element a [1] can be represented as * (a + 1). On the other hand, if y is a pointer to an array a, then the following two entries: a [i] and * (y + i) are equivalent.
There is one important difference between the name of the array and the corresponding pointer. The pointer is a variable and y = a; or y ++; - allowable operations. The name of the array is a constant, therefore constructions of the form a = y; a ++; cannot be used because the value of the constant is constant and cannot be changed.
Variables with addresses can form some hierarchical structure (they can be multi-level) such as a pointer to a pointer (that is, the pointer value is the address of another pointer), a pointer to a pointer to a pointer, etc. If the pointers address the elements of one array, then they can be compared (relations like <,>, = =,! = And others work correctly). At the same time, it is impossible to compare whether to use pointers to different arrays in arithmetic operations (the corresponding expressions do not lead to compilation errors, but in most cases they do not make sense). Any address can be checked for equality or inequality with the constant NULL. Pointers to the elements of a single array can also be subtracted. Then the result will be the number of array elements located between the reduced and subtracted objects.
The C language allows initialization of an array when it is defined. To do this, use the following form:
type array_name [...] ... [...] = {list of values};
Examples:
int a [5] = {0, 1, 2, 3, 4}; char ch [3] = {'d', 'e', '9'}; int b [2] [3] = {1, 2, 3, 4, 5, 6};
In the latter case: b [0] [0] = 1, b [0] [1] = 2, b [0] [2] = 3, b [1] [0] = 4, b [1] [1 ] = 5, b [1] [2] = 6.
In the language, arrays of pointers are allowed, which are defined, for example, as follows: char * m [5] ;. Here m [5] is an array containing the addresses of elements of type char.
The C language does not support a separate string data type, but it allows strings to be defined in two different ways. The first uses an array of characters, and the second uses a pointer to the first character of the array.
Definition char a [10]; tells the compiler to reserve space for a maximum of 10 characters. The constant a contains the address of the memory cell in which the value of the first of ten objects of type char is placed. Procedures related to entering a particular string into array a copy it one character at a time into the memory area pointed to by the constant a, until the zero character terminating the string is copied. When a function of type printf ("% s", a) is executed, the value a is transferred to it, i.e. the address of the first character pointed to by a. If the first character is null, then the printf () function ends, and if not, it displays it, adds one to the address, and starts checking for a null character again. Such processing allows you to remove restrictions on the length of the string (of course, within the declared dimension): the string can have any length, but within the available memory.
To initialize a string with this method of definition, you can do the following:
char array [7] = "String"; char s [] = {'С', 't', 'p', 'o', 'k', 'a', '\ 0'};(when defining an array with simultaneous initialization, the limits for changing the index can be omitted).
The second way to define a string is to use a pointer to a character. Definition char * b; sets the variable b, which may contain the address of some object. However, in this case, the compiler does not reserve space for storing characters and does not initialize the variable b with a specific value. When the compiler encounters an operator of the form b = "IBM PC" ;, it performs the following actions. First, as in the previous case, it creates the string "IBM PC" in some place of the object module, followed by a null character ('\ 0'). Secondly, it assigns the value of the starting address of this line (the address of the character 'I') to the variable b. The printf ("% s", b) function works in the same way as in the previous case, performing the output of characters until the final zero is encountered.
An array of pointers can be initialized, i.e. assign it elements specific addresses of certain specified lines in the definition.
In addition to scanf () and printf (), the functions gets () and puts () can be used to input and output strings of characters (their prototypes are in the stdio.h file).
If string is an array of characters, then you can enter a string from the keyboard as follows:
gets (string);
(entry ends by pressing <Enter>). The line can be displayed on the screen as follows:
puts (string);
Note also that for working with strings there is a special library of functions, the prototypes of which are in the file string.h.
The most commonly used functions are strcpy (), strcat (), strlen (), and strcmp ().
If string1 and string2 are arrays of characters, then the call to the strcpy () function is:
strcpy (string1, string2);
This function is used to copy the contents of string2 into string1. Array string1 must be large enough to fit string2. Since the compiler does not monitor this situation, the lack of space will lead to data loss.
The call to the strcat () function has the form:
strcat (string1, string2);
This function appends string2 to string1 and places it in the array where string1 was, and string2 is not changed. The zero byte that completed the first line is replaced by the first byte of the second line.
The strlen () function returns the length of the string, and the terminating zero byte is ignored. If a is an integer, then the function call has the form:
a = strlen (string);
The strcmp () function compares two strings and returns 0 if they are equal.
A structure is the union of one or more objects (variables, arrays, pointers, other structures, etc.). Like an array, it is a collection of data. The difference is that its elements must be addressed by name and that different elements of the structure do not have to be of the same type.
The structure is declared using the struct keyword followed by its type and then the list of elements enclosed in braces:
struct type {element type_1 element name_1; ......... element type_n element_n name; };
The item name can be any identifier. As above, in a single line you can write several separate identifiers of the same type separated by a comma.
Consider an example:
sruct date {int day; int month; int year; };
Following the curly bracket ending the list of elements, variables of this type can be written, for example:
struct date {...} a, b, c;
(at the same time the corresponding memory is allocated). Description without the following list does not allocate any memory; it simply sets the shape of the structure. The entered type name can later be used to declare a structure, for example:
struct date days;
Now the days variable is of type date.
If necessary, structures can be initialized by placing a list of initial values of elements following the description.
Allowed to put structures into each other, for example:
struct man {char name [20], fam [20]; struct date bd; int age; };
The data type defined above includes three elements: day, month, year, containing integer values (int). The man structure includes the name, fam, bd, and voz elements. The first two, name [20] and fam [20], are character arrays of 20 elements each. The variable bd is represented by a compound element (nested structure) of type data. The age element contains values of the integer type int). Now you can define variables whose values belong to the type entered:
struct man man_ [100];
The array man_ is defined here, consisting of 100 structures of type man.
To access a separate structure element, you must specify its name, put a full stop and immediately write down the name of the desired element, for example:
man_ [j] .age = 19; man_ [j] .bd.day = 24; man_ [j] .bd.month = 2 man_ [j] .bd.year = 1987;
When working with structures, it is necessary to remember that the type of the element is determined by the corresponding description string in curly brackets. For example, the array man_ is of type man, year is an integer, etc. Since each structure element belongs to a specific type, its name can appear anywhere that the use of values of this type is allowed. Structures of the form man_ [i] = man_ [j]; where man_ [i] and man_ [j] are objects corresponding to a single description of the structure. In other words, it is allowed to assign one structure to another by their names.
The unary operation & allows you to take the address of the structure. Suppose the day variable is defined:
struct date {int d, m, y;} day;
Here day is a date type structure that includes three elements: d, m, y. Another definition
struct date * db;
establishes the fact that db is a pointer to a date structure.
We write the expression:
db = & day;
In this case, to select the elements d, m, the structure must use the structure:
(* db) .d; (* db) .m; (* db) .y;
Indeed, db is the address of the structure, * db is the structure itself. Parentheses are necessary here, since the dot has a higher priority than the asterisk. For similar purposes, the C language provides a special operation ->. This operation selects the structure element and allows you to present the above constructions in a simpler form:
db -> d; db -> m; db -> y;
Consider the structure description:
struct data {int d, m, y;};
Here, in fact, a new data type is introduced - data. Now it can be used to declare specific instances of the structure, for example:
struct data a, b, c;
A special tool has been introduced in the C language that allows you to assign names to data types (rename). Such a tool is the typedef operator. It is written as follows:
typedef type name;
Here “type” is any permitted data type and “name” is any permitted identifier.
Consider an example:
typedef int INTEGER;
After that you can make an announcement:
INTEGER a, b;
It will do the same thing as the usual declaration int a, b ;. In other words, INTEGER can be used as a synonym for the int keyword.
A special kind of structures are bit fields. A bit field is a sequence of adjacent bits within a single, integer value. It can be of the type signed int or unsigned int and take from 1 to 16 bits. The fields are placed in the machine word in the direction from the younger to the highest order. For example, the structure:
struct prim {int a: 2; unsigned b: 3; int c: 5; int d: 1; unsigned d: 5; } i, j;
provides data placement in two bytes (in one word). If the last field were given as follows: unsigned d: 6, then it would be placed not in the first word, but in bits 0 - 5 of the second word.
In fields of type signed, the leftmost bit is signed.
Fields are used to pack the values of several variables into one machine word in order to save memory. They cannot be arrays and do not have addresses; therefore, the unary operation & cannot be applied to them.
A union is a variable that can store (at different times) objects of various types and sizes. As a result, it is possible to work with the same kind of data in the same memory area. The union keyword is used to describe a union, and the corresponding syntax is similar to structures.
Let the definition be given:
union r {int ir; float fr; char cr;} z;
Here ir has a size of 2 bytes, fr is 4 bytes, cr is 1 byte. The size of the variable z will be equal to the size of the largest of the three types given (i.e. 4 bytes). At the same time, z can only have the value of one of the variables ir, fr, or cr.
The enumerated data type is intended to describe objects from some given set. It is given by the enum keyword. Let's look at an example:
enum seasons (spring, summer, autumn, winter);
A new seasons data type has been introduced here. Now you can define variables of this type:
enum seasons a, b, c;
Each of them (a, b, c) can take one of four values: spring, summer, autumn and winter. These variables could be determined immediately by describing the type:
enum seasons (spring, summer, autumn, winter) a, b, c;
Consider another example:
enum days {mon, tues, wed, thur, fri, sat, sun} my_week;
Names entered in days (as well as seasons in the previous example) are integer constants. The first one (mon) is automatically set to zero, and each next one has a value one greater than the previous one (tues = 1, wed = 2, etc.).
You can assign certain values of the integer type to the constants (names that do not have them will, as before, be assigned values of previous constants increased by one). For example:
enum days (man = 5, tues = 8, wed = 10, thur, fri, sat, sun} my_week;
After that, mon = 5, tues = 8, wed = 10, thur = 11, fri = 12, sat = 13, sun = 14.
The enum type can be used to set the constants true = 1 and false = 0, for example:
enum t_f (false, true) a, b;
Comments
To leave a comment
Algorithmization and programming. Structural programming. C language
Terms: Algorithmization and programming. Structural programming. C language