当前位置:网站首页>【C】 (written examination questions) pointer and array, pointer
【C】 (written examination questions) pointer and array, pointer
2022-07-05 00:18:00 【Xin Xiangrong】
Blog home page : Xin Xiangrong
Series column :【 from 0 To 1,C Language learning 】
A short sentence : If you are in full bloom , Butterflies come !
Blog description : Do what you can , Write every blog , Help yourself familiarize yourself with what you have learned , I also hope these contents can help some partners on the way of learning , If errors and deficiencies are found in the article , Also hope to leave a message in the comment area , We communicate progress together !
List of articles
Preface
This blog focuses on the understanding and application of pointers and arrays , Master these topics , The understanding and understanding of pointers and arrays will be greatly improved !
One . Written questions about pointers and arrays
- The meaning of array names :
- sizeof( Array name ), The array name here represents the entire array , It calculates the size of the entire array .
- & Array name , The array name here represents the entire array , It takes out the address of the entire array .
- In addition, all array names represent the address of the first element .
- strlen and sizeof The difference between :
- strlen Is to find the length of the string , Focus on... In the string \0, The calculation is \0 The number of characters that appear before
strlen It's a library function , For strings only
- sizeof Only pay attention to the size of memory space , Don't care what's in the memory
sizeof It's the operator
- Understand the topic correctly :
Understanding of this part ,sizeof(&…) It calculates the size of a pointer type , That's the address , The size of the address is 32 Bit environment (x86) Next is 4 byte , stay 64 Bit environment (x64) yes 8 byte ; But corresponding to the following example , You can't just understand the printed results , It is more important to understand whose address this address is ; Also understanding strlen When calculating the length of a string , Also have a correct understanding of the address !
1. One dimensional array
#include<stdio.h>
int main()
{
int a[] = {
1,2,3,4 };
printf("%d\n", sizeof(&a + 1));//4/8
//&a What we get is the address of the array
//&a The corresponding pointer type is int(*)[4]
//&a+1 Is from an array a The address of skipped a backward (4 An integer element ) Size of array
//&a+1 Or the address , Yes, the address is 4/8 byte
printf("%d\n", sizeof(&a[0]));//4/8
//&a[0] It's the address of the first element
// It calculates the size of the address
printf("%d\n", sizeof(&a[0] + 1));//4/8
//&a[0]+1 Is the address of the second element
// Size is 4/8 Bytes
//&a[0]+1 ---> &a[1]
printf("%d\n", sizeof(a));//16
//sizeof( Array name ), The array name represents the entire array , It calculates the size of the entire array , Unit is byte
printf("%d\n", sizeof(a + 0));//4
//a Not alone sizeof Inside , No address ,
// therefore a Is the address of the first element ,a+0 Or the address of the first element
// It's the address , Size is 4/8 Bytes
printf("%d\n", sizeof(*a));//4
//*a Medium a Is the address of the first element of the array ,*a Is to dereference the address of the first element , What you find is the first element
// The first element type is an integer , Size is 4 Bytes
printf("%d\n", sizeof(a + 1));
// there a Is the address of the first element of the array
//a+1 Is the address of the second element
//sizeof(a+1) Is the size of the address
printf("%d\n", sizeof(a[1]));//4
// It calculates the size of the second element
printf("%d\n", sizeof(&a));//4/8
//&a The address of the extracted array , Address of array , It's also an address
printf("%d\n", sizeof(*&a));//16
// The first 1 Two ways of understanding
//&a----> int(*)[4]
//&a What you get is the address of the array name , The type is int(*)[4], Is an array pointer
// Array pointer dereference finds an array
//*&a ---> a
//
// The first 2 Two ways of understanding
//& and * Offset
//*&a ---> a
return 0;
}
Running results :
2. A character array
#include<stdio.h>
int main()
{
char arr[] = {
'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//6
//sizeof( Array name ), Calculate the size of the entire array
printf("%d\n", sizeof(arr + 0));//4/8
//arr + 0 Is the address of the first element of the array
printf("%d\n", sizeof(*arr));//1
//*arr Is the first element of the array , Size is 1 byte
//*arr --> arr[0]
//*(arr+0) --> arr[0]
printf("%d\n", sizeof(arr[1]));//1
// Calculate the size of the second element of the array
printf("%d\n", sizeof(&arr));//4/8
//&arr Is the address of the array , Yes, the address is 4/8 Bytes
printf("%d\n", sizeof(&arr + 1));//4/8
//&arr + 1 Is the address after the array
printf("%d\n", sizeof(&arr[0] + 1));//4/8
//&arr[0] + 1 Is the address of the second element
return 0;
}
Running results :
#include<stdio.h>
#include <string.h>
int main()
{
char arr[] = {
'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));// Random value
// No, '\0' As an end sign
printf("%d\n", strlen(arr + 0));// Random value
//printf("%d\n", strlen(*arr));//--> strlen('a');-->strlen(97);// Wild pointer
// The program will report an error
//printf("%d\n", strlen(arr[1]));//-->strlen('b')-->strlen(98);
printf("%d\n", strlen(&arr));// Random value
printf("%d\n", strlen(&arr + 1));// Random value -6
printf("%d\n", strlen(&arr[0] + 1));// Random value -1
return 0;
}
Running results :
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abcdef";
//[a b c d e f \0]
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
//printf("%d\n", strlen(*arr));//err
// Wild pointer , The program will report an error
//printf("%d\n", strlen(arr[1]));//err
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));// Random value
printf("%d\n", strlen(&arr[0] + 1));//5
return 0;
}
Running results :
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
//[a b c d e f \0]
printf("%d\n", sizeof(arr));//7
printf("%d\n", sizeof(arr + 0));//4/8
printf("%d\n", sizeof(*arr));//1
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
return 0;
}
Running results :
#include<stdio.h>
int main()
{
char* p = "abcdef";
printf("%d\n", sizeof(p));//4/8
printf("%d\n", sizeof(p + 1));//4/8
printf("%d\n", sizeof(*p));//1
printf("%d\n", sizeof(p[0]));//1
printf("%d\n", sizeof(&p));//4/8
printf("%d\n", sizeof(&p + 1));//4/8
printf("%d\n", sizeof(&p[0] + 1));//4/8
return 0;
}
Running results :
#include<stdio.h>
#include<string.h>
int main()
{
char* p = "abcdef";
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
//printf("%d\n", strlen(*p));// Wild pointer , Report errors
//printf("%d\n", strlen(p[0]));// Wild pointer , Report errors
printf("%d\n", strlen(&p));// Random value
printf("%d\n", strlen(&p + 1));// Random value
// because p The address of 4/8 Lattice byte , Undetermined '\0' Will it appear in it
// Therefore, it is impossible to infer the relationship between these two random values
// The difference between these two random values is also a random value
printf("%d\n", strlen(&p[0] + 1));//5
//p[0]-->*(p+0)
return 0;
}
Running results :
3. Two dimensional array
#include<stdio.h>
int main()
{
int a[3][4] = {
0 };
printf("%d\n", sizeof(a));//48
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//16
//a[0] Is the array name of this one-dimensional array in the first line ,
// Put it alone sizeof Inside ,a[0] Represents the first entire one-dimensional array ;
//sizeof(a[0]) Calculate the size of the first row
printf("%d\n", sizeof(a[0] + 1));//4/8
//a[0] Not alone in sizeof Inside , I didn't take the address ,a[0] It means the address of the first element
// Is the address of the first element of the first row of this one-dimensional array ,
//a[0] + 1 Is the address of the second element in the first line
printf("%d\n", sizeof(*(a[0] + 1)));//4
//a[0] + 1 Is the address of the second element in the first line
//*(a[0] + 1)) It's the second element in the first line
printf("%d\n", sizeof(a + 1));//4/8
//a Although it is the address of a two-dimensional array , But it is not placed alone sizeof Inside , I didn't take the address
//a Represents the address of the first element , The first element of a two-dimensional array is its first row ,a It's the address on the first line
//a+1 Just skip the first line , Indicates the address of the second line
printf("%d\n", sizeof(*(a + 1)));//16
//*(a + 1) Is the dereference of the address in the second line , I got the second line
//*(a+1)-->a[1]
//sizeof(*(a+1))-->sizeof(a[1])
printf("%d\n", sizeof(&a[0] + 1));//4/8
//&a[0] - Address the array name in the first row , Take out the address on the first line
//&a[0]+1 - What you get is the address on the second line
printf("%d\n", sizeof(*(&a[0] + 1)));//16
printf("%d\n", sizeof(*a));//16
//a Represents the address of the first element , It's the address on the first line
//*a Is the dereference of the address in the first line , What you get is the first line
printf("%d\n", sizeof(a[3]));//16
// There will be no cross-border visits ,sizeof What I care about in calculation is a[3] The type of
// Will not really visit a[3], Calculate it and a[0] It's the same
printf("%d\n", sizeof(a[0]));//16
return 0;
}
Running results :
Two . Written test questions about pointer
topic 1:
#include <stdio.h>
int main()
{
int a[5] = {
1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);
printf("%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
Running results :
analysis :
&a+1 What you get is the address after the array , Cast this address as int * type , And assign it to int * Type of prt, here * prt Only the space of one shaping element can be accessed ;
*(a+1) Medium a Is the address of the first element of the array ,a + 1 Is the address of the second element of the array , because prt There is only one access to the shaping space ,prt - 1 Get the address of the last element of the array .
topic 2:
#include <stdio.h>
// It is known that , stay 32 Bit environment (x86)
// Structure Test The variable size of type is 20 Bytes
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}* p = (struct Test*)0x100000;
// hypothesis p The value of is 0x100000; What are the values of the expressions in the following table ?
int main()
{
printf("%p\n", p + 0x1);
//0x100000+20-->0x100014
printf("%p\n", (unsigned long)p + 0x1);
//1,048,576+1 --> 1,048,577
//0x100001
printf("%p\n", (unsigned int*)p + 0x1);
//0x100000+4-->0x100004
return 0;
}
Running results :
analysis :
p The type of struct Test * ,p+1 Skip a structure (20 byte ) The size of the space ,20 Turn it into 16 Hexadecimal is 14;
unigned int Is an unsigned integer , Carry out shaping operation ;
take p The structure pointer type forces the type to be converted to unigned int* type , here p+1 skip 4 Bytes
topic 3:
#include <stdio.h>
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;
}
Running results :
analysis :
prt1 Is the address after the array , The type is int * ,prt1[-1]–>*(prt-1),prt-1 Skip four bytes forward ;
Cast the address of the first element of the array into an integer , here + 1 It's a shaping operation ; then + 1 The result after is cast to int Type assigned to prt2, here prt2 yes a Skip back one byte address ,* prt2 visit 4 Bytes of content ,
And in the vs In the environment , The data adopts the small end storage mode , It's stored upside down , Look at the picture below to understand :
%x With 16 Print in hexadecimal form .
topic 4:
#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;
}
Running results :
analysis :
This question has a deceptive point , The initialization in the question uses ( ) instead of { } ; And the title ( ) In is a comma expression ;
So the contents of the array are actually equivalent to int a[3][2] = {1,2,3};
topic 5:
#include <stdio.h>
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;
}
Running results :
analysis :
a Is the address of the first element of a two-dimensional array , That is, the address of the first row of the two-dimensional array , The type of int ( * ) [5], have 5 Bytes of access ; Assign to p,p The type of int ( * )[4], have 4 Bytes of access ;
The pointer - The number of elements between two pointers calculated by the pointer , High address - The result of a low address is an integer , The opposite is negative ; Refer to the following figure to understand :
It can be observed from the figure that , The number of elements between two addresses is 4, Low address - High address , So it should be - 4;
Put the result in %p and %d Print ;%d The printed result is - 4;
take - 4 Print in the form of an address ;%p It can be understood as an unsigned number , Find out - 4 The complement of is converted to 16 It can be done in decimal ;
Original code :10000000 00000000 00000000 00000100
Inverse code :11111111 11111111 11111111 11111011
Complement code :11111111 11111111 11111111 11111100
Hexadecimal complement :ff ff ff fc
topic 6:
#include <stdio.h>
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;
}
Running results :
analysis :
&aa+1 Get the address after the array , Cast it to int * type , Assign a value to prt1, here prt1 have 4 Bytes of access ; therefore prt1-1 Get the address of the last element of the array ;
aa+1( amount to &arr[1]) Get the address of the second row of the two-dimensional array ,* *(aa+1) Get the second line ( amount to * &aa[1]–>aa[1]); here ** (aa + 1 ) There is no & Or put it in sizeof in , So at this time, it is equivalent to the address of the first element in the second row of the array , The forced type conversion here belongs to confusing behavior , Is it all the same ; Assign it to prt2,prt2-1 It is the address of the last element in the first line !
topic 7:
#include <stdio.h>
int main()
{
char* a[] = {
"work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
Running results :
analysis :
It's more intuitive to look at the picture , as follows ,
topic 8:
#include <stdio.h>
int main()
{
char* c[] = {
"ENTER","NEW","POINT","FIRST" };
char** cp[] = {
c + 3,c + 2,c + 1,c };
char*** cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *-- * ++cpp + 3);
printf("%s\n", *cpp[-2] + 3);
printf("%s\n", cpp[-1][-1] + 1);
return 0;
}
Running results :
analysis :
it is to be noted that , Such as :++cpp, Will cpp The value of itself changes ; and cpp+1 Will not change cpp In itself ; Pay attention to the distinction , Prevent confusion when doing questions , The specific understanding is shown in the figure below :
Conclusion :
Dear friends , It's fate to see here , I hope my content can bring you a little help , If you can, support it for three times !!! Thank you for coming here , We can learn and communicate together , Progress together !!! come on. !!!
边栏推荐
- 同事的接口文档我每次看着就头大,毛病多多。。。
- P4281 [ahoi2008] emergency assembly / gathering (LCA)
- Go step on the pit - no required module provides package: go mod file not found in current directory or any parent
- Illustrated network: what is gateway load balancing protocol GLBP?
- Tester's algorithm interview question - find mode
- Face recognition 5- insight face padding code practice notes
- 城市轨道交通站应急照明疏散指示系统设计
- 2022.07.03(LC_6111_统计放置房子的方式数)
- 【路径规划】RRT增加动力模型进行轨迹规划
- P4408 [NOI2003] 逃学的小孩(树的直径)
猜你喜欢
What did I pay for it transfer to testing post from confusion to firmness?
Fast analysis -- easy to use intranet security software
[paper reading] Tun det: a novel network for meridian ultra sound nodule detection
如何有效对直流列头柜进行监测
2022.07.03(LC_6111_统计放置房子的方式数)
How to use fast parsing to make IOT cloud platform
Learning of basic amplification circuit
企业公司项目开发好一部分基础功能,重要的事保存到线上第一a
[path planning] RRT adds dynamic model for trajectory planning
Detailed explanation of openharmony resource management
随机推荐
uniapp微信小程序拿来即用的瀑布流布局demo2(方法二)(复制粘贴即可使用,无需做其他处理)
2022.07.03(LC_6109_知道秘密的人数)
P4281 [AHOI2008]紧急集合 / 聚会(LCA)
IELTS examination process, what to pay attention to and how to review?
[paper reading] cavemix: a simple data augmentation method for brain vision segmentation
It's too convenient. You can complete the code release and approval by nailing it!
用快解析内网穿透实现零成本自建网站
A new method for analyzing the trend chart of London Silver
JS how to realize array to tree
Meet ThreadPoolExecutor
城市轨道交通站应急照明疏散指示系统设计
Some basic functions of enterprise projects are developed, and important things are saved to online first a
模板的进阶
go踩坑——no required module provides package : go.mod file not found in current directory or any parent
业务实现-日志写到同一个行数据里面
【雅思阅读】王希伟阅读P3(Heading)
Best practice case of enterprise digital transformation: introduction and reference of cloud based digital platform system security measures
Actual combat simulation │ JWT login authentication
How to save your code works quickly to better protect your labor achievements
Significance of acrel EMS integrated energy efficiency platform in campus construction