C Language Array

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

Keywords: C Back-end

Added by Redapple on Fri, 25 Feb 2022 20:45:18 +0200