Explicação detalhada da matriz bidimensional e da função de comparação do qsort

Este artigo foi resumido ao executar o tópico nº 524 do LeetCode, principalmente para compensar os três aspectos da matriz bidimensional, o método de armazenamento de várias seqüências de caracteres e o uso de qsort.

# 524. Combine a palavra mais longa no dicionário excluindo letras

 

Tipo de pergunta

Ponteiro duplo

Sumário

1. Sobre o uso da matriz bidimensional

  • O conceito de uma matriz bidimensional: uma matriz bidimensional é semelhante a uma matriz unidimensional, exceto que os elementos da matriz são matrizes unidimensionais.De fato, a [0], a [1] ... são os primeiros endereços de uma matriz unidimensional. Para entender o conceito de uma matriz bidimensional, você precisa entender o modelo de memória de uma matriz bidimensional, por int a[4][3]exemplo,
    [___|___|___][___|___|___][___|___|___][___|___|___]
    ^            ^            ^            ^               
    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) ...         
  • Observe que os endereços de um [0] e o elemento da matriz a [0] [0] são numericamente os mesmos, mas não são do mesmo tipo de endereço (ponteiro)
  • O nome da matriz de uma matriz bidimensional: No int a[3][4]nome da matriz, a é um ponteiro para a primeira matriz unidimensional, (a + 1) aponta para a segunda ... e a [0] = * (a + 0) = * a é o nome da matriz da primeira matriz unidimensional, a [1] = * (a + 1) é o nome da matriz da segunda matriz unidimensional ...
  • Como declarar um ponteiro para uma matriz inteira? : int (*p)[4], Aqui você deve especificar o número de elementos da matriz para os quais deseja apontar, para que po deslocamento correto possa ser executado durante a operação, como p++aumentar o endereço 4*sizeof(int). Você pode usar o ponteiro para a matriz para operar na matriz bidimensional, como
    int a[3][4];
    int (*p)[4] = a;
    p++;
    ...
    Se você deseja que um ponteiro acesse os elementos na matriz bidimensional, um por um, você pode declará-lo assim: int *p = &a[0][0]ouint *p = a[0]
  • Quando a matriz multidimensional é usada como parâmetro de função, como declarar o parâmetro de função correspondente? : O nome da matriz multidimensional como parâmetro de função é transferido da mesma maneira que uma matriz unidimensional - a transferência real é um ponteiro para o primeiro elemento da matriz. Primeiro, observe o caso em que o nome da matriz unidimensional é usado como parâmetro de função:
    int a[10];
    ...
    func1( a );
    Aqui, o protótipo de função de func1 pode ser um dos 2 tipos a seguir:
    void func1( int *vec );
    void func1( int vec[] );
    Veja a situação da matriz bidimensional:
    int b[4][10]
    ...
    func2( b );
    O protótipo de função de func2 pode ser declarado da seguinte maneira:
    void func2( int (*mat)[10] );
    void func2( int mat[][10] );
    Note-se que a seguinte declaração está errado: void func2( int **mat );. Embora o nome da matriz bidimensional pertença ao ponteiro para o ponteiro, ele aponta para o ponteiro (primeiro endereço) da matriz unidimensional, que contém a natureza da matriz unidimensional - o número de elementos e o int **mat;ponteiro para a variável inteira (endereço ) Se o nome da matriz bidimensional btransmitida para a função void func2( int **mat )é gerado quando a operação aritmética realizada problema esteira: mat++apenas o endereço de offset sizeof(int), que é equivalente a uma esteira matriz b [4] [1], em caso afirmativo void func2( int (*mat)[10] );, então mat++irá abordar Deslocamento 10*sizeof(int).
  • Como armazenar um conjunto de strings? : Existem dois métodos, um é usar uma matriz de ponteiros, a declaração e a inicialização são as seguintes:
    char *ps[] = { "just", "do", "it" };
    Ou
    char *ps[3] = { "just", "do", "it" };
    Usando esse método, os elementos da matriz são ponteiros para seqüências de caracteres individuais e o 3*sizeof(char *)
    outro método é usar uma matriz bidimensional.A declaração e a inicialização são as seguintes:
    char s[3][10] = { "just", "do", "it" };
    Usando esse método, o conteúdo da string é todo armazenado em uma matriz bidimensional, o tamanho do espaço ocupado é 3*10*sizeof(char), esse método ocupa mais espaço, especialmente quando o comprimento da string é muito diferente, haverá muito espaço desperdiçado.
  • Qual é o valor de sizeof (nome da matriz)? : Embora o nome da matriz seja um ponteiro, sizeof (nome da matriz) não são os bytes ocupados por um ponteiro, mas o número de bytes ocupados por toda a matriz. Por exemplo:
    char s[10][10];
    int i = sizeof( s );
    O valor de i é 100, não 32 (determinado pelo número específico de ponteiros)

2. Sobre a definição da função cmp no
qsort, o qsort é usado para classificar os elementos da void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));matriz.O protótipo da função é onde compar é a função de comparação.A função qsort passa os ponteiros dos dois elementos da matriz a serem comparados a ela e prossegue de acordo com seu valor de retorno. Classificar. Como o ponteiro do elemento é passado para a função compar, sua implementação interna geralmente tem a seguinte 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;
}

Ou seja void *, o ponteiro do tipo deve ser convertido novamente no tipo de ponteiro do elemento da matriz e depois comparado, como na classificação de matrizes inteiras:

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 );

Outro exemplo é a comparação de matrizes de string:

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 );

Outro exemplo é a classificação de matrizes de ponteiros de caracteres (literais de string):

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 );

Acho que você gosta

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