Initial C language - explain the contents of the array and error-prone points in detail

Series Article Directory

 The first chapter  "C" Huzhuan - Getting to know C language for the first time (more suitable for beginners!)

 Chapter 2  has a detailed understanding of branch statements and loop statements and their error-prone points 

 Chapter 3  Beginners C—introducing functions in particular detail

 Chapter 4  Initial C Language——Explain in detail the content of arrays and error-prone points


Table of contents

Series Article Directory

foreword

1. Creation and initialization of one-dimensional array

1.1 Array creation

1.2 Array initialization

1.3 Use of one-dimensional arrays

 1.4 Storage of one-dimensional arrays in memory

Second, the creation and initialization of two-dimensional array 

2.1 Creation of two-dimensional array

2.2 Initialization of two-dimensional array

2.3 Use of two-dimensional arrays 

2.4 Storage of two-dimensional arrays in memory

3. Array out of bounds

 Fourth, the array as a function parameter

4.1 The wrong design of the bubble sort function 

4.2 What is the name of the array? 

4.3 Correct Design of Bubble Sort Function 

Summarize


foreword

       In the previous chapter, we have introduced the relevant content of functions in detail , learned what functions are, the classification of functions in C language, function parameters, calls, nested calls and chained access of functions, and function declarations And definition, function recursion.

       In this chapter, the editor will lead you to learn about arrays . Although the knowledge points of arrays are relatively small, we still need to study hard. From the title, we can see that we need to learn the knowledge of arrays in detail. I hope everyone Happy to see!


1. Creation and initialization of one-dimensional array

       The editor has been fascinated by arrays before. The first is that the subscript of the array starts from 0 , but don't be afraid, follow the steps of the editor and learn!

1.1 Array creation

       An array is a collection of elements of the same type . It must be remembered, because we will learn the structure later, and the structure can store a collection of elements of different types .   

How the array is created:

type_t arr_name [const_n]

type_t refers to the element type of the array

const_n is a constant expression used to specify the size of the array

       After understanding how to create an array, let's create an example of an array:

//代码1
int arrq[10];

//代码2
int count = 10;
int arr2[count];  //数组这样可以正常创建吗?

//代码3
char arr3[10];
float arr4[10];
double arr5[10];

       The situation of code 2 cannot be used in C language (before C99) , because the array is created before the C99 standard, and a constant must be given in [], and variables cannot be used. The C99 standard supports the concept of variable-length arrays. The size of the array can be specified using variables, but it must be remembered that variable-length arrays cannot be initialized .

1.2 Array initialization

Why talk about array initialization?

       Because if the local variable is not initialized, a random value is placed in the local variable ; if the global variable is not initialized, 0 is placed in the global variable . So initialization is very important.

Array initialization means : while creating an array, give some reasonable initial values ​​(initialization) to the contents of the array .

Array initialization is divided into : full initialization and incomplete initialization .

 Look at the code:

    int arr1[10] = { 1,2,3 };        //不完全初始化
	int arr2[] = { 1,2,3,4 };        //不完全初始化
	int arr3[5] = { 1,2,3,4,5 };     //完全初始化
	char arr4[3] = { 'a', 98, 'c' }; //完全初始化
	char arr5[] = { 'a', 'b', 'c' }; //不完全初始化
	char arr6[] = "abcdef";          //不完全初始化

       The full initialization of the array means that the array is filled when the number is given when the array is created ; the incomplete initialization of the array means that the array is not filled when the number is given when the array is created, and the remaining elements are initialized to 0 by default. ; Next, let's debug and verify.

       When the array is created, if you do not want to specify the definite size of the array, you have to initialize it . The number of elements in the array is determined according to the initialization content.

1.3 Use of one-dimensional arrays

       For the use of arrays , we introduced an operator before : [ ], the subscript reference operator . He is actually an operator for array access . Next, let's take a look at the code!

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };//数组的不完全初始化
    //计算数组的元素个数
	int sz = sizeof(arr) / sizeof(arr[0]);
    //对数组内容赋值,数组是使用下标来访问的,下标从0开始,所以:
	int i = 0; //做下标
	for (i = 0; i < sz; i++)
	{
		arr[i] = i;
	}
    //输出内容数据
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

       Here, I want to remind everyone: remember how to calculate the length of the array? But there is one situation where you should not use this method for calculation (the code is below) : this method will calculate the length of the entire array in sizeof(arr), not the length of the input array, and you can use it casually in other cases .

const int N = 10;
int arr[100];
for(int i = 0; i < N; i++)
{
    ...
}
int sz = sizeof(arr)/sizeof(arr[0]);

Summarize:

1) Arrays are accessed using subscripts , which start at 0 and increase by 1 in turn ;

2) The size of the array can be obtained by calculation .

 1.4 Storage of one-dimensional arrays in memory

       After discussing the use of one-dimensional arrays, let's discuss the storage of arrays in memory . Next, let's take a look at the code! (To mention here, the placeholder for the print address is: %p; for ease of observation, we change the environment to X86.)

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		arr[i] = i;
	}
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p\n", i, &arr[i]);
	}
	printf("\n");
	return 0;
}

 The output results are as follows:

       Carefully observe the output results, we know that as the array subscript increases, the address of the element also increases regularly. It can be concluded from this that the array is stored continuously in memory. (Convenient to use arrays in the memory area)


