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 quep
o deslocamento correto possa ser executado durante a operação, comop++
aumentar o endereço4*sizeof(int)
. Você pode usar o ponteiro para a matriz para operar na matriz bidimensional, como
Se você deseja que um ponteiro acesse os elementos na matriz bidimensional, um por um, você pode declará-lo assim:int a[3][4]; int (*p)[4] = a; p++; ...
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:
Aqui, o protótipo de função de func1 pode ser um dos 2 tipos a seguir:int a[10]; ... func1( a );
Veja a situação da matriz bidimensional:void func1( int *vec ); void func1( int vec[] );
O protótipo de função de func2 pode ser declarado da seguinte maneira:int b[4][10] ... func2( b );
Note-se que a seguinte declaração está errado:void func2( int (*mat)[10] ); void func2( int mat[][10] );
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 oint **mat;
ponteiro para a variável inteira (endereço ) Se o nome da matriz bidimensionalb
transmitida para a funçãovoid func2( int **mat )
é gerado quando a operação aritmética realizada problema esteira:mat++
apenas o endereço de offsetsizeof(int)
, que é equivalente a uma esteira matriz b [4] [1], em caso afirmativovoid func2( int (*mat)[10] );
, entãomat++
irá abordar Deslocamento10*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:
Ouchar *ps[] = { "just", "do", "it" };
Usando esse método, os elementos da matriz são ponteiros para seqüências de caracteres individuais e ochar *ps[3] = { "just", "do", "it" };
3*sizeof(char *)
outro método é usar uma matriz bidimensional.A declaração e a inicialização são as seguintes:
Usando esse método, o conteúdo da string é todo armazenado em uma matriz bidimensional, o tamanho do espaço ocupado échar s[3][10] = { "just", "do", "it" };
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:
O valor de i é 100, não 32 (determinado pelo número específico de ponteiros)char s[10][10]; int i = sizeof( s );
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 );