C Programming: Arrays, Strings, Structures, Pointers
Numeric Arrays or Vectors
Consider a vector as a sequential formation in memory. All data elements of an array must be of the same data type and the same type of storage.
Declaration
To declare a one-dimensional array, specify the size of the array with a positive integer expression enclosed in square brackets.
Syntax: type-of-storage data-type array_name [expression].
Reference Array Elements
To reference an array element we will use an index. The index value must be a positive integer, it can be an integer constant, a variable, or an integer expression.
Initialization
We call the initiation of a vector assigning known values to vector elements. If not initialized explicitly, it will be set to zero.
Memory Address of the Vector
The name of the variable representing the vector and the address of the first element of the vector have the same value: the first memory address of the vector.
Size of the Array
C automatically allocates the space needed depending on the type of data being used in the vector, with all elements of the vector arranged contiguously in memory.
Declaration of a Vector Locally and Globally
Vectors declared globally are initialized to zero by default, while local vectors are not.
Assigned Values Using scanf()
You can enter values for the elements of a vector using instructions with scanf().
Initializing a Vector with Null Values
In a program, when we want the vector to not contain random values, we can use a loop to assign an initial value of 0 to each vector element.
Processing Dimensional Arrays
C does not allow full operations involving arrays. The assignment operations, comparison, and so on, between two similar arrays must be done element by element. This is normally done within a loop.
Traversal of a Vector
Used to know the contents of the elements of a vector. You can have access to all elements of the vector using a loop. It can be used for testing or treatment of each data element.
Searching for an Element of an Array
You can also use a loop to check whether a value is in the array. It will access each element and check if it is the one we are looking for.
Modification of Elements in an Array
You can modify an element of an array. To do this, you first have to locate the data and then change its value by assigning the new one.
Deletion of Elements in an Array
One of the operations we can perform on a vector is to eliminate one of its elements. To remove an item from a vector, we must locate the item and move the other elements one position to the left.
Inserting Elements in an Array
Inserting an element in an array means adding an element to the array. Therefore, we have to locate the position where we want to insert the item and then move some elements within the array.
Two-Dimensional Arrays
They are two-dimensional vectors, also called matrices.
Declaration and Initialization
To declare a two-dimensional array, you must indicate the name followed by bracketed indices. The value of each index should be a positive integer, it can be an integer constant, an integer variable, or an expression. To reference an array element, specify the array name followed by the values at the position where the element is located. To assign values to the array, you can do it in the code indicating the values in braces and separated by commas or by applying the keyboard using scanf instructions().
Memory Storage
Arrays in C are stored in memory by rows. The elements of the last dimension, which form a vector, are always stored in memory consecutively.
Multidimensional Arrays
Multidimensional arrays have three or more dimensions. The size limit is set by the compiler. Multidimensional arrays have a drawback in that they are memory-intensive.
Strings
We can say that a string is a character vector with its elements occupying consecutive positions in memory. Each character of a string will occupy a position in memory. The last character in the string is the null character of C (‘\0’), it indicates where the string ends. The null character is automatically added by the C language when a string is initialized.
Declaring a String
In the C language, to use a character string (a vector of characters), place square brackets [] immediately after the string identifier. The %s format specifier is used for a variable of string type and %c for a variable of type char.
The sentence string[] = “Aula” tells the compiler to reserve space in memory to store the string “Classroom”. The string variable specifies the name of the character string as well as indicating the memory address of the first character of the string. Each character of “Classroom” is an array element. The elements in an array of characters in C are numbered starting from 0. The null character in a string ensures that programs know where the strings end.
Initializing Strings
Allocating a Complete String
The sentence char str[] = “Software” automatically reserves the number of memory positions to store each element of the string, including the null character ‘\0’ at the end.
Assigning Individual Characters
You can also indicate the individual characters enclosed in braces: char str[] = { ‘S’, ‘o’, ‘f’, ‘t’, ‘w’, ‘a’, ‘r’, ‘e’, ‘\0’};. We must also assign the null character ‘\0’ to the string.
Indicating the Length of the String
To indicate the length of the string, we will put an integer value between the brackets. For example: char str[4] = “Classroom”;. The null character is not counted as part of the length of the string. The null character will be placed automatically by the compiler. If we want to create a zero-length string, we write the null character in the position of the zero element: char str[0] = ‘\0’;. Single quotes define a character while double quotes define a string. ‘x’ represents the ASCII character “x” and “x” represents a string containing two characters ‘x’ and ‘\0’.
When keying a longer string that contains spaces between words like “This is a string” the statement scanf reads only the first word because it stops reading characters when it encounters the first blank space.
With gets()
To enter strings of characters, you can also use the function gets(). The function gets() reads the entire line of text written by you until you find the carriage return.
Address of Beginning of a String
When we read the contents of a string with scanf(), we do not put the ampersand in front of the string variable. This is because the string variable name is automatically the start address of the string.
Working with String Elements
We will use several library functions to read string elements, examine them, and even transform them.
Input/Output Character Functions
- getchar(): Allows you to read one character at a time from the input. It can be used to check each character read to determine if it is a letter of the alphabet, a number, or another input such as a punctuation mark.
- putchar(): Used to write out character by character. The character is transmitted as an argument.
- getch() and getche(): Read a character from the keyboard without waiting for the carriage return. getch() does not display the character on the screen while getche() does.
- puts(): Writes out a string of characters, including the end-of-line character, by bringing the output pointer to the next line.
Character Treatment Functions
Contained in the library <ctype.h>
- isalnum(): Determines if the argument is alphanumeric. Returns a nonzero value if true and 0 if false.
- isalpha(): Indicates whether the argument is alphabetical. Nonzero if it is true, it returns 0 when the character is not a letter of the alphabet (as blank), 1 for any uppercase character, and 2 for any character in lowercase.
- isascii(): Determines if the argument is a character. Nonzero if true, 0 if false.
- iscntrl(): Indicates whether the argument is a control character. Nonzero if true, 0 if false.
- isprint(): Determines if the argument is a printable ASCII character. Other than 0 if true, 0 if false.
- ispunct(): Determines if the argument is a punctuation character. Other than 0 if true, 0 if false.
- isspace(): Determines if the argument is a blank space. Nonzero if true, 0 if false.
- isupper(): Determines if the argument is capitalized. Nonzero if true, 0 if false.
- islower(): Determines if the argument is lowercase. Nonzero if true, 0 if false.
- tolower(): Converts a character to lowercase.
- toupper(): Converts a character to uppercase.
- isxdigit(): Determines if the argument is a hexadecimal digit. Returns a nonzero value if true, 0 if false.
- isdigit(): Determines if the argument is a decimal digit. Nonzero if true, 0 if false.
Conversion Functions: Strings to Numbers
- atoi(): Converts an ASCII string to an integer.
- atof(): Converts an ASCII string to a real number.
- atol(): Converts an ASCII string to a long integer.
String Handling Functions
They are used when we process strings as complete entities. The library functions we use are in the file string.h.
- strlen(): Calculates the length of a string. The length is an integer that indicates the number of characters that are part of the string, excluding \0.
- strcat() and strncat(): The contents of the second string are copied to the end of the first. It is important that the first string is greater than or equal to the second.
- strcat() takes two arguments, which are the names of the strings to concatenate.
- strcat() (str1, str2)
- strncat() concatenates only the first n characters of the second string to the first.
- strncat(str1, str2, n)
- strcmp() and strncmp(): Compare strings. The comparison is made character by character.
- Return a value:
- strcmp(str1, str2) returns:
- 0 if the strings match.
- > 0 if the first string precedes the second alphabetically.
- < 0 if the second precedes the first alphabetically.
- strncmp only compares the first n characters.
- strcasecmp(): Compares two strings ignoring case.
- strchr() and strrchr(): Look for a specific character within a string. They need two arguments. The first is the string within which to search. The second is the character to search for. Both methods return a pointer to the character position within the string (position in memory), if found, or a null pointer if not found. Strchr() returns the first occurrence of the character in the string. strrchr() returns the last occurrence of the character within the string.
- strstr(): Finds the first occurrence of a substring within a string. If the substring is found, the function strstr() returns a pointer to the beginning of the substring. If not found, it returns a null pointer.
- strpbrk(): Finds the first occurrence of any character in a substring within another.
- strtod(), strtol(), and strtoul(): Available to convert strings to numbers of type double, long, and unsigned long. This functionality is similar to the functions atoi() and atof(). These functions allow the conversion of longer numbers.
Dimensional Arrays for Character Strings
You can declare two-dimensional arrays of characters. This will store strings in an array. Each string is stored in one row of the array.
Definition of Type with typedef
Type definition. Defines a name for a type of data in C. Its statement is similar to declaring a variable except that you use the keyword typedef.
Syntax:
typedef type new_type
By using the new identifiers, typedef can be used as data types. These data types can be used anywhere in the program, both in the function bodies and in parameters. The typedef declaration does not create a new type, it just creates synonyms for existing types.
Structures
Type struct
It is a type of data that can be grouped under one name, with its elements being of different types of data related to each other.
Statement
To declare a structure, we have to specify the name of the structure and its component variables, which are called members. Members of a structure can be of different types.
Syntax:
struct
(
type identifier_1;
type identifier_2;
type identifier_N;
) structure_identifier;
Member Operator
It is used to assign values to members of a structure. The member operator specifies the name of the structure and the member of which it is a part. It is represented by the dot (.). Members of a structure can be processed individually. To access a structure member, write structure_variable.member.
Structure Label
If we define the structure in main(), it may only be used within main(). If it is defined before the function main(), it will create a global variable. We will be creating a template that can be used by any function within the program.
Type of Data Structures
We can identify a structure using typedef. Thus, we define a new type of data that will be a structure.
typedef struct
(
char name[30];
char address[40];
int year;
int age;
) students;
Initial Allocation of a Structure
You can only assign an initial value to structure type variables that are global or static. Members of a structure variable can be assigned initial values in the same way as arrays. The initial values must appear in the order in which they will be assigned to the corresponding members of the structure, enclosed in braces and separated by commas.
typedef struct
(
char name[30];
char address[40];
int year;
int age;
) students;
int main()
(
static students student1 = {
“Manuel”,
“Round 56”,
1,
19
};
static students student2 = {
“Alice”,
“Calatrava 35”,
2,
20
};
)
Vector Structures
Each element of a vector may be a structure. The elements or structures that compose the vector are all of the same type.
typedef struct
(
char name[30];
char address[40];
int year;
int age;
) students;
int main()
(
static students vector_students[tam];
)
The definition of a student as a static variable allows assigning 0 if the data is numeric or blank if they are strings, to all their fields.
Nested Structures
A structure can contain other structures called nested structures. You must define the common members only once in their own structure and then use that structure as a member of another structure. The nested structure has to be defined before the structure it is going to be a part of.
Vectors and Matrices within Structures
You can also declare vectors or arrays within a structure.
Union in C
It is very similar to the structure of C. Different types of data are stored in the same memory area.
Enumerated Types
The members of an enumeration are constants written as identifiers that are assigned integer numbers. The names are defined within the enumerated list. The resulting enum variable (tag) can be used anywhere in the program as if it were an int.
Example:
enum days_week
(
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
);
The above example is equivalent to the definition of the constants MONDAY, TUESDAY, …, SUNDAY, such as:
const int MONDAY = 0;
const int TUESDAY = 1;
const int SUNDAY = 7;
Values are assigned by the compiler according to a progression from left to right, i.e. the constant 0 for the leftmost, 1 for the next, etc.
Reference to the Elements
It is done with the name of the corresponding constant. A dias_semana enum type variable can take the values specified in the declaration of type.
enum days_week
(
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
);
int main()
(
enum days_week day;
for (day = MONDAY; day <= SUNDAY; day++)
(
printf(“%d”, day);
)
)
Assigning Values to Enumerated Types
You can assign values to an enum type in C as if they were integer values. The objective pursued with enumerated types is to make the program more readable and allow changes in the constants used in the program to be made easily.
Displaying Constants
An enumerated list variable is an integer and cannot be displayed as a string in a sentence of writing. For constant strings, it can be done like this:
- Using a switch statement ()
Example:
enum days_week {MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY} day;
switch (day)
(
case MONDAY: printf(“Monday”);
break;
case TUESDAY: printf(“Tuesday”);
break;
case SUNDAY: printf(“Sunday”);
break;
)
Pointers
A pointer is a variable that holds the memory address of other data, such as a variable or an element of an array.
Memory Address
Each memory location can store a byte of information. The memory addresses are listed sequentially from zero to the memory size. We will have data if we know its location.
Pointer Declaration
When you declare a pointer variable, the variable name must be preceded by an asterisk (*).
int var;
var = 47;
pointer = &var; // pointer contains the number of the memory location of var
*pointer; // contains 47
Initialization of a Pointer
A common mistake is forgetting to give an initial value to a pointer. Giving an initial value means indicating the address to which the pointer points before using it.
Changing Variables with Pointers
You can change the value of a variable using pointers.
Type Checking
C requires that the variables whose addresses are assigned to pointers are of the same type of data that is linked to the pointers in their statements.
Null and Void Pointers
A null pointer does not point anywhere, in particular to valid data, that is, a null pointer does not address any valid data in memory. Now, you can define NULL at the top of a program or a personal header file with the line:
#define NULL 0
One way to initialize a variable to a null pointer is:
char *p = NULL;
int *ptr = 0;
In C, you can declare a pointer so it points to any type of data, i.e. not assigned to a specific data type.
void *ptr;
Pointers to Pointers
A pointer can point to another pointer variable. To declare a pointer to a pointer, precede the variable with two asterisks (**).
int var = 100;
int *pint1 = &var;
int **pint2 = &pint1;
Values can be assigned to var with any of the following statements:
var = 47;
*pint1 = 84; /* Assigns 84 to var */
**pint2 = 64; /* Assigns 64 to var */
Pointers and Strings
In a string vector, each element is a character and occupies a single memory of an octet. As with other types of data, you can use a pointer to access any element in the string.
We can say that:
*pchar = str[0]
*(pchar + 1) = string[1];
*(pchar + 2) = str[2];
*(pchar + 3) = str[3];
*(pchar + 4) = string[4];
Pointers and Dimensional Numerical Vectors
It is the same as for strings. We can use pointers to get the contents of each of the vector elements. This shows the following equalities:
vector[0] = *pint;
vector[1] = *(pint + 1);
vector[2] = *(pint + 2);
Dimensional Arrays and Pointers
We consider a two-dimensional array as a collection of one-dimensional arrays. To scroll through the vector, use pointers instead of using the array name and subscripts.
Arrays of Pointers
A multidimensional array can be expressed as an array of pointers rather than as a pointer to a group of contiguous arrays. The array elements are memory addresses. The wider use of arrays of pointers is to provide arrays of pointers to strings.
Declaration:
data_type *array[expression 1];
Pointers and Structures
We can access the starting address of a structure in the same way as any other direction, using the address operator (&). If var is a variable of structure type we can declare a pointer to a structure of the form:
tipo_de_dato * ptvar;
tipo_de_dato where is the data type that identifies the structure and ptvar the pointer variable name. Assign the address of the structure pointer as follows:
ptvar = &var;
To access an individual member of a structure in terms of pointers will do so as follows:
ptvar-> member
where is the variable pointer ptvar and -> is equivalent to the dot operator.
ptvar-> member is equivalent to writing var.miembro, where var is a variable structure.
typedef struct
(
char name [30];
char address [40];
int year;
int age;
) students;
int main ()
(
student learners;
palumno students *;
palumno = &alumno;
printf ( “\ nEnter the name
gets (palumno-> name);
The operator -> belongs to the group of higher precedence, as the dot operator. Its associativity is left to right.
The operator -> can be combined with the operator. to access a submiembrodentro of a structure, therefore a submiembro can be accessed by typing
Similarly, the operator -> can be used to access an element of an array that is a member of a structure.
NOTE: The arrow ? sus4tuye operator a * and ()