Pointer advanced written test questions

Insert image description here
Today I am sharing the written test questions about pointers. I believe that after reading this article, you will have an in-depth understanding of pointers. Let’s study.
The first thing to share is the relationship between pointers and arrays. We all know that the array name is the address of the first element, so let us take a look at the relationship between one-dimensional arrays and pointers.

//一维数组
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));

We must keep some rules in mind for these questions. The first one is that the array name is the address of the first element. There are only two exceptions. One is the sizeof operator. We must remember that it is not a function. And the other one is that we often see The two address-taking operators (&) we get are used to take out the entire array, and the others are just the address of the first element. So let’s take a look at the question now.

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

In fact, these problems can be solved as long as you master some rules. For example, you need to know that the array name is the size of the first element, and you need to know that sizeof and & take out the size of the entire array. These problems can be solved.

//字符数组
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));

Let’s take a look at the problem of character arrays for the same reasons as above.

//字符数组
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));
随机数

We can check the strlen here on cplusplsu

Insert image description here
From the picture, we can see that its parameter is a pointer of type char, so it means that it can only receive pointers. When we receive int, the compiler will report an 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));
}

Let's take a look at this topic. First of all, p does not store this constant string. It should store the address of the first element of a. Then it will be easier to understand when we operate it. Let's take a look.


	//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

After looking at one-dimensional arrays, let's take a look at the question of two-dimensional arrays. Two-dimensional arrays are actually arrays of one-dimensional arrays.

/二维数组
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]));

The first element of the array is 0, and the contents of the subsequent array are random values.

//二维数组
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个字节大小

Let’s continue looking at some written test questions below

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

In fact, after reading the above, this question feels a bit like killing a chicken with a knife. Hahaha.
First, there is a symbol for taking the address in front of a. Then we take out the entire address of the array a, and then add it, which means jumping to
position 5. There is an int-sized place at the back, so the answer is 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;
}

We will continue to look at this topic later. We actually have an article about structure size alignment. If you are interested, you can read it. Then I will tell you that the size is 20 bytes, 0x means hexadecimal, and then\p It is the printing of the address. Let's look at the first one first. The first one is to add 1 to the size of the structure type. The addition is 20. Then 20 is represented by 14 in hexadecimal, so the answer is 0x10014. The following is a bit misleading. , what we can see is unsigned. Don’t be deceived here, thinking that what is added is 8. In fact, loving him is integer addition and subtraction. What is added is the number 1. The answer here is 0x100001. Next, continue reading. Here we just add an integer size, so the answer is 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;
}

This question is also very misleading. The first one is very simple. &a is to take out the entire array. Then what we skip by adding 1 is the size of the entire array, which points to the address after 4, ptr[- 1] is *(ptr-1), then we use %x which is also the print address, which is our 4, so it is 00000004, but the following is not here, a is first forced to be converted into an integer, because a is the address of the first element ,
Insert image description here
then if we add one and force the conversion into an integer, it is actually equivalent to getting 02 00 00 00 and printing 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;
}

Let's continue to look at this question later. I usually use {} for arrays, but here () represents a comma expression.
In fact, the first element of the array is 1, and the answer is 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;
}

Let's look at this. This is equivalent to pointer minus pointer. We also know that pointer minus pointer actually means the number of elements.
We must draw a picture here.
So one is -4 printed with %d, and the other is the complement of -4 and then converted into hexadecimal. I am lazy here because I am going to eat soon hahaha

There are still three questions left, and the editor is already starving to death.

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

Let's take a look at this problem. First, we take out the address of the entire two-dimensional array, and then add 1 to skip the int-sized address after 10. Our ptr1-1 accesses 10. Continue to look at aa, which is the first Add 1 to the address of the row to get the address of the second row, and then cast it to int* ptr2-1, which is 5

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

This drawing can be written out. Let's ctrl+F5 to see the result. I can't stand it anymore. I want to eat, so I won't write anymore.

Thank you everyone for sharing today. See you next time! ! !

Guess you like

Origin blog.csdn.net/2301_76895050/article/details/132914785