[Key Points of C Language (1)] The "grievances and hatreds" of two-dimensional arrays, pointers and functions


1. Understanding of two-dimensional arrays

(1) Understanding of two-dimensional array array[i] and array[i][j]

  • Two-dimensional array: essentially an array with arrays as array elements, that is, an "array of arrays". Also called a matrix, when the number of rows and columns is equal, it is called a square matrix.
  • array[i]: represents the address (address, address, address) of the one-dimensional array in the i-th row of the two-dimensional array.
  • array[i] [j]: represents the value of the element in row i and column j of the two-dimensional array.
#include <stdio.h>
int main() {
    
    
    int array[3][4] = {
    
    
            {
    
    1,2,3,4},
            {
    
    5,6,7,8},
            {
    
    9,10,11,12},
    };
    /* 1.array[i]是每一行的数组(一维)的地址 */
    int i,j;
    for(i=0;i<3;i++){
    
    
        printf("%p\n",array[i]);
    }
    /* 2.array[i][j]是每一行数组(一维)的值 */
    for(i=0;i<3;i++){
    
    
        for(j=0;j<4;j++){
    
    
            printf("%d  ",array[i][j]);
        }
        putchar('\n');
    }
    return 0;
}

Insert image description here

(2) Understanding of array[i]+j, *array[i]+j

  • array[i]+j: The address of the i-th row and j-th column of the two-dimensional array

  • *array[i]+j: The value of the address of the i-th row and j-th column of the two-dimensional array

    注意:*array[i]+j和*(array[i]+j)写法不同,表示意思相同

#include <stdio.h>
int main() {
    
    
    int array[3][4] = {
    
    
            {
    
    1,2,3,4},
            {
    
    5,6,7,8},
            {
    
    9,10,11,12},
    };
    /* 1.array[i]+j:二维数组的i行第j列的地址 */
    /* 2.*array[i]+j:二维数组第i行第j列的地址的值(元素的值) */
    /* PS:*array[i]+j和*(array[i]+j)意思一样(*和+运算符优先级一样,遵循从右往左计算) */
    int i,j;
    for(i=0;i<3;i++){
    
    
        for(j=0;j<4;j++){
    
    
            printf("%d\t",*array[i]+j);
        }
        putchar('\n');
    }
    return 0;
}

Insert image description here

(3) Understanding of the two-dimensional array name array

在前面一维数组的认知中,我们知道数组名就是数组的首地址,可以通过数组首地址来操作数组元素。同样地,在二维数组中,二维数组名array也表示二维数组的首地址,只是该地址存放的是每一组一维数组的首地址。也就是说,二维数组名是一个存放其一维数组首地址的地址("地址的地址")。所以array[i]也可以写成*(array+i);array[i]+j可以写成(*(array+i))+j;可以理解成以array为基地址,*(array+i)偏移i得到第i行的首地址,(*(array+i))+j再偏移j得到第i行第j列元素的地址;或许有亿点点绕,亿点点晕,继续体会下面的代码吧

  • Array: Two-dimensional array name, which is the address that stores the first address of its one-dimensional array (although the two-dimensional array name is somewhat similar to the second-level pointer in understanding, the two-dimensional array name is not different from the second-level pointer)
#include <stdio.h>
int main() {
    
    
    int array[3][4] = {
    
    
            {
    
    1,2,3,4},
            {
    
    5,6,7,8},
            {
    
    9,10,11,12},
    };
    int i,j;
    for(i=0;i<3;i++){
    
    
        for(j=0;j<4;j++){
    
    
           printf("%d\t",*array[i]+j);	//写法一
           printf("%d\t",*(*(array+i))+j);	//写法二(输出结果可以看到,两种写法等价)
        }
        putchar('\n');
    }
    return 0;
}

Insert image description here

2. Various "forms" of pointers

