Preguntas de prueba escrita avanzadas de Pointer

Insertar descripción de la imagen aquí
Hoy estoy compartiendo las preguntas del examen escrito sobre punteros. Creo que después de leer este artículo, comprenderás en profundidad los punteros. Estudiemos.
Lo primero que debemos compartir es la relación entre punteros y matrices. Todos sabemos que el nombre de la matriz es la dirección del primer elemento, así que echemos un vistazo a la relación entre matrices unidimensionales y punteros.

//一维数组
int a[] = {
    
     1,2,3,4 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(a[1]));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
printf("%d\n", sizeof(&a[0]));
printf("%d\n", sizeof(&a[0] + 1));

Debemos tener en cuenta algunas reglas para estas preguntas. La primera es que el nombre del array es la dirección del primer elemento. Sólo hay dos excepciones. Una es el operador sizeof. Debemos recordar que no es una función. Y la otra es que a menudo vemos que los dos operadores de toma de direcciones (&) que obtenemos se utilizan para extraer toda la matriz, y los demás son solo la dirección del primer elemento, así que echemos un vistazo a la pregunta ahora.

int a[] = {
    
     1,2,3,4 };
printf("%d\n", sizeof(a));
//这里a在sizeof内部,是单独出现的,所以表示整个数组的大小,因为sizeof单位是字节
//所以大小就是16,一个int是4个字节
printf("%d\n", sizeof(a + 0));
a不是单独出现,所以表示数组首元素的大小,这里加0就还是数组首元素的地址,所以就是4或者8个字节大小

printf("%d\n", sizeof(*a));
//这里的a就是表示首元素的地址,我们对它解引用,那就是第一个元素,所以这里就表示第一个元素的大小

printf("%d\n", sizeof(a + 1));
//a表示数组首元素的地址,所以加1就是跳过一个int,但是本质还是地址,所以还是4/8个字节
printf("%d\n", sizeof(a[1]));
表示第二个元素,是整型,所以就是4个字节
printf("%d\n", sizeof(&a));
&取出的就是整个数组,就是这个数组的地址,是地址大小就是4/8个字节的大小
printf("%d\n", sizeof(*&a));
*&就相当于加减,所以这里就表示sizeof(a)就是整个数组的大小,所以大小就是16
printf("%d\n", sizeof(&a + 1));
我们先取出a的地,表示真个数组的地址,然后加一跳过的就是整个数组,相当于是4后面的地址,是地址就是4/8

printf("%d\n", sizeof(&a[0]));
是地址就是4/8
printf("%d\n", sizeof(&a[0] + 1));
取出第一个元素的地址然后我们加1,那么就是第二个元素的地址,但是他的本质还是地址,是地址答案就是4/8

De hecho, estos problemas se pueden resolver siempre que domines algunas reglas. Por ejemplo, necesitas saber que el nombre de la matriz es el tamaño del primer elemento, y necesitas saber que sizeof y & sacan el tamaño del toda la matriz Estos problemas se pueden resolver.

//字符数组
char arr[] = {
    
     'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr + 0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr + 1));
printf("%d\n", sizeof(&arr[0] + 1));
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));

Echemos un vistazo al problema de las matrices de caracteres por las mismas razones que antes.

//字符数组
char arr[] = {
    
     'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));
还是一样的道理,首先是数组名单独出现在sizeof中,所以表示的就是整个数组的大小
char的大小就是一个字节大小,所以答案就是6
printf("%d\n", sizeof(arr + 0));
arr就是首元素的地址,所以加上0还是首元素的地址,是地址大小就是4/8个字节的大小
printf("%d\n", sizeof(*arr));
arr不是单独出现,所以这里表示的就是首元素的地址,那么对它解引用就是第一个元素
那答案就是一个字节大小
printf("%d\n", sizeof(arr[1]));
这里就是数组索引,表示的就是第二个元素,所以大小也是1个字节
printf("%d\n", sizeof(&arr));
是地址就是4/8
printf("%d\n", sizeof(&arr + 1));
地址4/8
printf("%d\n", sizeof(&arr[0] + 1));
地址4/8
printf("%d\n", strlen(arr));
strlen统计的是'\0'之前的,因为我们这里数组结尾并没有\0所以是随机数
printf("%d\n", strlen(arr + 0));
这里也是一样的
printf("%d\n", strlen(*arr));
这里表示的是第一个元素,但是我们strlen的参数是指针,所以这里表示错误
printf("%d\n", strlen(arr[1]));
表示错误
printf("%d\n", strlen(&arr));
随机数

Podemos comprobar el strlen aquí en cplusplsu.

Insertar descripción de la imagen aquí
En la imagen podemos ver que su parámetro es un puntero de tipo char, por lo que significa que solo puede recibir punteros. Cuando recibimos int, el compilador informará un error.


int main()
{
    
    
	char* p = "abcdef";

	printf("%d\n", strlen(p));
	printf("%d\n", strlen(p + 1));
	printf("%d\n", strlen(*p));
	printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));
	printf("%d\n", strlen(&p + 1));
	printf("%d\n", strlen(&p[0] + 1));
}

