C language analyzes the operational relationship between sizeof, strlen, arrays, and pointers

When using sizeof and strlen to find the size and length of an array when the pointer points to different positions, analyze the position pointed by the pointer at this time and the meaning of the formula in order to deepen the understanding of arrays and pointers.

Table of Contents

Foreword:

1. One-dimensional array and sizeof

2. Character array (in the form of a single character in the array) and sizeof, strlen

2.1 Calculation with sizeof

2.2 Calculation with strlen

3. Character array (string form in array) and sizeof, strlen

3.1 Calculation with sizeof

3.2 Calculation with strlen

4. Character array (char* form) and sizeof, strlen

4.1 Character array (char* form) and sizeof

4.2 Character array (char* form) and strlen

5. Two-dimensional array and sizeof

Conclusion


Foreword:

The array name is understood as the address of the first element, but there are two exceptions:

1.sizeof (array name), the array name here represents the entire array, find the size of the entire array, in bytes

2. & amp;Array name, the array name here also represents the entire array, that is, taking out the address of the entire array, that is, + 1 skips the entire array

In addition, as long as it is not the above two situations, the array represents the address of the first element.

The size of the address is only related to the number of bits in the machine. The address size on a 32-bit machine is 4 bytes, and the address size on a 64-bit machine is 8 bytes.

1. One-dimensional array and sizeof

Perform the following detailed analysis on the different locations pointed to by the integer array and the pointer:

#include<stdio.h>

int main()
{
//One-dimensional array
int a[] = { 1,2,3,4 };
printf("%zd\
", sizeof(a));//When sizeof only contains the array name,
//That is, sizeof finds the size of the entire array, 4*4=16 bytes
\t
printf("%zd\
", sizeof(a + 0)); //sizeof contains more than just array names, so the array name here represents the address of the first element.
// + 0 means that the address of the first element has been moved backward by 0 bits. It is still necessary to find the size of the address of the first element.
//The size of the address is only related to the number of machine bits, so the size is 4/8 bytes
\t
printf("%zd\
", sizeof(*a));//The array name is the address of the first element, dereference it to get the value of the first element,
//Because it is an int type array, the space of each element is an int type, which is 4 bytes.
\t
printf("%zd\
", sizeof(a + 1));//a represents the address of the first element, a + 1 represents the address of the second element,
    //That is the address of array element 2,
//The address size is related to the number of machine bits, so it is equal to 4/8 bytes
\t
printf("%zd\
", sizeof(a[1]));//a[1] represents the second element in array a,
//The element size is related to the array type, so it is 4 bytes
\t
printf("%zd\
", sizeof( & amp;a));//sizeof( & amp;a) where a represents the entire array, take out the address of array a,
    //That is, get the address of the entire array. The address size is only related to the number of machine digits, so the size is 4/8 bytes.
\t
printf("%zd\
", sizeof(* & amp;a));//Get the address of a and dereference it,
//Therefore * & amp;a=a, sizeof(a) is to find the size of the entire array, 4*4=16 bytes
\t
printf("%zd\
", sizeof( & amp;a + 1));// & amp;a is to take out the entire address of array a, + 1 step size is the entire array,
//That is, the address after skipping the entire array, but because it is still an address, the address size is only related to the number of machine digits, so the size is 4/8 bytes

printf("%zd\
", sizeof( & amp;a[0]));//a[0] represents the first element, & amp;a[0] is the address where a[0] is taken out,
//So the expression is the address of the first element. The address size is only related to the number of machine bits. The size is therefore 4/8 bytes.

printf("%zd\
", sizeof( & amp;a[0] + 1));//a[0] represents the first element, & amp;a[0] is the method for taking out a[0] address,
// + 1 represents the address pointing to the second element. The address size is only related to the number of machine bits, so the size is 4/8 bytes
return 0;
}

operation result:

2. Character array (in the form of a single character in the array) and sizeof, strlen

2.1 Calculation with sizeof

Under siezof, conduct the following detailed analysis of the character array and pointer pointing to different locations:

#include<stdio.h>
#include<string.h>

int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%zd\
", sizeof(arr));//sizeof (array name) finds the size of the entire group. The array has 6 elements.
//Because it is a char type array, the size of each element is 1 byte, so the size of the entire set of elements is 6*1=6 bytes

