当前位置:网站首页>【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. !!!
边栏推荐
- 初识ROS
- P3304 [SDOI2013]直径(树的直径)
- Introduction to ACM combination counting
- 人生无常,大肠包小肠, 这次真的可以回家看媳妇去了。。。
- How to use fast parsing to make IOT cloud platform
- Hisilicon 3559 universal platform construction: YUV422 pit stepping record
- Summary of week 22-07-02
- Acwing164. Accessibility Statistics (topological sorting +bitset)
- Huawei employs data management experts with an annual salary of 2million! The 100 billion market behind it deserves attention
- 同事的接口文档我每次看着就头大,毛病多多。。。
猜你喜欢
The waterfall flow layout demo2 (method 2) used by the uniapp wechat applet (copy and paste can be used without other processing)
Get to know ROS for the first time
URLs and URIs
Verilog tutorial (11) initial block in Verilog
Every time I look at the interface documents of my colleagues, I get confused and have a lot of problems...
图解网络:什么是网关负载均衡协议GLBP?
华为200万年薪聘请数据治理专家!背后的千亿市场值得关注
他做国外LEAD,用了一年时间,把所有房贷都还清了
lambda expressions
abc 258 G - Triangle(bitset)
随机推荐
Business implementation - the log is written to the same row of data
P3304 [SDOI2013]直径(树的直径)
Is it safe to open an account in the College of Finance and economics? How to open an account?
模板的进阶
【雅思阅读】王希伟阅读P4(matching2段落信息配对题【困难】)
AcWing164. 可达性统计(拓扑排序+bitset)
Hisilicon 3559 universal platform construction: YUV422 pit stepping record
青海省国家湿地公园功能区划数数据、全国湿地沼泽分布数据、全国省市县自然保护区
How to effectively monitor the DC column head cabinet
Using the uniapp rich text editor
OpenHarmony资源管理详解
URLs and URIs
【报错】 “TypeError: Cannot read properties of undefined (reading ‘split‘)“
跨域请求
打新债开户注册安全吗?有没有风险的?靠谱吗?
Go pit - no required module provides Package: go. Mod file not found in current directory or any parent
如何用快解析自制IoT云平台
同事的接口文档我每次看着就头大,毛病多多。。。
P4408 [noi2003] truant children (tree diameter)
Face recognition 5- insight face padding code practice notes