当前位置:网站首页>【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. !!!
边栏推荐
- (script) one click deployment of any version of redis - the way to build a dream
- 【selenium自动化】常用注解
- 城市轨道交通站应急照明疏散指示系统设计
- Go pit - no required module provides Package: go. Mod file not found in current directory or any parent
- 积分商城游戏设置的基本要点
- Specification for fs4061a boost 8.4v charging IC chip and fs4061b boost 12.6V charging IC chip datasheet
- C语言中sizeof操作符的坑
- uniapp微信小程序拿来即用的瀑布流布局demo2(方法二)(复制粘贴即可使用,无需做其他处理)
- P3304 [sdoi2013] diameter (diameter of tree)
- 【报错】 “TypeError: Cannot read properties of undefined (reading ‘split‘)“
猜你喜欢
微服务(Microservice)那点事儿
In June, the list of winners of "Moli original author program" was announced! Invite you to talk about the domestic database
Detailed explanation of openharmony resource management
【雅思阅读】王希伟阅读P4(matching2段落信息配对题【困难】)
A new method for analyzing the trend chart of London Silver
Hisilicon 3559 universal platform construction: YUV422 pit stepping record
雅思考试流程、需要具体注意些什么、怎么复习?
Fs8b711s14 electric wine bottle opener MCU IC scheme development special integrated IC
Pytoch --- use pytoch to realize linknet for semantic segmentation
基于三维gis平台的消防系统运用
随机推荐
Go step on the pit - no required module provides package: go mod file not found in current directory or any parent
Best practice case of enterprise digital transformation: introduction and reference of cloud based digital platform system security measures
【路径规划】RRT增加动力模型进行轨迹规划
Cross domain request
What did I pay for it transfer to testing post from confusion to firmness?
[IELTS reading] Wang Xiwei reading P4 (matching1)
《论文笔记》Multi-UAV Collaborative Monocular SLAM
go踩坑——no required module provides package : go.mod file not found in current directory or any parent
abc 258 G - Triangle(bitset)
C语言中sizeof操作符的坑
uniapp微信小程序拿来即用的瀑布流布局demo2(方法二)(复制粘贴即可使用,无需做其他处理)
IT转测试岗,从迷茫到坚定我究竟付出了什么?
城市轨道交通站应急照明疏散指示系统设计
Hisilicon 3559 universal platform construction: YUV422 pit stepping record
Using the uniapp rich text editor
Illustrated network: what is gateway load balancing protocol GLBP?
巩固表达式C# 案例简单变量运算
P3304 [SDOI2013]直径(树的直径)
AcWing164. 可达性统计(拓扑排序+bitset)
He worked as a foreign lead and paid off all the housing loans in a year