Advanced c language: pointer

✨ The author introduces: Hello, everyone. I'm pangdudu, the king of fishing. You can call me Xiaodu 💕
✨ Author home page: Fishing king chubby personal blog home page 🎉
🎈 Author's gitee: Small bit_ Doodle's personal gitee
🎈 Series column: [from 0 to 1, roam the world of c language]
✨ Xiao Du studies and makes progress with everyone! Try your best to write every blog and immerse yourself in the joy of your progress 🤭. If there are errors in the article, welcome to the comment area ✏️ comment. Let's start today's study! 😊

💻 preface

Hello everyone ~ today I'm going to take you to learn pointers again. Today I'm going to bring you a very important interview question about pointers and arrays. I hope you can study carefully and gain something!!

🍁 First of all, let's review some knowledge!

🎈 The meaning of array name:

🍁 Sizeof (array name) - the array name represents the size of the entire array - calculates the size of the entire array.
🍁& Array name - the array name represents the entire array, and the address of the entire array is taken out.
🍁 In addition, all array names are the addresses of the first elements of the array.

🎈 Meaning of pointer type:

🍁 The type of pointer determines how many bytes the pointer can access when dereferenced.
🍁 The type of pointer determines that several bytes are skipped during pointer ± 1 operation, that is, the step size of the pointer.

🎈 One dimensional array (integer array):

✏️ Note: different operating systems have different byte sizes 4(x86) 8(x64)

#include<stdio.h>

int main()
{
/One dimensional array
	int a[] = { 1,2,3,4 };//4*4=16
	printf("%d\n", sizeof(a));//16
	//Sizeof (array name), sizeof has a separate array name inside, so here the array name a represents the whole array 
	//——It calculates the size of the entire array in bytes
	printf("%d\n", sizeof(a + 0));//4/8 - A + 0 is the address of the first element, and sizeof(a + 0) calculates the size of the address
	printf("%d\n", sizeof(*a));//4 - *a is the first element of the array, and sizeof(*a) calculates the size of the first element
	printf("%d\n", sizeof(a + 1));//4/8 - a+1 is the address of the second element, and sizeof(a + 1) calculates the size of the address
	printf("%d\n", sizeof(a[1]));//4 - the size of the second element is calculated

	printf("%d\n", sizeof(&a));//4/8 - &a although the address of the array, it is also an address
	printf("%d\n", sizeof(*&a));//16 * &a = = a - calculates the size of the array
	//&a -- int (*p)[4] = &a;
	printf("%d\n", sizeof(&a + 1));//4/8 - address of the next space after skipping the entire array
	printf("%d\n", sizeof(&a[0]));//4/8
	//&A[0] is the address of the first element
	//——The size of the first element address is calculated
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//&A[0] is the address of the first element, &a[0] + 1 gets the address of the second element
	//——The size of the address is calculated

	return 0;
}

🎉 Effect display:

🎈 Character array:

🍁 Use sizeof to observe arr[] = {'a', 'b', 'c','d ',' e ',' f '}

#include<stdio.h>

int main()
{
//Character array
	char arr[] = { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' };

	printf("%d\n", sizeof(arr));//6
	//——The size of the whole array is calculated
	printf("%d\n", sizeof(arr + 0));//4/8
	//——The size of the first element address is calculated
	printf("%d\n", sizeof(*arr));//1
	//——The size of the first element is calculated
	printf("%d\n", sizeof(arr[1]));//1
	//——The size of the second element is calculated
	printf("%d\n", sizeof(&arr));//4/8
	//——The size of the address of the entire array is calculated
	printf("%d\n", sizeof(&arr + 1));//4/8
	//——The size of the address is calculated
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	//arr[0] is the first element: character'a', character +1, the character will be integer promoted, and the result is an integer, which is 4 bytes
	//——The size of the address of the second element is calculated
	return 0;
}

🎉 Effect display:

🍁 Use strlen to observe arr[] = {'a', 'b', 'c','d ',' e ',' f '}

#include<stdio.h>

int main()
{
//Character array
	char arr[] = { ' a ' , ' b ' , ' c ' , ' d ' , ' e ' , ' f ' };

	printf("%d\n", strlen(arr));//Random value
	//The array name is the address of the first element. The strlen function starts from the first element and will not stop until it encounters'\0', but there is no'\0' in the array, so it is a random value.
	printf("%d\n", strlen(arr + 0));//Random value
	//The reason is the same as above
	printf("%d\n", strlen(*arr));//error
	//The strlen function receives the address. Standing on the strlen function, it thinks that what you pass to it is the address.
	//*Arr is the first element, that is,'a', so strlen(*arr) is equivalent to strlen ('a'). The ASCII value of 'a' is 97, so it is equivalent to strlen(97),
	//97 will be passed to the strlen function as an address, but 97 is not mine. It is an illegal access and wild pointer problem.
	printf("%d\n", strlen(arr[1]));//error
	//The reason is the same as above. The address passed on does not belong to me. It's a wild pointer problem
	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;
}

strlen function:
🍁 Find the length of the string. It will stop when it encounters' \0 ', and the number of characters that appear from the beginning to' \0 'is calculated.
🍁 What you receive is not the string itself, but the address of the first element of the string.
Even if it is written like this: my_strlen(“abc”); Strlen passed a string internally
This string of codes and, char arr[] = "abc"; my_strlen(arr); There is no difference.
Note that the string is passed to my_strlen does not pass the string itself, but the address of the first element a, which is received with a pointer.
🍁 The parameter type received by strlen function is char*, which means that strlen function will read data byte by byte, that is, one character by one to see whether it is' \0 '.
If the passed pointer type is char * * or char * [4], it will be converted to char * type.

🍁 Use sizeof to observe arr[] = "abcdef"

#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  char (*)[7]
	printf("%d\n", sizeof(&arr + 1));//4/8
	printf("%d\n", sizeof(&arr[0] + 1));//4/8
	return 0;
}