Echemos un vistazo a este tema. En primer lugar, p no almacena esta cadena constante. Debería almacenar la dirección del primer elemento de a. Entonces será más fácil de entender cuando lo operemos. Echemos un vistazo.


	//printf("%d\n", sizeof(p));//4/8 计算的是指针变量的大小
	//printf("%d\n", sizeof(p + 1));//p+1还是地址,大小是4/8个字节
	//printf("%d\n", sizeof(*p));//1个字节, *p == 'a'
	//printf("%d\n", sizeof(p[0]));//1个字节, p[0]--> *(p+0) --> *p == 'a';

 //	printf("%d\n", sizeof(&p));//4/8个字节,&p 是地址
	//printf("%d\n", sizeof(&p + 1));//&p是地址,&p+1还是地址,是地址就是4/8个字节

	//printf("%d\n", sizeof(&p[0] + 1));
	因为p是数组首元素的地址,其实它的意思就可以是数组名,那我们取出的就是第一个地址元素的地址,然后我们对它进行加1,那么就是的哥元素的地址,是地址大小就是4/8

Después de ver las matrices unidimensionales, echemos un vistazo a la cuestión de las matrices bidimensionales. Las matrices bidimensionales son en realidad matrices de matrices unidimensionales.

/二维数组
int a[3][4] = {
    
     0 };
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a[0][0]));
printf("%d\n", sizeof(a[0]));
printf("%d\n", sizeof(a[0] + 1));
printf("%d\n", sizeof(*(a[0] + 1)));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(*(a + 1)));
printf("%d\n", sizeof(&a[0] + 1));
printf("%d\n", sizeof(*(&a[0] + 1)));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(a[3]));

El primer elemento de la matriz es 0 y el contenido de la matriz siguiente son valores aleatorios.

//二维数组
int a[3][4] = {
    
     0 };
printf("%d\n", sizeof(a));
首先是a是数组名,说过数组名是首元素的地址,但是由于是二维数组,所以这里的意思就是第一行的地址
类型可不是int 而是int (*)[4],所以这里的意思就是第一行的大小,那就是16个字节
printf("%d\n", sizeof(a[0][0]));
表示第一个元素的大小,所以大小就是4个字节
printf("%d\n", sizeof(a[0]));
表示的是第一行的数组名,所以这里的大小也是16
printf("%d\n", sizeof(a[0] + 1));
a[0]就是第一行的数组名,数组名就是首元素的大小,加一就是第一行第二个元素的地址,是地址就是4/8
printf("%d\n", sizeof(*(a[0] + 1)));
a[0]就是第一行的数组名,数组名就是首元素的地址,加一就是第一行第二个元素大小,所以解引用就是一个整型
大小就是4个字节
printf("%d\n", sizeof(a + 1));
表示第二行的大小,因为a是第一行的地址,加1跳过的是一行,所以就是第二行的地址,那大小
就是4/8个字节大小
printf("%d\n", sizeof(*(a + 1)));
解引用出来应该第二行的所有数据,所以大小就是16个字节
printf("%d\n", sizeof(&a[0] + 1));
因为a[0]表示第一行的数组名,所以取地址应该是第一行,是整个第一行,然后进行加1那么就是第二行
的地址,是地址大小就是4/8
printf("%d\n", sizeof(*(&a[0] + 1)));
根据上面的分心,这是第二行的地址,所以解引用是整个第二行,那大小就是16个字节大小

printf("%d\n", sizeof(*a));、
a是数组名,表示第一行的地址,那么解引用就是第一行,大小就是16个字节
printf("%d\n", sizeof(a[3]));
这里a[3]虽然看起来越界了,但是其实没有,我们这里还是可以理解为它是个数组名,因为数组名单独出现在sizeof当中,那么
表示的就是16个字节大小