printf("%zd\
", sizeof(arr + 0));//sizeof contains more than just array names, so the array here represents the address of the first element,
// + 0 means that the address of the first element has been moved backward by 0 bits. It is still necessary to find the size of the address of the first element, which is 4/8 bytes.
\t
printf("%zd\
", sizeof(*arr));//Here arr represents the address of the first element of the array, and represents the value of the first element after dereference.
//Because it is a char type array, the size of each element is 1 byte
\t
printf("%zd\
", sizeof(arr[1]));//arr[1] represents the value of the second element,
//Because it is a char type array, the size of each element is 1 byte
\t
printf("%zd\
", sizeof( & amp;arr));//sizeof( & amp;arr), at this time arr represents the entire array,
//So the address of the entire array is taken out, and the step size is the entire array. Because it is still an address, the size is 4/8 bytes.
\t
printf("%zd\
", sizeof( & amp;arr + 1));//Indicates taking the entire set of addresses of the arr array, + 1 skips the address after the entire set of addresses,
//Because it is still an address after all, the size is 4/8 bytes
\t
printf("%zd\
", sizeof( & amp;arr[0] + 1));//arr[0] represents the first element, & amp;arr[0] is the address of the first element,
// + 1 represents the address of the second element, which is the address of 'b'. The address size is still 4/8 bytes
\t
return 0;
}

operation result:

2.2 Calculation with strlen

Under strlen, perform the following detailed analysis of the character array and pointer pointing to different locations. strlen will not stop until it encounters ‘\0’, so it calculates the length before ‘\0’. And the formal parameter type of strlen function must be a pointer.

#include<stdio.h>
#include<string.h>

int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%zd\
", strlen(arr));//arr is the address of the first element, so counting backward from the first element,
//Stop counting to '\0', but this array does not have '\0', so strlen will keep counting backwards until it encounters '\0'
//We don't know when we encounter '\0' later, so it is a random value.
\t
printf("%zd\
", strlen(arr + 0));//The array here represents the address of the first element,
// + 0 means that the address of the first element has moved backward by 0 bits, and still points to the first element, so counting backward from the first element,
//Stop counting to '\0', but this array does not have '\0', so strlen will keep counting backwards until it encounters '\0'
//We don't know when we encounter '\0' later, so it is also a random value.
\t
printf("%d\
", strlen(*arr));//Dereference the first element address to get the value of the first element, but
//The parameter given to strlen must be a pointer. Here, the ascii value 97 of a is given to strlen, and strlen will treat it as an address.
//So '\0' will be accessed starting from 97, but the address 97 does not belong to the address we can access, and illegal access will occur.

printf("%d\
", strlen(arr[1]));//arr[1] represents the second element 'b', and the value passed to strlen is also a value.
//The situation is the same as above
\t
printf("%zd\
", strlen( & amp;arr));// & amp;arr takes out the entire address of the array arr and passes it to strlen,
//Although it transmits the entire set of addresses, the address number of the entire set of addresses is the same as the address number of the first element of the array.
//It's just that their step sizes after + 1 are different, and strlen doesn't care what the step size of the address passed is.
//He will still look for '\0' from this address to the back of the array, so the length is still a random value
\t
printf("%zd\
", strlen( & amp;arr + 1));// & amp;arr + 1 means skipping the entire array and pointing to the address behind the array.
//But we don't know when '\0' is encountered at the end of the array, so the length is still a random value
\t
printf("%zd\
", strlen( & amp;arr[0] + 1));// & amp;arr[0] represents the address of the first element, + 1 means the address of the second element
//So whether to look for '\0' from the address of the second element or backward, we still don't know when we encounter '\0', so it is still a random value
//Or it can be said that it is the number of random values looking backward from the first element -1
return 0;
}

operation result:

3. Character array (string form in array) and sizeof, strlen

3.1 Calculation with sizeof

Under siezof, conduct the following detailed analysis of the character array and pointer pointing to different locations:

#include<stdio.h>

int main()
{
char arr[] = "abcdef";//'\0' is automatically added to the end of the string: [a b c d e f '\0']
printf("%zd\
", sizeof(arr));//sizeof(arr) means the size of the entire array, '\0' is also counted as an element,
//There are a total of 7 elements. Because it is a char type array, each element is 1 byte in size, 7*1=7 bytes.
\t
printf("%zd\
", sizeof(arr + 0));//arr here represents the address of the first element,
// + 0 means that the first element address has moved backward by 0 bits and still points to the first element address. The address size is 4/8 bytes.
\t
printf("%zd\
", sizeof(*arr));//Dereference the address of the first element to get the value of the first element, which is 'a',
//Because it is a char type array, each element is 1 byte in size, so the size of 'a' is 1 byte
\t
printf("%zd\
", sizeof(arr[1]));//arr[1] represents the value of the second element, which is 'b',
//Because it is a char type array, each element is 1 byte in size, so the size of 'b' is 1 byte
\t
printf("%zd\
", sizeof( & amp;arr));// & amp;arr means taking out the address of the entire array of arr. The size of the address is always 4/8
\t
printf("%zd\
", sizeof( & amp;arr + 1));//Indicates that the address of the entire array of arr is taken out + 1 backwards across the entire array,
//Points to the address behind the entire array. Because the size of the address is still calculated, it is 4/8 bytes.
\t
printf("%zd\
", sizeof( & amp;arr[0] + 1));// & amp;arr[0] represents the first element, + 1 points to the address of the second element,
//Still calculate the size of the address, so it is 4/8 bytes
\t
return 0;
}

