Resumen entre matrices y punteros unidimensionales/bidimensionales de C/C++

En primer lugar, lanzo la siguiente pregunta, lectores, si saben lo que significa, entonces este artículo no los ayudará, el autor también es un novato, pero recientemente estoy repasando los conceptos básicos de C, y de repente estaba confundido antes He resuelto el problema, así que escribo este blog aquí, no pido ayuda, solo pido que pueda revisarlo rápidamente en el futuro.

Observe cuidadosamente el problema en el siguiente código y observe la información de salida

#include <QDebug>

///一维数组
///问题1:为什么a1不能自增(报语法错误,根本编译不过去),而p1却可以自增呢?
///问题2:为什么a1和&a1的输出值是一样的呢?
void linearArray()
{
    int a[3] = {1277,2,3};
    int *p = a;
    p++;
    //a1++;
    qDebug() << a << &a << *p << *a;

/*
    0x66f918 0x66f918 2 1277
*/
}


///二维数组
///问题1:为什么 sizeof(a)的输出结果是48?
///问题2:为什么下面的第二条输出语句输出的内容全部一样?并且他们都有什么含义
///问题3:为什么第四条输出语句会是666 和 4?
///问题4:int * p3 = a;为什么会报错,为什么必须加强制类型转换后才能编译过去:int * p3 = (int*)a,以及为什么p3+=2后的输出是777?
void twoDimensionalArray()
{
    int a[3][4];
    a[0][0] = 555;
    a[0][1] = 666;
    a[0][2] = 777;
    a[1][0] = 888;
    qDebug() << sizeof(a);

    qDebug() << a << &a << a[0] << &a[0] << *a;

    qDebug() << sizeof (a[0]) << sizeof (*a);

    int * p2 = a[0];
    p2++;
    qDebug() << *p2 << sizeof(a[0])/sizeof(int);

    //int * p3 = a;语法错误?
    int * p3 = (int*)a;
    p3 += 2;//相当于两次自增
    qDebug() << *p3;

/*
输出信息:
    48
    0x12ffb9c 0x12ffb9c 0x12ffb9c 0x12ffb9c 0x12ffb9c
    16 16
    666 4
    777
*/
}

int main(int argc, char *argv[])
{
    linearArray();
    //twoDimensionalArray();
}

Primero, hablemos de arreglos unidimensionales:

        Los estudiantes que pueden conocer el lenguaje c saben que el nombre de la matriz en el lenguaje c es la primera dirección de la matriz.Mucha gente sabe que el nombre de la matriz no se puede autoincrementar , pero se puede autoincrementar después de asignarlo a un puntero del mismo tipo que su elemento (como la declaración a1++ y la declaración p1++ comentadas anteriormente).

Esto se debe a que el nombre del arreglo está en la función actual (la función que define el arreglo) Aunque su valor es la primera dirección del arreglo, su tipo (nombre del arreglo) no es un puntero , ¡sino un arreglo! Para ser precisos, ¡incluso puedes entenderlo como una constante! Esto también explica por qué ejecutar {sizeof(array name)➗sizeof(array element type)} en la función actual puede obtener la cantidad de elementos de la matriz, porque no es un puntero en absoluto, es una constante, pero el valor de este constante El valor es su primera dirección, y el tamaño de paso de esta constante (de hecho, el tamaño de paso no es exacto, el tamaño de paso sigue siendo desde la perspectiva del puntero, pero será fácil de entender) es su tamaño completo . Si realiza operaciones de autoincremento en constantes, es ilógico, i++ está bien, pero 3++ no, esa es la razón.

( pd: después de que el nombre de la matriz se pasa como parámetro, degenera en la dirección del primer elemento de la matriz . Pero sizeof no es una función, sino un operador, así que no se preocupe por degenerar en un puntero)

La razón por la cual el nombre de la matriz a1 puede incrementarse automáticamente después de asignarse al puntero p1 es que en realidad se le asigna la primera dirección del primer elemento de la matriz , pero la primera dirección del primer elemento es exactamente la misma que la primera dirección de la matriz. El tamaño del tipo de elemento al que apunta p1 es el tamaño de paso de p1, por lo que después de p1++, el primer elemento apunta al segundo elemento.

int * p1 = a1; Suele decirse que la primera dirección de la matriz se asigna al puntero p1, lo cual no es del todo exacto. Cabe decir que "asigne la dirección del primer elemento de este puntero al puntero p" es más preciso . En primer lugar, sabemos que el valor de la constante a1 es una dirección, simplemente asigna esta dirección a un puntero de tipo int, y el tamaño de paso de int es el tamaño de paso de un solo elemento de la matriz, por lo que debería cabe decir que el primer elemento de este puntero se asigna a p

En cuanto a &a es un puntero de matriz, si a se entiende como un todo, no como un puntero, &a es un puntero de matriz. Debido a que la dirección de a también es la primera dirección de la matriz, la salida es la misma, pero el tamaño de paso es el tamaño de paso de toda la matriz.

¿Por qué *a genera el primer elemento de la matriz? Debido a que lo anterior decía que el nombre de la matriz no es un puntero en esta función, sino una matriz completa, entonces, ¿por qué *nombre de la matriz obtiene el valor del primer elemento? Aquí hay una breve charla sobre el papel de "*" en la matriz. Se usa antes del nombre de la matriz como un operador de valor, que se usa para obtener el valor del primer elemento de la matriz . Es decir, *a == a[0], la razón de tirar este concepto es que me temo que la matriz bidimensional se mareará después (hace mucho tiempo que no uso el lenguaje C, y He olvidado el papel de * en la matriz, por la presente escríbalo).

Después de dominar las características de la matriz unidimensional mencionada anteriormente, veamos la matriz bidimensional:

Pregunta uno:

         Como una matriz unidimensional, consulte la matriz unidimensional anterior

Pregunta dos:

        a: a es el nombre de la matriz, y el valor del nombre de la matriz es la primera dirección de la matriz, por lo que se genera la primera dirección de la matriz. Pero el tipo de a es una matriz, no un puntero.

        &a: es un puntero de matriz, y el tamaño de paso es el tamaño de paso de toda la matriz bidimensional. Puede consultar la matriz unidimensional anterior

a[0]: es el nombre de la matriz del         primer elemento de a (también una matriz) . Esto también explica por qué la salida de qDebug() << sizeof (a[0]); es 16.

        &a[0]: como se mencionó anteriormente, puede usar a[0] como nombre de matriz, luego &a[0] significa la dirección del primer elemento de la matriz a[0], que es exactamente la solución a la pregunta tres sin explicación

        *a: Como se mencionó anteriormente, puede ver la explicación de * en la matriz unidimensional anterior, *a es el puntero de la matriz que representa la primera matriz unidimensional, es decir, puede considerar a aquí como uno- matriz dimensional, y *a es el nombre de la matriz de esta matriz unidimensional.

        Después de convertir a una matriz unidimensional, es fácil de entender, *a == a[0], lo que explica la tercera información de salida

Cuarta pregunta:

        Debido a que los tipos no coinciden, la asignación debe ser incorrecta, uno es un puntero de número entero y el otro es un tipo de matriz.

        Después de realizar la conversión de tipo obligatoria en el nombre de la matriz, el nombre de la matriz representa la primera dirección de la matriz, lo que equivale a asignar la dirección del primer elemento de la matriz al puntero p3, y el tamaño de paso de este puntero es el paso de modelado Largo, por lo que después de agregar dos pasos, la salida es 777

        

Supongo que te gusta

Origin blog.csdn.net/qq_25704799/article/details/127399223
Recomendado
Clasificación