🍁 Use strlen to observe arr[] = "abcdef"

#include<stdio.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));//error
	printf("%d\n", strlen(arr[1]));//error
	printf("%d\n", strlen(&arr));//6
	printf("%d\n", strlen(&arr + 1));//Random value
	//&Arr, which takes out the address of the entire array, +1 skips the entire array and points to the back of'\0 ', so it is a random value from the back of'\0'
	printf("%d\n", strlen(&arr[0] + 1));//5
	//&Arr[0], takes the address of the first element, +1 is the address of the second element
	return 0;
}

🎈 Pointer:

#include<stdio.h>
int main()
{
	char* p = "abcdef";
	//p is the address of the first element of the string, that is, the address of the character'a'

	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  p[0] ->*(p+0)
	printf("%d\n", sizeof(&p));//4/8
	//What you get is the address of the first element address, the address of the primary pointer variable p, which is a secondary pointer
	printf("%d\n", sizeof(&p + 1));//4/8
	//P points to the first element 'a', the type of P is char*, the type of the element pointed to by P is char,char is 1 byte, p+1 skips 1 byte
	//&P points to P, &p's type is char**, &p points to element type is char*,char* is 4 bytes, &p+1 skips 4 bytes
	//Therefore, &p+1 skips P and points to the space behind P
	printf("%d\n", sizeof(&p[0] + 1));//4/8
	//Is the address of the second element, that is, the address of'b'
	
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//5
	printf("%d\n", strlen(*p));//error
	printf("%d\n", strlen(p[0]));//error
	printf("%d\n", strlen(&p));//Random value 1
	//Why is it a random value?
	//P points to the character'a', &p points to P, and in P is the address, so &p points to the address
	//&The space pointed by p and the space pointed by p are two completely different spaces. No contact.
	//Because strlen receives an address of type char*, while &p's type is char**,
	//Therefore, char * * will be converted to char* type, looking down'\0 'byte by byte
	//Then why not make mistakes?
	//Because the space of P has been opened up, P belongs to my current program, so &p is not a wild pointer, and will not cause a wild pointer error like strlen(97) before.
	printf("%d\n", strlen(&p + 1));//Random value 2
	//The reason is the same as above
	//Moreover, random value 2 is not related to random value 1, &p points to P, &p+1 skips 4 bytes and points to the back of P
	//But when &p and &p+1 are passed to strlen function respectively, because strlen receives an address of type char*,
	//Therefore, the data type of the elements they point to will be forcibly converted to char*, and then look for'\0'byte by byte,
	//Maybe there is'\0'between the element pointed to by & and the element pointed to by &p1+1.
	printf("%d\n", strlen(&p[0] + 1));//5
	//&P[0] + 1 is equivalent to p + 1
	return 0;
}

🎈 Two dimensional array:

#include<stdio.h>
int main()
{
	//Two dimensional array
	int a[3][4] = { 0 };

	printf("%d\n", sizeof(a));//48 = 3 * 4 *sizeof(int)
	printf("%d\n", sizeof(a[0][0]));//4 - a[0][0] - the first element in the first line
	printf("%d\n", sizeof(a[0]));//16
	printf("%d\n", sizeof(a[0] + 1));//4 - a[0] as an array name is not separately placed in sizeof, nor is it addressed, indicating the address of the first element in the first line
									 //	a[0] + 1 indicates the address of the second element in the first line
	printf("%d\n", sizeof(*(a[0] + 1)));//4 * (a[0] + 1) is the second element in the first line
	printf("%d\n", sizeof(a + 1));//4a is the array name of the two-dimensional array. It does not take the address, nor is it separately placed in sizeof, indicating the address of the first element of the two-dimensional array
								  // a + 1 is the address of the first element in the second line
	printf("%d\n", sizeof(*(a + 1)));//16 * (a + 1) - >a[1] a + 1 is the address of the second line * (a + 1) indicates the second line
	printf("%d\n", sizeof(&a[0] + 1));//4 a[0] is the array name of the first row, &a[0] is the address of the first row, &a[0] + 1 is the address of the second row
	printf("%d\n", sizeof(*(&a[0] + 1)));//16 &a[0] + 1 is the address of the second line, * (&a[0] + 1) is the second line
	printf("%d\n", sizeof(*a));//16   *a  - > *(a + 0) - > a[0]
							   //A, as the array name of a two-dimensional array, does not take the address and is not placed separately in sizeof,
							   //A is the address of the first element, that is, the address of the first line, so *a is the size of the first line
	printf("%d\n", sizeof(a[3]));//16
	return 0;
}
In the two-dimensional array: int a[3][4] = { 0 };
 
Calculate the size of the entire array: sizeof(a); 
Calculate the size of the entire first row: sizeof(a[0]); sizeof(*a);
 
Calculate the size of the second element in the first row:  sizeof(a[0][1]); sizeof(*(a[0] + 1));
Calculate the size of the address of the second element in the first line: sizeof(&a[0][1]); sizeof(a[0] + 1);
 
Calculate the size of the second row: sizeof(a[1]); sizeof(*(a + 1)); sizeof(*(&a[0] + 1));
Calculate the size of the address in the second line: sizeof(&a[1]); sizeof(a + 1); sizeof(&a[0] + 1);

🎈 summary

This article may be difficult for you to understand. In order to better understand this part of knowledge, you can pay attention to brother bitpeng's explanation of this part of knowledge
Attached link: Pengge C language - 121. Pointer advanced 8

Tags: C

Posted by blkraven on Fri, 05 Aug 2022 21:31:35 +0300