当前位置:网站首页>【C】 (written examination questions) pointer and array, pointer

【C】 (written examination questions) pointer and array, pointer

2022-07-05 00:18:00 Xin Xiangrong

 Insert picture description here
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 !

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 :
  1. sizeof( Array name ), The array name here represents the entire array , It calculates the size of the entire array .
  2. & Array name , The array name here represents the entire array , It takes out the address of the entire array .
  3. In addition, all array names represent the address of the first element .
  • strlen and sizeof The difference between :
  1. 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

  1. 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 :

img

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 :

img

#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 :

img

#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 :

img

#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 :

img

#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 :

img

#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 :

img

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 :

img

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 :

img

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 ;

img

*(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 :

img

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 :

img

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 :

img

%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 :

img

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 :

img

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 :

img

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 :

img

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 :

img

analysis :

It's more intuitive to look at the picture , as follows ,

img

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 :

img

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 :

img

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. !!!

img

原网站

版权声明
本文为[Xin Xiangrong]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/186/202207050013044072.html