当前位置:网站首页>【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. !!!
边栏推荐
- Life is changeable, and the large intestine covers the small intestine. This time, I can really go home to see my daughter-in-law...
- Application of multi loop instrument in base station "switching to direct"
- 两个数相互替换
- 青海省国家湿地公园功能区划数数据、全国湿地沼泽分布数据、全国省市县自然保护区
- Chinese verification of JS regular expressions (turn)
- How to do the project of computer remote company in foreign Internet?
- Hologres Query管理及超时处理
- Data on the number of functional divisions of national wetland parks in Qinghai Province, data on the distribution of wetlands and marshes across the country, and natural reserves in provinces, cities
- URL和URI
- js如何实现数组转树
猜你喜欢
企业公司项目开发好一部分基础功能,重要的事保存到线上第一a
[IELTS reading] Wang Xiwei reads P4 (matching2 paragraph information matching question [difficult])
ORB(Oriented FAST and Rotated BRIEF)
Microservice
如何有效对直流列头柜进行监测
"Xiaodeng" domain password policy enhancer in operation and maintenance
ORB(Oriented FAST and Rotated BRIEF)
【雅思阅读】王希伟阅读P4(matching2段落信息配对题【困难】)
js如何实现数组转树
[kotlin] the third day
随机推荐
如何避免电弧产生?—— AAFD故障电弧探测器为您解决
Detailed explanation of openharmony resource management
Mit-6.824-lab4b-2022 (10000 word idea explanation - code construction)
abc 258 G - Triangle(bitset)
「运维有小邓」域密码策略强化器
[Peking University] tensorflow2.0-1-opening
Paper notes multi UAV collaborative monolithic slam
How to effectively monitor the DC column head cabinet
两个数相互替换
How to do the project of computer remote company in foreign Internet?
Go step on the pit - no required module provides package: go mod file not found in current directory or any parent
URL和URI
Cross domain request
【监控】zabbix
Réseau graphique: Qu'est - ce que le Protocole d'équilibrage de charge de passerelle glbp?
Huawei employs data management experts with an annual salary of 2million! The 100 billion market behind it deserves attention
【路径规划】RRT增加动力模型进行轨迹规划
(脚本)一键部署redis任意版本 —— 筑梦之路
Design of emergency lighting evacuation indication system for urban rail transit station
如何将自己的代码作品快速存证,已更好的保护自己劳动成果