"C and Pointers" Reading Notes (Chapter 8 Arrays)

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.
Insert image description here

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:
Insert image description here

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:
Insert image description here
As can be seen from the above program, the pointer p points to the 2element 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:
Insert image description here
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:
Insert image description here
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:
Insert image description here
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:
Insert image description here

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:
Insert image description here
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:
Insert image description here
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 3elements, each element is 10an 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;
}

Insert image description here
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 COLarray 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:
Insert image description here

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
Insert image description here
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*5The 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.

  1. One is to directly assign a stored value to each element
  2. One is to separate each dimension with curly braces and assign a value

Both methods are correct, but the second method has two advantages:

  1. Good for reading
  2. 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:
Insert image description here
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 1dimension 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:
Insert image description here
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:
Insert image description here
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----------------------------------------------------------------

Guess you like

Origin blog.csdn.net/weixin_43719763/article/details/130659740