Why do I need arrays?
When we create a small number of variables of the same type, we usually create them one by one, but when we create more and more variables of the same type, it's not practical to create variables one by one. We'd better create many variables at a time. By introducing an array, we can create many variables of the same type quickly and easily, which greatly improves our efficiency.
1. One-dimensional array
1. Concepts
What is an array?
An array is a collection of elements of the same type
Same type: all reshaping, all character, all floating point...
2. Create
How arrays are created:
type_t arr_name [const_n] //type_t is the element type of the array //const_n is a constant expression used to specify the size of an array
General creation method:
int arr[10];
Note [] is a constant expression
You can use define to define the variable n to create an array:
#define n 10 int main(){ int arr[n] ; return 0; }
This is not possible:
int n = 10; int arr[n];
Note: The concept of variable-length arrays was introduced in c99, allowing the size of arrays to be specified by variables. If the compiler does not support variable-length arrays in c99, it cannot be used, for example, VS2019 does not support variable-length arrays.
There is one exception:
const int n = 0; //This is incorrect, const-decorated n cannot create arrays int arr[n] ;
In C language, a variable modified by const is called a constant variable or a variable. (Constant in c++)
3. Initialization
Assignment while creating
int arr[10]={1,2,3,4,5};//Incomplete initialization, zero for remaining elements int arr[10]={1,2,3 4,5,6,7,8,9,0};//Full Initialization //int arr[10]; Assign random values to uninitialized arrays, and sometimes the compiler will error to keep us from using them
Note: Variable-length arrays cannot be initialized. (
Compare these two ways of creating:
int arr1[10] = { 1,2,3,4 }; int arr2[] = { 1,2,3,4 };
After debugging, we found that there were no values in the initialization [], and the number of elements created in the array was created according to the values we gave.
And when we specify the number of elements, even if we give less than 10, it will set the rest of our elements to zero
Int: (Take int for example above)
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
char type:
char arr[3] = { 'a','b','c' }; char arr[3] = { 'a',98 ,'c' };//b has an asterisk value of 98, so you can also use 98 here char arr[ ] = "abc";//Notice that there are four elements in this array a b c a B C \0
4. Use
When we want to use each element precisely, reference the operator with the [] subscript
Each element has been labeled. Note that the label starts at 0, as shown below:
When we want to print 5, we should refer to element 4.
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; printf("%d", arr[4]); //arr and 4 are the two operands of [] }
The number of elements in the array can be calculated:
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; int sz = sizeof(arr) / sizeof(arr[0]); printf("%d", sz); }
Notice here that strlen and sizeof find the length of the string
#include<stdio.h> #include<string.h> int main() { char str[] = "abcd"; printf("%d ", sizeof(str)); printf("%d ", strlen(str)); return 0; }
The results are 5 and 4
Reason:
The str array contains'a''b''c''d''\0'
The strlen function works by detecting each character + 1 until the'\0'stop is detected, so'\0' is not included and the result is 4
sizeof calculates that elements in an array are always'\0'or not, so the result is 5
5. Storage in memory
Next, we need to get a deeper understanding of how each element of an array is stored
Look at the code:
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0;i < sz;i++) { printf("&arr[%d] = %p\n",i, &arr[i]); //%p--Print address (hexadecimal) } }
The result is 4 because the elements in an int-type array are all int, and the size of the elements is 4 bytes, causing them to have an address difference of 4, which is just one reshaping element.
From the above we can see:
- Conclusion 1: One-dimensional arrays are stored continuously in memory.
- Conclusion 2: As the array subscript increases, the address changes from low to high.
So we can also apply the nature of continuous storage.
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,0 }; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); for (i = 0;i < sz;i++) { printf("arr[%d] = %d\n",i, *(arr+i));//Pointer+1 skips an integer because arrays are stored continuously } //So go straight to the next element }
You can also use each element
2. 2-D Array
1. Create
Create in much the same way as a one-dimensional array
int arr[3][5];//Array of three rows and five columns
2. Initialization
Let's first fully initialize them:
int main() { int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; return 0; }
We find the law of assignment for two-dimensional arrays. (
Incomplete initialization:
First case: If you assign 6 values, do you assign the sixth number to the second row?
int main() { int arr[3][5] = { 1,2,3,4,5,6 }; return 0; }
We found that 6 was indeed assigned to the second row and that no assignment was initialized to zero
Second case: What do the brackets in parentheses represent?
int main() { int arr[3][5] = { {1,2},{4,5},{5,6} }; return 0; }
We find that the first enclosed element is initialized on the first line, the second is initialized on the second line, the third is initialized on the third line, and the uninitialized element defaults to zero.
Third, you can omit rows, but not columns.
int main() { int arr[][5] = { 1,2,3,4,5,6 }; return 0; }
This row is omitted, but there are columns. When five numbers are full, the sixth number is automatically initialized to the second row
In int arr[][5], [] is defaulted to 2
3. Use
As with one-dimensional arrays, be aware that the first element a[0][0] starts with 0. (
Print 2-D Array
#include<stdio.h> int main() { int arr[3][5] = { 1,2,3,4,5,6 }; int i = 0; int j = 0; for (i = 0;i < 3;i++) { for (j = 0;j < 5;j++) { printf("%d ", arr[i][j]); } printf("\n"); } return 0; }
There are also improvements:
#include<stdio.h> int main() { int arr[3][5] = { 1,2,3,4,5,6 }; int i = 0; int j = 0; for (i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) {//arr[0] treats the first row as an array, and dividing the total size by the first row size is the number of rows for (j = 0;j < sizeof(arr[0])/sizeof(arr[0][0]);j++) {//arr[0] - The size of the first row divided by the size of the first element is the number of columns printf("%d ", arr[i][j]); } printf("\n"); } return 0; }
Here we can calculate the rows and columns of the array
4. Storage in memory
We will print out the address of each array element
#include<stdio.h> int main() { int arr[3][5] = { 1,2,3,4,5,6 }; int i = 0; int j = 0; for (i = 0;i < 3;i++) { for (j = 0;j < 5;j++) { printf("&arr[%d][%d] = %p\n",i,j, &arr[i][j]); } printf("\n"); } return 0; }
The observation shows that, like a one-dimensional array, each address differs by 4, but the first address of the second line differs by 4 from the address of the element at the end of the first line, indicating that the two-dimensional array is also stored continuously in memory, where the first and second lines are also contiguous
A two-dimensional array can also be imagined as a one-dimensional array, with the first row array name arr[0], the second row array name arr[1], and the third row array name arr[3]
3. Array out of bounds
Subscripts of arrays are range-bound
The array subscript specifies that if there are n elements, then the subscript of the last element is n-1.
If the array subscript is less than 0 or greater than n-1, it represents an array that is out of bounds, but the compiler does not necessarily make an error, but the consequences of using the out-of-bounds value are unknown and are likely to cause program errors.
4. Some Problems with Arrays as Function Parameters
The array name is the address of the first element of the array
There are two exceptions:
- Sizeof (array name), the array name is not the address of the first element of the array, the array name represents the entire array, the size of the entire array is calculated
- &Array name, the array name is not the address of the first element of the array, the array name represents the entire array, the address of the entire array is taken out
However, when the array name is passed to sizeof after the function, the array name represents the address of the first element
Let's design a function to calculate the number of array elements
#include<stdio.h> void arr_size(int arr[]) { int sz = sizeof(arr) / sizeof(arr[0]); printf("%d", sz); } int main() { int arr[] = { 3,1,5,2,4,9,8,6,0,7 }; arr_size(arr); }
The result is 1, not 10
Why?
The reason is arr_size passes by the first address of an array of arrs, not the entire array, so sizeof (arr) calculates the size of the address of the first element of an array (32 bits, 8 hexadecimal arrays, 4 bytes), not the size of the entire array