Table of contents
- 0 Introduction
- 1. One-dimensional array
-
- 1.1 Array name
- 1.2 Subscript reference
- 1.3 Pointers and subscripts
- 1.4 Efficiency of pointers
- 1.5 Arrays and pointers
- 1.6 Array name as function parameter
- 1.7 Declare array parameters
- 1.8 Initialization
- 1.9 Incomplete initialization
- 1.10 Automatically calculate array length
- 1.11 Initialization of character array
- 2. Multidimensional array
- 3. Pointer array
- 4. Summary
0 Introduction
In C language, arrays play an important role. The inextricable connection between arrays and pointers has also made them the focus of technical discussions during job hunting, study and work. There are so many stars in computer programming languages. Why does C language array remain so popular in interviews for many years? What kind of magical charm does it have? Today we will discuss related topics together.
Let’s take a look at the main content of this article first (the chapter numbers are consistent with those in the book). Have a macro grasp.
1. One-dimensional array
One-dimensional array is the most common array and the most commonly used array. In actual development, in order to facilitate iteration and reading, multiple arrays are sometimes split into multiple one-dimensional arrays.
1.1 Array name
The array name of a one-dimensional array is a pointer constant, pointing to the first element of the array. You can refer to the following program:
#include <stdio.h>
int main()
{
int temp[] = {
1,2,3};
printf("%d \n", *(temp));
printf("%d \n", *(temp + 1));
printf("%d \n", *(temp + 2));
return 0;
}
Printout:
1.2 Subscript reference
Except for priority, subscripted references are exactly the same as indirect accesses. You can refer to the following procedures:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int temp[] = {
1,2,3};
int *p = temp + 1;
printf("数组的第一个元素是:%d \n", *(temp));
printf("数组的第二个元素是:%d \n", *(temp + 1));
printf("数组的第三个元素是:%d \n", *(temp + 2));
//打印数组的第一个元素
printf("数组的第一个元素是:%d \n", p[-1]);
system("pause");
return 0;
}
Print output:
As can be seen from the above program, the pointer p points to the 2
element of the array at this time, so p[-1]
it will point to the first element of the array.
1.3 Pointers and subscripts
Pointers and subscripts are both effective ways to access array elements. However, subscripts are never more efficient than pointers, but pointers are sometimes more efficient than subscripts. Since they involve underlying instructions, they will not be expanded here.
1.4 Efficiency of pointers
Pointers are sometimes more efficient than subscripts, provided they are used correctly. Since it involves underlying instructions, it will not be expanded upon here.
1.5 Arrays and pointers
Arrays and pointers are not equal. When declaring the array, the memory has been allocated, but when declaring the pointer, we only know the data type it points to, but do not know the specific address pointed to, or it is an address that has no meaning.
For example, let's say we have the following two statements:
int a[5];
int *p;
We can verify it through the following procedure
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[5];
int *p;
printf("数组a的大小是%d \n", sizeof(a));
printf("指针p的大小是%d \n", sizeof(p));
system("pause");
return 0;
}
Print output:
You can see that after compilation, an int type data occupies 4 bytes. At this time, the system has allocated all the memory for the array; as for the pointer p, we only know that it points to an int type variable. , however it is not known which variable is pointed to .
1.6 Array name as function parameter
When an array name is passed as a parameter to a function, a copy of the pointer is passed to the function. If a function makes a subscript reference, it actually performs an indirect access operation on this pointer, and through this indirect access, the function can access and modify the array elements of the calling program.
You can refer to the following procedures:
#include <stdio.h>
#include <stdlib.h>
void reverse_array(int arr[], int size)
{
for (int i = 0; i < size / 2; i++)
{
int temp = arr[i];
arr[i] = arr[size - i - 1];
arr[size - i - 1] = temp;
}
}
int main()
{
int a[5];
for (int i = 0; i < 5; i++)
a[i] = i;
reverse_array(a, 5);
for (int i = 0; i < 5; i++)
{
printf("数组a第%d个元素是%d \n", i, a[i]);
}
system("pause");
return 0;
}
1.7 Declare array parameters
There is an interesting question. When we pass an array as a parameter to a function, what should the correct function parameters look like? Should it be declared as a pointer or an array?
All are correct in a strict sense. You can refer to the following code
#include <stdio.h>
#include <stdlib.h>
//声明为数组
void reverse_array1(int arr[], int size)
{
for (int i = 0; i < size / 2; i++)
{
int temp = arr[i];
arr[i] = arr[size - i - 1];
arr[size - i - 1] = temp;
}
}
//声明为指针
void reverse_array2(int *arr, int size)
{
for (int i = 0; i < size / 2; i++)
{
int temp = arr[i];
arr[i] = arr[size - i - 1];
arr[size - i - 1] = temp;
}
}
int main()
{
int a1[5];
int a2[5];
for (int i = 0; i < 5; i++)
{
a1[i] = i;
a2[i] = i;
}
//翻转数组
reverse_array1(a1, 5);
reverse_array2(a2, 5);
//打印输出
for (int i = 0; i < 5; i++)
{
printf("数组a1第%d个元素是%d \t", i, a1[i]);
printf("数组a2第%d个元素是%d \n", i, a2[i]);
}
system("pause");
return 0;
}
Printout:
As can be seen from the above example, the two initializations are equivalent in effect. But to be more accurate, you should use pointers. Because the actual parameter is actually a pointer, not an array.
1.8 Initialization
When the initialization of an array is local to a function (or block of code), you should carefully consider whether it is worthwhile to reinitialize the array every time the execution flow of the program enters that function (or block of code). If the answer is no, declare the array as static so that the initialization of the array only needs to be performed once before the program starts.
Regarding the static keyword, you can refer to this article: Detailed explanation of static keyword (C/C++)
1.9 Incomplete initialization
The so-called incomplete initialization means that when initializing the array, if we only assign values to some elements, then the remaining elements will automatically be assigned 0
. You can refer to the following code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a1[5] = {
0,1};
//打印输出
for (int i = 0; i < 5; i++)
{
printf("数组a1第%d个元素是%d \n", i, a1[i]);
}
system("pause");
return 0;
}
Print output:
You can see that several elements that have not been initialized will be automatically initialized to 0, butThis automatic initialization is limited. It can only automatically assign values to the following elements, but not the front and middle elements.
1.10 Automatically calculate array length
If the array is initialized when it is defined, there is no need to specify the array length. Refer to the following example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a1[] = {
0,1};
//打印输出
printf("数组a1的大小是%d \n", sizeof(a1) / sizeof(int));
system("pause");
return 0;
}
Printout:
1.11 Initialization of character array
There are two initialization methods for character arrays. One is conventional initialization, such as:
char a1[] = {
'0','1'};
There is another way, which is convenient and fast, which is similar to how strings are defined:
char a2[] = "01";
In fact, the two are not completely equivalent. In the second initialization method, there is an extra ' \0
' by default, so array a2 has 3 elements. You can refer to the following test code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char a1[] = {
'0','1'};
char a2[] = "01";
//打印输出
printf("数组a1的大小是%d \n", sizeof(a1) / sizeof(char));
printf("数组a2的大小是%d \n", sizeof(a2) / sizeof(char));
system("pause");
return 0;
}
Print output:
The data type string does not exist in the C language. Instead, a character array is used to save the string.
2. Multidimensional array
Multidimensional arrays are arrays of two or more dimensions, with two-dimensional arrays being the most commonly used. What needs to be paid attention to is the storage order of the elements of multi-dimensional arrays. And how to access elements, etc.
When a multi-dimensional array appears, it will be a slightly more difficult problem to use pointers or a combination of pointers and subscripts to access array elements.
2.1 Storage order
In C language, the storage order of elements of a multi-dimensional array follows the principle that the rightmost subscript changes first, which is calledrow main order。
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COL 8
int main()
{
int matrix[ROW][COL];
int *p = &matrix[0][0];
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
matrix[i][j] = i * ROW + j;
}
}
//打印输出
printf("第一个值是%d \n", *p);
printf("第二个值是%d \n", *++p);
printf("第三个值是%d \n", *++p);
system("pause");
return 0;
}
Print output:
As can be seen from the above example, when the pointer grows, it points to the elements of the array in the order of the rightmost change first. When a line of scanning ends, it will automatically point to the next line and continue accessing.
2.2 Array name
The value of a one-dimensional array name is a pointer constant pointing to aelement, and the element of the first dimension of the multidimensional array is another array. For example the following statement:
int matrix[3][10];
It can be regarded as a one-dimensional array, containing 3
elements, each element is 10
an array containing integer elements.
Or you can read the subsequent chapters of this article, and you will understand it naturally after you slowly understand it.
2.3 Subscript
If you want to identify an element of a multidimensional array, you must provide a subscript for each dimension in the same order as the array is declared, and each dimension must be enclosed in a separate pair of square brackets.
#include <stdio.h>
#include <stdlib.h>
#define ROW 8
#define COL 3
int main()
{
int matrix[ROW][COL];
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
matrix[i][j] = i * COL + j;
}
}
//打印输出
printf("第一个值是:%d \n", **matrix);
printf("第二个值是:%d \n", *(*(matrix + 1)));
printf("第三个值是:%d \n", *(*(matrix) + 2));
printf("第四个值是:%d \n", *(*(matrix + 1) + 2));
system("pause");
return 0;
}
The above example may be a little difficult. You can figure it out by carefully considering the direction of the pointer movement.
2.4 Pointers to arrays
How should a pointer to a multidimensional (two-dimensional) array be defined?
int matrix[ROW][COL] = {
{
0,1,2},{
3,4,5}};
int(*p)[COL] = matrix;
We define a pointer p, pointing to an COL
array with n elements. When p is added to an integer value, the integer value is first adjusted to the length of the integer value before the addition is performed. See the example below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 2
#define COL 3
int main()
{
//定义二维数组
int matrix[ROW][COL] = {
{
0,1,2},{
3,4,5}};
//定义指向数组的指针
int(*p)[COL] = matrix;
//打印输出
printf("(*(*p))的值为:%d \n",(*(*p)));
printf("(*(*p + 1))的值为:%d \n", *(*(p + 1)));
printf("(*(*p) + 1的值为:%d \n", (*(*p) + 1));
printf("(*(*p + 1) + 1)的值为:%d \n", *(*(p + 1) + 1));
system("pause");
return 0;
}
Printout:
It can be seen that if you directly use the p pointer to perform indirect access, you will definitely access the 0th element ( (*(*p))
) in row 0. When adding 1 directly to p, a one-dimensional array is moved, and then accessed indirectly, so what is obtained is the 0th element in row 1 of the array, which is such an expression; but if accessed *(*(p + 1))
indirectly After adding 1 once, the first accessed is row 0 of the two-dimensional array. Adding 1 will naturally be the first element of row 0, which is the above expression; the last expression ( ) is naturally self (*(*p) + 1)
- *(*(p + 1) + 1)
evident .
2.5 Multidimensional arrays as function parameters
When a multidimensional (two-dimensional) array is used as a function parameter, the function declaration is also different from that of a one-dimensional array. There are two declaration methods:
Method 1:
void func1(int(*mat)[5])
Way 2:
void func2(int mat[][5])
These two declaration methods are equivalent in effect, and both are acceptable. This can be proven from the following program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 3
#define COL 5
//声明方式1
void func1(int(*mat)[5])
{
int add = 1;
printf("在函数func1中\n");
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
mat[i][j] += 10;
printf("数组的第%d个元素是:%d\n", add, mat[i][j]);
add++;
}
}
}
//声明方式2
void func2(int mat[][5])
{
int add = 1;
printf("在函数func2中\n");
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
mat[i][j] += 10;
printf("数组的第%d个元素是:%d\n", add, mat[i][j]);
add++;
}
}
}
int main()
{
//定义二维数组
int matrix1[ROW][COL];
int matrix2[ROW][COL];
//定义累加变量
int add = 1;
//数组初始化
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
matrix1[i][j] = i * COL + j;
matrix2[i][j] = i * COL + j;
printf("数组1的第%d个元素是:%d \t", add, matrix1[i][j]);
printf("数组2的第%d个元素是:%d \n", add, matrix1[i][j]);
add++;
}
}
printf("-----------------");
//函数调用
func1(matrix1);
printf("-----------------");
func2(matrix2);
system("pause");
return 0;
}
Print output: In the above example, two two-dimensional arrays are
defined , initialized in the same way, and then passed to two functions for processing. The two functions only have different declaration methods of formal parameters. 3*5
The two functions add 10 to each element of the original array and obtain the same result.
Therefore, these two declaration methods are equivalent in effect.
2.6 Initialization
There are two common forms of initialization of multidimensional (two-dimensional) arrays.
- One is to directly assign a stored value to each element
- One is to separate each dimension with curly braces and assign a value
Both methods are correct, but the second method has two advantages:
- Good for reading
- To facilitate initialization, several values at the end of each sub-initialization list can be omitted (incomplete initialization list).
Refer to the procedure below:
#include <stdio.h>
#include <stdlib.h>
#define ROW 2
#define COL 3
int main()
{
//初始化形式1
int matrix1[ROW][COL] = {
0,1,2,3,4,5};
//初始化形式2
int matrix2[ROW][COL] = {
{
0,1,2},{
3,4,5}};
int add = 1;
//打印输出
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("matrix1的第%d个值为%d \t", add, matrix1[i][j]);
printf("matrix2的第%d个值为%d \n", add, matrix2[i][j]);
add++;
}
}
system("pause");
return 0;
}
Print output:
As can be seen from the above example, these two forms are consistent in terms of implementation effects.
2.7 Automatic calculation of array length
In multidimensional arrays, only the first 1
dimension is provided by default based on the initialization list. The remaining dimensions must be written out explicitly so that the compiler can infer the length of each subarray dimension. For example:
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COL 5
int main()
{
int matrix3[][5] = {
{
0,1,2},{
3,4,5},{
6,7,8}};
int add = 1;
//打印输出
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("matrix1的第%d个值为%d \t", add, matrix3[i][j]);
add++;
}
printf("\n");
}
system("pause");
return 0;
}
Print output:
So even if the value of the first dimension is not written at this time, the compiler can automatically infer the value of the dimension based on the initialized value and the curly braces when running.
3. Pointer array
Pointer arrays are easy to understand, that is, the elements in an array are pointers. As for what kind of data the pointers point to, it is defined by the user.
For example, in the following example, a pointer array is used to store pointers to strings (more strictly speaking, character arrays).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 3
#define COL 5
char const *keyword[] = {
"do","for"};
int main()
{
int add = 1;
//打印输出
char const desired_word[] = "do";
char const **p;
for (p = keyword; p < keyword + 2; p++)
{
if (strcmp(desired_word, *p) == 0)
{
printf("YES");
system("pause");
return 0;
}
}
printf("NO");
system("pause");
return 0;
}
The printout is as follows:
In the above example, an array is used to store an array of pointers to several character arrays. Then the matching function of multiple strings is implemented.
Or it can be implemented using a two-dimensional array, but the size of the longest string needs to be known in advance.
4. Summary
The relationship between arrays and pointers cannot be explained clearly in one or two sentences. It needs to be slowly experienced and understood during specific development.
The elements of an array can be accessed through subscripts and pointers , and pointers are often more efficient.
Pointer arrays are also commonly used in development, and array elements not only point tostring (character array), which may also point toStructure variableand other data types.
----------------------------------------------------------------end----------------------------------------------------------------