operation result:

3.2 Calculation with strlen

Under strlen, perform the following detailed analysis on the different locations pointed by character arrays and pointers:

#include<stdio.h>

int main()
{
char arr[] = "abcdef";//'\0' is automatically added to the end of the string: [a b c d e f '\0']
\t
printf("%d\
", strlen(arr));//arr is the address of the first element, so count backwards from the first element.
//Stop counting to '\0' and take the value of the number of previous elements. There are 6 elements in front of '\0', so the length is 6
\t
printf("%d\
", strlen(arr + 0));//The array here represents the address of the first element,
// + 0 means that the address of the first element has moved backward by 0 bits, and still points to the first element, so counting backward from the first element,
//Stop counting to '\0' and take the value of the number of previous elements. There are 6 elements in front of '\0', so the length is 6
\t
printf("%d\
", strlen(*arr));//Dereference the first element address to get the value a of the first element, but
//The parameter given to strlen must be a pointer. Here, the ascii value 97 of a is given to strlen, and strlen will treat it as an address.
//So '\0' will be accessed starting from 97, but the address 97 does not belong to the address we can access, and illegal access will occur.
\t
printf("%d\
", strlen(arr[1]));//The same as above is also illegal access, arr[1] represents the value of the second element
\t
printf("%d\
", strlen( & amp;arr));// & amp;arr takes out the entire address of the arr array and passes it to strlen,
//Although it transmits the entire set of addresses, the address number of the entire set of addresses is the same as the address number of the first element of the array.
//It's just that their step sizes after + 1 are different, and strlen doesn't care what the step size of the address passed is.
//He will still look for '\0' from this address to the back of the array, so the length is 6
\t
printf("%d\
", strlen( & amp;arr + 1)); // & amp;arr + 1 means skipping the entire array and pointing to the address behind the array.
//But we don't know when '\0' is encountered at the end of the array, so the length is still a random value
\t
printf("%d\
", strlen( & amp;arr[0] + 1));// & amp;arr[0] is the address of the first element, + 1 points to the address of the second element,
//So counting from the address of the second element, the length is 5
\t
return 0;
}

operation result:

4. Character array (char* form) and sizeof, strlen

4.1 Character array (char* form) and sizeof

Under sizeof, conduct the following detailed analysis of the character array and the different locations pointed by the pointer:

#include<stdio.h>
#include<string.h>

int main()
{
char* p = "abcdef";//'\0' is automatically added to the end of the string: [a b c d e f '\0']
\t
printf("%zd\
", sizeof(p));//Note that p here is not an array, but a pointer, and points to the address of the first element.
//The size of pointer p is determined based on the number of bits of the machine, so the size of p is 4/8 bytes
\t
printf("%zd\
", sizeof(p + 1));//p is the address pointing to the first element, + 1 moves one position to the right to point to the second element 'b',
//But it is still a pointer, so the size is between 4/8
\t
printf("%zd\
", sizeof(*p));//Dereference the pointer p pointing to the first element and get the value of 'a',
//Because it is a pointer of type char*, the size of the access is 1 byte
\t
printf("%zd\
", sizeof(p[0]));//p[0] also represents the first element 'a', so it is also 1 byte in size
\t
printf("%zd\
", sizeof( & amp;p));//Get the address of pointer p, the address is 4/8 bytes,
//Here his type is char**, which is a secondary pointer
\t
printf("%zd\
", sizeof( & amp;p + 1));// & amp;p represents the address of the pointer variable p, + 1 represents the address after p
//The address is 4/8 bytes
\t
printf("%zd\
", sizeof( & amp;p[0] + 1));//Indicates the address of the first element + 1, pointing to the address of the second element,
//The address is 4/8 bytes
return 0;
}

operation result:

4.2 Character array (char* form) and strlen

Under strlen, perform the following detailed analysis on the different locations pointed by character arrays and pointers:

#include<stdio.h>

