Explicación detallada de la matriz bidimensional y la función de comparación de qsort

Este artículo se resumió al hacer el tema # 524 de LeetCode, principalmente para compensar los tres aspectos de la matriz bidimensional, el método de almacenamiento de cadenas múltiples y el uso de qsort.

# 524. Coincide con la palabra más larga del diccionario eliminando letras

 

Tipo de pregunta

Doble puntero

Resumen

1. Sobre el uso de la matriz bidimensional

  • El concepto de una matriz bidimensional: una matriz bidimensional es similar a una matriz unidimensional, excepto que sus elementos de matriz son matrices unidimensionales De hecho, un [0], un [1] ... son las primeras direcciones de una matriz unidimensional. Para comprender el concepto de una matriz bidimensional, debe comprender el modelo de memoria de una matriz bidimensional, por int a[4][3]ejemplo,
    [___|___|___][___|___|___][___|___|___][___|___|___]
    ^            ^            ^            ^               
    a           a+1           a+2          a+3          int **
    a[0]        a[1]          a[2]         a[3]         int *
    a[0][0]     a[1][0]       a[2][0]      a[3][0]      int
    下标与指针的关系和一维数组相同:            
    a[1] = *(a+1)  a[2] = *(a+2) ...                           
    a[1][1] = *(a[1]+1)  a[1][2] = *(a[1]+2) ...         
  • Tenga en cuenta que las direcciones de un [0] y un elemento de matriz a [0] [0] son ​​numéricamente iguales, pero no son del mismo tipo de dirección (puntero)
  • El nombre de matriz de una matriz bidimensional: en el int a[3][4]nombre de matriz a es un puntero a la primera matriz unidimensional, (a + 1) apunta a la segunda ... y a [0] = * (a + 0) = * a es el nombre de la matriz de la primera matriz unidimensional, a [1] = * (a + 1) es el nombre de la matriz de la segunda matriz unidimensional ...
  • ¿Cómo declarar un puntero a una matriz entera? : int (*p)[4], Aquí debe especificar el número de elementos de la matriz a los que desea apuntar, para que pse pueda realizar el desplazamiento correcto durante la operación, como p++aumentar la dirección 4*sizeof(int). Puede usar el puntero a la matriz para operar en la matriz bidimensional, como
    int a[3][4];
    int (*p)[4] = a;
    p++;
    ...
    Si desea que un puntero acceda a los elementos en la matriz bidimensional uno por uno, puede declararlo así: int *p = &a[0][0]oint *p = a[0]
  • Cuando se utiliza una matriz multidimensional como parámetro de función, ¿cómo declarar el parámetro de función correspondiente? : El nombre de la matriz multidimensional como parámetro de función se transfiere de la misma manera que una matriz unidimensional: la transferencia real es un puntero al primer elemento de la matriz. Primero observe el caso en el que el nombre de matriz de una matriz unidimensional se utiliza como parámetro de función:
    int a[10];
    ...
    func1( a );
    Aquí, el prototipo de función de func1 puede ser cualquiera de los siguientes 2 tipos:
    void func1( int *vec );
    void func1( int vec[] );
    Mire la situación de la matriz bidimensional:
    int b[4][10]
    ...
    func2( b );
    La función prototipo de func2 se puede declarar de la siguiente manera:
    void func2( int (*mat)[10] );
    void func2( int mat[][10] );
    Tenga en cuenta que la siguiente declaración es incorrecta: void func2( int **mat );. Aunque el nombre de la matriz bidimensional pertenece al puntero al puntero, apunta al puntero (primera dirección) de la matriz unidimensional, que contiene la naturaleza de la matriz unidimensional: el número de elementos y el int **mat;puntero a la variable entera (dirección ) Si el nombre de la matriz de dos dimensiones bpasado a la función void func2( int **mat )se genera cuando la operación aritmética realizada problema estera: mat++sólo la dirección compensado sizeof(int), lo que equivale a una matriz estera b [4] [1], si es así void func2( int (*mat)[10] );, a continuación, mat++se abordará compensado 10*sizeof(int).
  • ¿Cómo almacenar un conjunto de cadenas? : Hay dos métodos, uno es usar una matriz de punteros, la declaración y la inicialización son las siguientes:
    char *ps[] = { "just", "do", "it" };
    O
    char *ps[3] = { "just", "do", "it" };
    Con este método, los elementos de la matriz son punteros a cadenas individuales, y el 3*sizeof(char *)
    otro método es utilizar una matriz bidimensional. La declaración y la inicialización son las siguientes:
    char s[3][10] = { "just", "do", "it" };
    Usando este método, el contenido de la cadena se almacena en una matriz bidimensional, el tamaño del espacio ocupado es 3*10*sizeof(char), este método ocupa más espacio, especialmente cuando la longitud de la cadena es muy diferente, habrá mucho espacio desperdiciado.
  • ¿Cuál es el valor de sizeof (nombre de matriz)? : Aunque el nombre de la matriz es un puntero, sizeof (nombre de la matriz) no son los bytes ocupados por un puntero, sino el número de bytes ocupados por toda la matriz. Por ejemplo:
    char s[10][10];
    int i = sizeof( s );
    El valor de i es 100, no 32 (determinado por el número específico de punteros)

2. Acerca de la definición de la función cmp en
qsort qsort se utiliza para ordenar los elementos de la matriz. El prototipo de la función es void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));donde compar es la función de comparación. La función qsort pasará los punteros de los dos elementos de la matriz para compararlos y procederá de acuerdo con su valor de retorno. Ordenar Dado que el puntero del elemento se pasa a la función de comparación, su implementación interna generalmente tiene la siguiente forma:

int compareMyType (const void * a, const void * b)
{
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}

Es decir void *, el puntero del tipo debe convertirse de nuevo al tipo de puntero del elemento de matriz, y luego compararse, como la ordenación de matrices de enteros:

int compar( const void *a, const void *b )
{
    return ( *(int*)a - *(int*)b );  //从小到大排序
}
int a[4] = { 3, 1, 4, 5 };
qsort( a, 4, sizeof(int), compar );

Otro ejemplo es la comparación de matrices de cadenas:

int compar( const void *a, const void *b )
{
    //注意,由于比较的是二维数组的元素,因此qsort传递给
    //compar的是数组元素的指针,也就是各一维数组的指针,
    //其类型和二维数组名相同,为指向字符数组的指针,其
    //声明方式为:char (*p)[5],因此类型转换为(char (*)[5]),
    //由于strcmp需要的是字符串的指针,因此需要解引用。
    //强制转换后a的类型为指向字符数组的指针,因此解引用
    //后类型为字符数组的数组名(首地址),也是字符串指针
    //,于是就可以给strcmp使用了。
    return strcmp( *(char (*)[5])a, *(char (*)[5])b );
}
char a[3][5] = { "go", "to", "do" };
qsort( a, 3, 5*sizeof(char), compar );

Otro ejemplo es la ordenación de matrices de punteros de caracteres (literales de cadena):

int compar( const void *a, const void *b )
{
    //由于数组元素为字符指针类型,传递给
    //compar的是字符指针的指针(地址),
    //因此应先转换回类型char **
    return strcmp( *(char **)a, *(char **)b );
}
char *a[3] = { "go", "to", "do" };
qsort( a, 3, sizeof(char *), compar );

Supongo que te gusta

Origin www.cnblogs.com/uestcliming666/p/12728742.html
Recomendado
Clasificación