Sigamos viendo algunas preguntas de la prueba escrita a continuación.

int main()
{
    
    
	int a[5] = {
    
     1, 2, 3, 4, 5 };
	int* ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));
	return 0;
}

De hecho, después de leer lo anterior, esta pregunta se siente un poco como matar un pollo con un cuchillo. Jajaja.
Primero, hay un símbolo para tomar la dirección delante de a. Luego sacamos la dirección completa de la matriz a. y luego agregarlo, lo que significa saltar a la posición 5.
Hay un lugar de tamaño int en la parte posterior, por lo que la respuesta es 2, 5

//程序的结果是什么?
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
    
    
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
    
    
	printf("%p\n", p + 0x1);
	printf("%p\n", (unsigned long)p + 0x1);
	printf("%p\n", (unsigned int*)p + 0x1);
	return 0;
}

Continuaremos analizando este tema más adelante. De hecho, tenemos un artículo sobre la alineación del tamaño de la estructura. Si está interesado, puede leerlo. Luego le diré que el tamaño es 20 bytes, 0x significa hexadecimal y luego\p Es la impresión de la dirección. Veamos primero el primero. El primero es sumar 1 al tamaño del tipo de estructura. La suma es 20. Luego 20 se representa con 14 en hexadecimal, por lo que la respuesta es 0x10014. . Lo siguiente es un poco engañoso. , lo que podemos ver no está firmado. No os dejéis engañar aquí pensando que lo que se suma es 8. De hecho, amarlo es suma y resta de enteros. Lo que se suma es el número 1. La respuesta aquí es 0x100001. A continuación, continúa leyendo. Aquí simplemente agregamos un tamaño entero, por lo que la respuesta es 0x100004.

int main()
{
    
    
	int a[4] = {
    
     1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	return 0;
}

Esta pregunta también es muy engañosa. La primera es muy simple. &a es sacar toda la matriz. Luego, lo que saltamos al agregar 1 es el tamaño de toda la matriz, que apunta a la dirección después de 4, ptr[- 1 ] es *(ptr-1), luego usamos %x, que también es la dirección de impresión, que es nuestro 4, por lo que es 00000004, pero lo siguiente no está aquí, primero se fuerza a convertir a en un número entero, porque a es la dirección del primer elemento,
Insertar descripción de la imagen aquí
entonces si sumamos uno y forzamos la conversión a un número entero, en realidad es equivalente a obtener 02 00 00 00 e imprimir 2000000

#include <stdio.h>
int main()
{
    
    
	int a[3][2] = {
    
     (0, 1), (2, 3), (4, 5) };
	int* p;
	p = a[0];
	printf("%d", p[0]);
	return 0;
}

Continuaremos viendo esta pregunta más adelante. Normalmente uso {} para matrices, pero aquí () representa una expresión de coma.
De hecho, el primer elemento de la matriz es 1 y la respuesta es 1.

int main()
{
    
    
	int a[5][5];
	int(*p)[4];
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	return 0;
}

Veamos esto. Esto es equivalente a puntero menos puntero. También sabemos que puntero menos puntero en realidad significa el número de elementos.
Debemos hacer un dibujo aquí.
Entonces uno es -4 impreso con %d, y el otro es el complemento de -4 y luego se convierte a hexadecimal. Me da pereza aquí porque voy a comer pronto jajaja

Todavía quedan tres preguntas y el editor ya se muere de hambre.

int main()
{
    
    
	int aa[2][5] = {
    
     1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	int* ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}

Echemos un vistazo a este problema: primero, sacamos la dirección de toda la matriz bidimensional y luego agregamos 1 para omitir la dirección de tamaño int después de 10. Nuestro ptr1-1 accede a 10. Continúe mirando aa, cuál es el primero Agregue 1 a la dirección de la fila para obtener la dirección de la segunda fila y luego conviértalo a int* ptr2-1, que es 5

#include <stdio.h>
int main()
{
    
    
	char* a[] = {
    
     "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

Este dibujo se puede escribir. Hagamos Ctrl+F5 para ver el resultado. No puedo soportarlo más. Quiero comer, así que no escribiré más.

Gracias a todos por compartir hoy. ¡Hasta la próxima! ! !

Supongo que te gusta

Origin blog.csdn.net/2301_76895050/article/details/132914785
Recomendado
Clasificación