当前位置:网站首页>【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. !!!
边栏推荐
- abc 258 G - Triangle(bitset)
- 圖解網絡:什麼是網關負載均衡協議GLBP?
- 模板的进阶
- Hologres Query管理及超时处理
- Some basic functions of enterprise projects are developed, and important things are saved to online first a
- 使用快解析搭建自己的minecraft服务器
- 22-07-02周总结
- Life is changeable, and the large intestine covers the small intestine. This time, I can really go home to see my daughter-in-law...
- How to do the project of computer remote company in foreign Internet?
- Ap8022 switching power supply small household appliances ACDC chip offline switching power supply IC
猜你喜欢
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
What did I pay for it transfer to testing post from confusion to firmness?
A new method for analyzing the trend chart of London Silver
公司要上监控,Zabbix 和 Prometheus 怎么选?这么选准没错!
两个数相互替换
P3304 [sdoi2013] diameter (diameter of tree)
lambda expressions
Hash table, hash function, bloom filter, consistency hash
abc 258 G - Triangle(bitset)
「运维有小邓」域密码策略强化器
随机推荐
2022.07.03(LC_6108_解密消息)
How to save your code works quickly to better protect your labor achievements
业务场景功能的继续修改
abc 258 G - Triangle(bitset)
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
ORB(Oriented FAST and Rotated BRIEF)
机器人强化学习——Learning Synergies between Pushing and Grasping with Self-supervised DRL (2018)
Mit-6.824-lab4b-2022 (10000 word idea explanation - code construction)
挖财学院开户安全的吗?开户怎么开?
如何在外地外网电脑远程公司项目?
Réseau graphique: Qu'est - ce que le Protocole d'équilibrage de charge de passerelle glbp?
华为200万年薪聘请数据治理专家!背后的千亿市场值得关注
TS快速入门-函数
积分商城游戏设置的基本要点
How many triangles are there in the golden K-line diagram?
跨域请求
go踩坑——no required module provides package : go.mod file not found in current directory or any parent
How to reduce the stock account Commission and stock speculation commission? Is it safe to open an online account
Business implementation - the log is written to the same row of data
Remember to build wheels repeatedly at one time (the setting instructions of obsidian plug-in are translated into Chinese)