Second, the creation and initialization of two-dimensional array 


2.1 Creation of two-dimensional array

       In my opinion, the difference between a two-dimensional array and a one-dimensional array is that the two-dimensional array increases the relationship between rows and columns . Next, look at the creation of two-dimensional arrays.

//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];

2.2 Initialization of two-dimensional array

The editor remembers that the initialization of a two-dimensional array is more difficult than that of a one-dimensional array. There are several situations below:

int arr1[3][4] = { 1,2,3,4 };
int arr2[3][4] = { {1,2},{3,4} };//如果二维数组没有放满,则补0
int arr3[][4] = { {1,2},{5,4} };//二维数组如果有初始化,行可以省略,列不能省略

The above can be verified in the monitoring window below:

  

Why can there be curly braces in two-dimensional array initialization?

We can think of each row of a two-dimensional array as a one-dimensional array .

2.3 Use of two-dimensional arrays 

       The use of two-dimensional arrays is also through subscripts .In the imagination, two-dimensional arrays are a matrix,so two-dimensional arrays have their own row numbers and column numbers. We can use an element by row number and column number, just like coordinate system to access. Here is an example:

int arr[3][5] = {
    
    {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};

 Look at the code below:

int main()
{
	int arr[3][5] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			arr[i][j] = i * 4 + j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

2.4 Storage of two-dimensional arrays in memory

       After experiencing the above study of two-dimensional arrays, you may find that two-dimensional arrays are basically similar to one-dimensional arrays. Like a one-dimensional array, here we try to print the address of each element of the two-dimensional array . Next, let's take a look at the code! (Here again, the placeholder for the print address is: %p; for ease of observation, we change the environment to X86.)

int main()
{
	int arr[3][5] = { 0 };
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			arr[i][j] = i * 4 + j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		int j = 0;
		for (j = 0; j < 5; j++)
		{
			printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

 The output results are as follows:

       Through the analysis of the results, we can get that, in fact, the two-dimensional array is also stored continuously in the memory . Here we can see that the two-dimensional array is an array of one-dimensional arrays , which confirms this point.


3. Array out of bounds


       The subscript of the array is limited in scope; the subscript of the array is specified to start from 0, if the array has N elements, the subscript of the last element is N-1. Therefore, if the subscript of the array is less than 0, or greater than N-1, it means that the array is accessed out of bounds, and the access exceeds the legal space of the array. Rows and columns of two-dimensional arrays may also be out of bounds.

       The C language itself does not perform an out-of-bounds check for array subscripts, and the compiler does not necessarily report an error, but the fact that the compiler does not report an error does not mean that the program is correct. 

But if there is an assignment operation, the program will crash.

Therefore, when programmers write code, it is best to do a good job of cross-border checks. 


Fourth, the array as a function parameter


       Often when we write code, we will pass an array as a parameter into a function . Next, we will introduce the simplest sorting algorithm in the sorting algorithm—bubble sorting.

The algorithm idea of ​​bubble sorting: compare two adjacent elements, and sink the larger (smaller) ones to the bottom.

4.1 The wrong design of the bubble sort function 

Let's look at the code next:

void bubble_sort(int arr[])
{
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (int i = sz - 1; i >= 0; i++)
    {
        for (int j = 0; j < i; j++)
        {
            if (arr[j] > arr[j + 1])
            {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
int main()
{
    int arr[] = { 3,5,7,8,0,2,1,4,6,9 };
    bubble_sort(arr);
    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

       There is a problem with this code, so let's find out the problem: After debugging, we can see that the sz inside the bubble_sort function is 2 , not the value we want. Isn't the whole array passed when the array is used as a function parameter?

4.2 What is the name of the array? 

In order to solve the above problem, we explore the content of the array name: look at the following code:

Conclusion: The array name is the address. Generally speaking, the array name is the address of the first element of the array. 

        If the name of the array is the address of the first element, then the length of the array we learned before is different from this case. Look at the code:

Therefore, the array name does not necessarily represent the address of the first element, with two exceptions: 

  1. sizeof(array name) , calculate the size of the entire array, put an array name inside sizeof, the array name represents the entire array , and the unit is byte.
  2. &Array name , the address of the array is taken out. & array name. The array name refers to the entire array .

4.3 Correct Design of Bubble Sort Function 

       When an array is passed as a parameter, in fact, only the address of the first element of the array is passed. So even if it is written in the form of an array in the function parameter part: int arr[ ] still represents a pointer: int* arr . Well this also answers the question in 4.1: the result of sizeof(arr) is 8.

 So how do we change the function design? Look at the code below:

void bubble_sort(int arr[], int sz)//参数接受元素个数
{
    //代码同上面函数
}

int main()
{
    int arr[] = { 3,5,7,8,0,2,1,4,6,9 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    bubble_sort(arr, sz);
    for (int i = 0; i < sz; i++)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}

Summarize

       In this part, the editor writes a blog about arrays in detail. I hope everyone will leave a comment after reading it, thank you!

Guess you like

Origin blog.csdn.net/2301_77868664/article/details/132122070