(1) Array pointer

  • Array pointer: A pointer to an array, that is, the address pointing to the first address of the array. (In fact, it is similar to the array mentioned above)

  • int (*p)[4] = array (array is the name of a two-dimensional array): Define a pointer variable pointing to the first address of a two-dimensional array with four elements.

    (二维数组实质上同一维数组一样,在内存中的地址空间连续,可以通过指针进行操作)

  • Output the specified row and column elements in the two-dimensional array according to the row and column values ​​input by the user, which requires the use of array pointers.

#include <stdio.h>

void getInput(int *i,int *j){
    
    
    printf("请输入行、列值(从1开始):");
    scanf_s("%d %d",i,j);
    printf("input done\n");
}

int findTargetValue(int (*p)[4],int i,int j){
    
    
    int targetValue;
//    targetValue = p[i][j];
    targetValue = *(*(p+i))+j;
    return targetValue;
}

int main() {
    
    
    int array[3][4] = {
    
    
            {
    
    1,2,3,4},
            {
    
    5,6,7,8},
            {
    
    9,10,11,12},
    };
    int i,j;
    int targetValue;
    getInput(&i,&j);
    targetValue = findTargetValue(array,i-1,j-1);
    printf("矩阵%d行%d列的数据是:%d",i,j,targetValue);
    return 0;
}

Insert image description here

(2) Function pointer

【2-1】Understanding of function pointers
  • Function pointer: A pointer to a function, a pointer variable that stores the address of the function.
  • Definition: int (*p)(const char *format, …);
  • Assignment (initialization so that it points to a function - the function name is also the address): p = printf;
  • Call: (*p)(“Hello World”);
#include <stdio.h>
int main() {
    
    
    int (*p)(const char *format, ...) =  printf;
    (*p)("Hello World\n");
    return 0;
}

Insert image description here

【2-2】Application of function pointers
  • Application: According to different situations during program running, different functions are called (similar to the interface in Java) +
  • Example: There are two integers a and b. The user inputs 1, 2 or 3. If you input 1, the program will give the larger of a and b. If you input 2, it will give the smaller of a or b. If you input 3, it will find a and b. of and.
#include <stdio.h>
#include <stdlib.h>

int getMax(int data1,int data2){
    
    
    return data1>data2 ? data1:data2;
}
int getMin(int data1,int data2){
    
    
    return data1<data2 ? data1:data2;
}
int getSum(int data1,int data2){
    
    
    return (data1+data2);
}

int getCommandAndHandle(int data1,int data2,int (*p)(int, int)){
    
    
    int choise = 0;
    printf("请输入1-取大值、2-取小值、3-求和:\n");
    scanf_s("%d",&choise);
    switch (choise) {
    
    
        case 1:
            p = getMax;
            break;
        case 2:
            p = getMin;
            break;
        case 3:
            p = getSum;
            break;
        default:
            printf("error\n");
            exit(-1);
    }
    return (*p)(data2,data1);
}

int main() {
    
    
    int data1 = 10;
    int data2 = 20;
    int result;
    int (*command)(int, int) = NULL;
    result = getCommandAndHandle(data1,data2,command);
    printf("%d\n",result);
    return 0;
}

  • Linux thread creation function: int pthread_create(pthread_t *th, const pthread_attr_t *attr, void ( func)(void *), void *arg);

    And the underlying logic of C++ QT's signal and slot callback functions - function pointer implementation.

3. "Stupidly unclear" about arrays, pointers and functions

Insert image description hereInsert image description here

(1) Pointer array

  • Pointer array: An array whose elements are all pointer type variables is called a pointer array (① is an array; ② array elements are pointers)

  • How to define: a pointer array with 4 integer variable elements: int *p[4]

    区别前面的数组指针int (*p)[4],可以知道优先级[]比*高

(2) Function pointer array

  • Array of function pointers: ① is an array; ② array elements are pointers; ③ pointers point to the address of the function

  • How to define: int (*p[4])(int,int)

    优先级:() > [] > *;到了这里,优先级对理解记忆这些东西显得十分关键

  • Example: Pass in two values ​​and output the maximum value, minimum value and the sum of the two numbers (array of function pointers).