int main()
{
char* p = "abcdef";//'\0' is automatically added to the end of the string: [a b c d e f '\0']
printf("%zd\
", strlen(p));//p points to the first element a, counting backwards from a to '\0',
//The length is 6
\t
printf("%zd\
", strlen(p + 1));//p + 1 points to the second element b, so counting backwards from b,
//The length is 5
\t
printf("%zd\
", strlen(*p)); //Dereference the address of the first element to get the value of the first element, but
//The parameter given to strlen must be a pointer. Here, the ascii value 97 of a is given to strlen, and strlen will treat it as an address.
//So '\0' will be accessed starting from 97, but the address 97 does not belong to the address we can access, and illegal access will occur.
\t
printf("%zd\
", strlen(p[0]));//Same as above, also illegal access
\t
printf("%zd\
", strlen( & amp;p));//Get the address of the pointer variable p itself, and access backward from this address.
//Stop until it encounters '\0', but we don't know what the specific content of p's address is, and when we encounter '\0' later,
//So the length is a random value
\t
printf("%zd\
", strlen( & amp;p + 1));//Same as above, take out the address of the pointer variable p,
// + 1 accesses the address behind p. We don't know when '\0' is encountered after the address of p.
//So the length is a random value
\t
printf("%zd\
", strlen( & amp;p[0] + 1));//The address of the first element + 1, pointing to the address of the second element
//So start accessing from the second element to the back until you encounter '\0', the length is 5
\t
return 0;
}

Schematic diagram of & amp;p and & amp;p + 1:

operation result:

5. Two-dimensional array and sizeof

Perform the following detailed analysis on the integer two-dimensional array and the different locations pointed by the pointer.

In a two-dimensional array, the array name of the two-dimensional array is the address of the first element. Because a two-dimensional array is composed of multiple one-dimensional arrays, the address of the first element of the two-dimensional array can be regarded as the address of the first row (the first one-dimensional array) in the two-dimensional array, and the address of the second row of the two-dimensional array The element address is the address of the second row in the two-dimensional array (the second one-dimensional array).

#include<stdio.h>

int main()
{
int a[3][4] = { 0 }; // Two-dimensional array, the elements in it are all 0
printf("%zd\
", sizeof(a));//The size of the entire two-dimensional array is calculated, that is, 3*4*4=48 bytes
\t
printf("%zd\
", sizeof(a[0][0]));//a[0][0]) is the first element of the two-dimensional array, which is an int array.
//So the size of the array elements is 4 bytes
\t
printf("%zd\
", sizeof(a[0]));//a[0] represents the address of the first element of the first row of the two-dimensional array, that is, the array name of the first row,
//As mentioned above, sizeof (array name) represents the size of the entire array, so here is the size of the first row of the array,
//A row of 4 elements, size 4*4=16 bytes
\t
printf("%zd\
", sizeof(a[0] + 1));//a[0] represents the address of the first element of the first line, + 1 represents the address of the second element of the line,
//The size of the address is 4/8 bytes
\t
printf("%zd\
", sizeof(*(a[0] + 1)));//a[0] + 1 is the address of the second element in the first line,
//Dereference it to get the value of the second element in the first row. The array is an int array.
//So the size of the array elements is 4 bytes
\t
printf("%zd\
", sizeof(a + 1));//a represents the address of the first row of the two-dimensional array, + 1 to get the address of the second row,
//That is, the address of the second one-dimensional array in the two-dimensional array a. The size of the address is 4/8 bytes.
\t
printf("%zd\
", sizeof(*(a + 1))); //a + 1 represents the address of the second one-dimensional array in the two-dimensional array a,
//Dereference it to get the address of the first element of the second line, which is the array name of the second line, *(a + 1)=a[1],
//So the result of sizeof (array name) is the size of the entire array, that is, the size of the second one-dimensional array, that is, 4*4=16 bytes
\t
printf("%zd\
", sizeof( & amp;a[0] + 1));// & amp;a[0] takes the address of the first element and gets the address of the first line.
//The address of the first row + 1 step size is the step size of the entire one-dimensional array, so + 1 gets the address of the second one-dimensional array, which is the address of the second row,
//The size of the address is always 4/8 bytes
\t
printf("%zd\
", sizeof(*( & amp;a[0] + 1)));// & amp;a[0] + 1 is the address of the second line, then dereference it,
//What is obtained is the address of the first element of the second line, that is, the array name a[1] of the second line,
//So the result of sizeof (array name) is the size of the entire array, that is, the size of the second one-dimensional array, that is, 4*4=16 bytes
\t
printf("%zd\
", sizeof(*a));//a here is the address of the first one-dimensional array (first row address),
//Dereference it to get the address of the first element, which is the array name of the first row,
//So the size of sizeof (array name) is 16 bytes
\t
printf("%zd\
", sizeof(a[3]));//Here a[3] seems to be accessed out of bounds, but sizeof will not actually calculate the memory.
//sizeof only needs its type to determine the size, and the type of this array is int [4],
//So the size logic of a[3] is the same as a[2] a[1], and their sizes are both 16 bytes.
\t
return 0;
}

operation result:

Conclusion

The above is the analysis of the operational relationship between sizeof, strlen, arrays, and pointers. If this article is helpful to you, I hope you can like it + follow + collect Oh! If there are any omissions or errors, please feel free to add them in the comment area~! ! thank you all! !

(?′?`?)