#include <stdio.h>

int getMax(int data1,int data2){
    
    
    return data1>data2 ? data1:data2;
}
int getMin(int data1,int data2){
    
    
    return data1<data2 ? data1:data2;
}
int getSum(int data1,int data2){
    
    
    return (data1+data2);
}

void getAllResult(int data1,int data2,int (*p[3])(int,int)){
    
    
    printf("Max  Min  Sum\n");
    for(int i=0;i<3;i++){
    
    
        printf("%d   ",(*p[i])(data1,data2));
    }
}

int main() {
    
    
    //函数指针
    //int (*p)(int,int);
    //函数指针数组
    int (*p[3])(int,int) = {
    
    getMax, getMin, getSum};
    getAllResult(88,99,p);
    return 0;
}

Insert image description here

(3) Pointer function

  • Pointer function: a function whose return value is a pointer type (① is a function; ② the function return value is a pointer)
  • Definition: int *p(int i,int j)
  • Outputs the elements of a column of a given two-dimensional array (matrix) based on a user-specified row number.
#include <stdio.h>

int *findTargetSubArray(int (*parray)[4],int target){
    
    
    return (int *)parray+target;
}
int main() {
    
    
    int array[3][4] = {
    
    
            {
    
    11,22,33,44},
            {
    
    55,66,77,88},
            {
    
    99,110,220,330},
    };
    int targetNumber;
    int *subArray;
    puts("输入要查询的行号(0-2)");
    scanf_s("%d",&targetNumber);
    subArray = findTargetSubArray(array,targetNumber);
    for (int i = 0; i < 4; i++) {
    
    
        printf("%d ",*subArray++);
    }
}

Insert image description here

(4) Definitions of various "demons" (classic written test questions):

  • It is recommended to copy it to the IDE and practice it.

1. Define an integer
2. Define a pointer to an integer
3. Define a pointer to a pointer that points to an integer
4. Define an array of 10 integers
5. Definition An array of 10 pointers, each pointing to an integer.
6. Define a pointer to an array of 10 integers.
7. Define a pointer to a pointer. The pointed pointer points to an array of 10 integers. Array of type
8. Define a pointer to the array, there are 10 integer pointers in the array
9. Define a pointer to the function, the function has only one integer parameter and returns an integer
10. Define a pointer with 10 An array of pointers. Each array points to a function. The function has only one integer parameter and returns an integer. 11.
Define a function pointer. The function pointed to has two integer parameters and returns a function pointer. The returned function pointer Pointer to a function that takes an integer parameter and returns an integer

定义一个整型数 int a;
定义一个指向整型数的指针 int *a;
定义一个指向指针的指针,它指向的指针指向一个整型数 int **a;
定义一个有10个整型数的数组 int a[10];
定义一个有10个指针的数组,每个指针指向一个整型数 int *p[10];
定义一个指向有10个整型数的数组的指针 int (*p)[10];
定义一个指向指针的指针,被指向的指针指向一个有10个整型数的数组 int *(*p)[10];() / int (**a)[10];(对)
定义一个指向数组的指针,数组中有10个整型指针 int *((*p1)[10]);(我的答案) / int *(*p2)[10];(参考答案)
定义一个指向函数的指针,该函数只有一个整型参数且返回一个整型数 int (*p)(int);
定义一个有10个指针的数组,每个数组指向一个函数,该函数只有一个整型参数且返回一个整型数 int (*p[10])(int);
定义一个函数指针,指向的函数有两个整型参数且返回一个函数指针,返回的函数指针指向有一个整型参数且返回整型数的函数 int(* (*p)(int,int))(int)
  • Regarding question 8: I really don’t understand question 8. I still think int *(( *p1)[10]); and int *( *p2)[10]; are the same. I hope someone can shed some light on this!

Insert image description here

Guess you like

Origin blog.csdn.net/weixin_54429787/article/details/129371459