Analysis of sizeof and strlen to obtain arrays and pointers

Table of Contents

sizeof Vs strlen in one-dimensional array

integer array sizeof

character array

sizeof

strlen

string array

sizeof

strlen

String pointer char *p

sizeof

strlen

sizeof in two-dimensional array

Summarize


The main questions today are mainly array & pointer analysis questions and written test questions. I feel a little anxious recently. Everyone must focus on what is at hand and don’t be too anxious.

sizeof Vs strlen in one-dimensional array

Array name: It is the address of the first element of the array, but there are 2 exceptions.

1.sizeof(array name), the array name here represents the entire array, sizeof(array name) calculates the size of the entire array, the unit is bytes.

2. & amp;Array name, the array name here represents the entire array, & amp;array name retrieves the address of the entire array.

int arr[5] ={1,2,3,4,5};

When sizeof(arr), arr refers to the entire array, 20 bytes.

& amp;arr, arr refers to the address of the entire array.

About strlen and sizeof

  • sizeof

sizeof is an operator.
The size of the memory occupied by sizeof is calculated in bytes.
Counting the string includes \0 and the number of characters before \0.
Counting characters is the number of characters.
The object calculated by sizeof can be of any type.

  • strlen

strlen is a library function.
strlen counts the length of a string.
strlen stops calculating when it encounters \0.
strlen can only be used for strings, and the calculated string does not include \0.
When strlen counts characters, it cannot encounter \0, so it has a random value.
strlen cannot calculate the length of integer and character arrays because it stops when it encounters \0.

  • Notice
  • When strlen calculates the length of a string, it counts the number of characters that appear before the string \0.
  • When sizeof calculates the length of a string, it counts the number of characters that appear before \0 and \0.
  • The address must be passed to strlen, and any writing method can be passed to sizeof.

integer array sizeof

//One-dimensional array
int a[] = {1,2,3,4};
printf("%d\\
",sizeof(a));
printf("%d\\
",sizeof(a + 0));
printf("%d\\
",sizeof(*a));
printf("%d\\
",sizeof(a + 1));
printf("%d\\
",sizeof(a[1]));
printf("%d\\
",sizeof( & amp;a));
printf("%d\\
",sizeof(* & amp;a));
printf("%d\\
",sizeof( & amp;a + 1));
printf("%d\\
",sizeof( & amp;a[0]));
printf("%d\\
",sizeof( & amp;a[0] + 1))
#include<stdio.h>
int main()
{
//One-dimensional array
int a[] = { 1,2,3,4 };
printf("%d\\
", sizeof(a));//?
//sizeof (array name) represents the entire array. The array name a is placed alone inside sizeof. The size unit of the entire array is calculated in bytes, 16 bytes.
//4 elements, each element is int type (4 bytes), 16 bytes
//16
printf("%d\\
", sizeof(a + 0));
//sizof(a + 0), the array name a is not placed alone inside sizeof, and there is no & amp;, a represents the address of the first element of the array, + 0 is still the address of the first element, no matter what type the address is, the size is 4/8 bytes
//4/8 bytes
printf("%d\\
", sizeof(*a));
//sizeof(*a), the array name a is not placed alone inside sizeof, and there is no & amp;, a represents the address of the first element of the array, *a represents the address of the first element of the dereference, that is, the first element is found, which is 1 , the size of an integer element is 4 bytes.
//4 bytes
//*a==*(a + 0)==a[0]
printf("%d ", sizeof(a + 1));//address + + and *address + +?
//sizeof(a + 1), the array name a is not placed alone inside sizeof, and there is no & amp;, a represents the address of the first element, a + 1 represents the address of the second element, no matter what type the address is, The sizes are all 4/8 bytes
//4/8 bytes--8 bytes (64 bits)
//a + 1 == & amp;a[1] is the address of the second element
//Point to where?
printf("%d\\
", sizeof(*a + 1));
//*a is the first element address dereferenced as the first element, either + 1 or + +. They just move one digit back by 4 bytes, and do not say 1 + 1 = 2. Assign the value like this to calculate the address of the second element.
//4 bytes
printf("%d\\
", sizeof(a[1]));
//sizeof(a[1]), a[1] subscript reference operator, the subscript of the array starts from 0, so a[1] refers to the second element 2, and the size of an integer element is 4 bytes
//4 bytes
printf("%d\\
", sizeof( & amp;a));//?
//sizeof( & amp;a), a represents the entire array. & amp;a takes out the address of the entire array. No matter what, it still represents the address. No matter what type the address is, the size is 4/8 words. Festival
//4/8 bytes
//The essential difference between the address of the array and the address of the first element of the array is the difference in type, not the size.
//a --- int* --pointer -- int*p =a; dereference accesses the size of an integer
// & amp;a --- int(*)[4]--pointer array-- int*p[4]= & amp;a; dereference accesses the size of an array
//But for p, it always stores an address. Whether it is the address of the first element of the array or the address of the entire array, it is always the same address, and the size is 4/8 bytes.
printf("%d\\
", sizeof(* & amp;a));
//sizeof(* & amp;a), a represents the entire array, & amp;a is to take out the address of the entire array, * & amp;a is to dereference the address of the entire array, representing the elements of the entire array , 16 bytes
//16 bytes
//* and & cancel
printf("%d\\
", sizeof( & amp;a + 1));//?
//sizeof( & a + 1), a represents the elements of the entire array, & a is to take out the address of the entire array, + 1 is to skip an element of the entire a array, pointing to the address after skipping place,
//No matter what it is, it still represents the address. No matter what type the address is, the size is 4/8 bytes.
//4/8 bytes
//Point to where?
printf("%d\\
", sizeof( & amp;a[0]));
//sizeof(& amp;a[0]), the priority a of the operator is first combined with [] and the subindex operator to obtain element 1; then combined with & amp;, the address of 1 is obtained. That is the address of the first element.
//No matter what it is, it still represents the address. No matter what type the address is, the size is 4/8 bytes.
//4/8 bytes
printf("%d\\
", sizeof( & amp;a[0] + 1));
//sizeof( & a[0] + 1), same as above, gets the address of the first element, + 1 gets the address of the second element.
//No matter what it is, it still represents the address. No matter what type the address is, the size is 4/8 bytes.
//4/8 bytes
// &a[1]
// & amp;a[0] + 1
//a + 1
return 0;
}
  • sizeof(array name), the array name represents the entire array, and the size of the entire array is calculated.
  • & amp;Array name, the array name represents the address of the entire array.
  • Except for the above two cases, the array name at other times is the address of the first element.
    printf("%d\\
    ", sizeof(a));//16 bytes
    printf("%d\\
    ", sizeof( & amp;a));//4/8 bytes
  • Don’t look at the address between the cracks in the door. No matter what type of address it is, char* int* double*, etc. are all 4/8 bytes.
  • On a 32-bit platform, 4 bytes.
  • On a 64-bit platform, 8 gives bytes.
     printf("%d\\
    ", sizeof( & amp;a));
        printf("%d\\
    ", sizeof(a + 0));
  • Regarding *p + + and p + +, that is, address + + and array element + +
  • Regarding the address + + and array element + +, note that the array element + + is not + 1 on the native value of the element, nor is it assigned a value.
  • For the inversion of strings, you can also review right + + and left + +, as well as the issues of assignment and change.
  • Regarding the location pointed by array name + + and & array name + +, see the figure below. What we need to note is that the address + + depends on the type of pointer
     printf("%d ", sizeof(a + 1 ));
    printf("%d\\
    ", sizeof(*a + 1));
    printf("%d\\
    ", sizeof( & amp;a + 1));//?

Character array

–Character array is without \0

#include<stdio.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\\
", sizeof(arr));
printf("%d\\
", sizeof(arr + 0));
printf("%d\\
", sizeof(*arr));
printf("%d\\
", sizeof(arr[1]));
printf("%d\\
", sizeof( & amp;arr));
printf("%d\\
", sizeof( & amp;arr + 1));
printf("%d\\
", sizeof( & amp;arr[0] + 1));

printf("%d\\
", strlen(arr));
printf("%d\\
", strlen(arr + 0));
printf("%d\\
", strlen(*arr));
printf("%d\\
", strlen(arr[1]));
printf("%d\\
", strlen( & amp;arr));
printf("%d\\
", strlen( & amp;arr + 1));
printf("%d\\
", strlen( & amp;arr[0] + 1));
return 0;
}

sizeof

#include<stdio.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };//6
printf("%d\\
", sizeof(arr));//?
//sizeof(arr), the array name arr is placed alone inside sizeof, referring to the entire array, and the elements of the entire array are calculated, 6 bytes
printf("%d\\
", sizeof(arr + 0));//?
//sizeof(arr + 0), arr refers to the address of the first element, + 0 is still the address of the first element, no matter what type the address is, the size is 4/8 bytes
//arr is the address of the first element == & amp;arr[0]. The address is 4/8 bytes
//char*
//The size of the pointer variable has nothing to do with the type. No matter what type of pointer variable, the size is 4/8 bytes
//Pointer variables are used to store addresses. How much space is needed to store addresses? The size of the pointer variable is just a few bytes.
//In a 32-bit environment, the address is 32 binary bits and requires 4 bytes, so the size of the pointer variable is just a few bytes
//In a 32-bit environment, the address is 64 binary and requires 8 bytes, so the size of the pointer variable is just a few bytes
//Please don't look at the pointer through the crack in the door, it will flatten the pointer.
printf("%d\\
", sizeof(*arr));
//sizeof(*arr), arr refers to the address of the first element, *arr is the first element of the array, 1 byte
printf("%d\\
", sizeof(arr[1]));
//The second element of the array, the subscript of the array starts from 0, 1 byte
printf("%d\\
", sizeof( & amp;arr));//?
// &arr is the address of the array, which refers to the address of the entire array, array pointer, char(*p)[6]=address, regardless of the type, the size is 4/8 bytes
printf("%d\\
", sizeof( & amp;arr + 1));
// & amp;arr + 1 is the address after skipping the array. Regardless of the type of address, the size is 4/8 bytes
printf("%d\\
", sizeof( & amp;arr[0] + 1));
//The address of the second element, no matter what type the address is, the size is 4/8 bytes
return 0;
}
  • The size of a pointer variable has nothing to do with its type. Regardless of the type of pointer variable, the size is 4/8 bytes.
  • The calculation of pointer variables is related to the type.
  • Pointer variables are used to store addresses. How much space is needed to store addresses? The size of the pointer variable is just a few bytes.
  • In a 32-bit environment, the address is 32 binary bits and requires 4 bytes, so the size of the pointer variable is just a few bytes.
  • In a 32-bit environment, the address is 64 binary bits and requires 8 bytes, so the size of the pointer variable is just a few bytes.

strlen

When we simulated the function of strlen, we wrote size_t my_strlen(const char* str) so strlen receives a character pointer and the address must be passed to strlen.

#include<stdio.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };//6 without \ 0
printf("%d\\
", strlen(arr));
//arr refers to the address of the first element
//strlen counts the number of characters from the first element onward and stops when it encounters \0, but at this time we don't know where \0 is in the memory
// The value obtained here should be a random value
printf("%d\\
", strlen(arr + 0));
//arr + 0 refers to the address of the first element.
//strlen counts the number of characters from the first element onward and stops when it encounters \0, but at this time we don't know where \0 is in the memory
// The value obtained here should be a random value
printf("%d\\
", strlen(*arr));
//*arr refers to the first element.
//Pass the ascll code value 97 of 'a' to strlen, because strlen only accepts addresses.
//So from the perspective of strlen, it is believed that 97 is an address and an illegal address. Direct access will cause illegal access, so an error will be reported. err
printf("%d\\
", strlen(arr[1]));
//arr[1] is the first element 'b'-98
//Same as above err
printf("%d\\
", strlen( & amp;arr));
// &arr is the address of the entire array, which is numerically the same as the address of the first element.
//So, strlen counts the number of characters from the first element onwards and stops when it encounters \0, but at this time we don't know where \0 is in the memory.
// The value obtained here should be a random value
printf("%d\\
", strlen( & amp;arr + 1));
// & amp;arr + 1, the address of the entire array + 1, skipping the entire array, pointing to the element after skipping the entire array
// The address of the entire array is a character array pointer type, // and our strlen receives a character pointer type
// char(*)[6] const char*
//So type conversion will occur here

//Then we don’t know where we will encounter \0 in the memory, so the random value
printf("%d\\
", strlen( & amp;arr[0] + 1));
// & amp;arr[0] + 1, the address of the first element + 1, which points to the address of the second element.
//So, strlen counts the number of characters from the second element onwards and stops when it encounters \0, but at this time we don't know where \0 is in the memory.
// The value obtained here should be a random value
return 0;
}
  • The data accepted by strlen will all be regarded as addresses from the perspective of strlen.
  • The address received by strlen is of const char* character pointer type. When other types are passed in, type conversion will occur.
  • What is the memory distribution of the space pointed to by arr + 1 and & arr + 1 in memory. To know clearly.

String array

–String array has hidden \0

#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\\
", sizeof(arr));
printf("%d\\
", sizeof(arr + 0));
printf("%d\\
", sizeof(*arr));
printf("%d\\
", sizeof(arr[1]));
printf("%d\\
", sizeof( & amp;arr));
printf("%d\\
", sizeof( & amp;arr + 1));
printf("%d\\
", sizeof( & amp;arr[0] + 1));
return 0;
}
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\\
", strlen(arr));
printf("%d\\
", strlen(arr + 0));
printf("%d\\
", strlen(*arr));
printf("%d\\
", strlen(arr[1]));
printf("%d\\
", strlen( & amp;arr));
printf("%d\\
", strlen( & amp;arr + 1));
printf("%d\\
", strlen( & amp;arr[0] + 1));
return 0;
}

sizeof

#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\\
", sizeof(arr));//7
//The calculation is the size of the entire array including \0
printf("%d\\
", sizeof(arr + 0));//4/8
//sizeof calculates the size of the space occupied by a variable
//The calculation is the size of the first element address 4/8
printf("%d\\
", sizeof(*arr));//1
//Calculates the size of the first element 1
printf("%d\\
", sizeof(arr[1]));//1
//Calculate the size of the second element
printf("%d\\
", sizeof( & amp;arr));//4/8
//Calculate the address of the entire array 4/8
printf("%d\\
", sizeof( & amp;arr + 1));//4/8
//Calculate the address pointed to after skipping the entire array 4/8
printf("%d\\
", sizeof( & amp;arr[0] + 1));//4/8
    printf("%d\\
", sizeof(arr + 1));
//Calculate skipping the address of the first element pointing to the address of the second element 4/8
return 0;
}

strlen

#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\\
", strlen(arr));//6
//The address of the first element is calculated backward until it encounters \0 and stops.
printf("%d\\
", strlen(arr + 0));//6
//The address of the first element is calculated backward until it encounters \0 and stops.
printf("%d\\
", strlen(*arr));//'a'--97
//err
printf("%d\\
", strlen(arr[1]));//'b'--98
//err
printf("%d\\
", strlen( & amp;arr));//6
//The address of the entire array is numerically == the address of the first element. Calculate backward until it encounters \0 and stops.
printf("%d\\
", strlen( & amp;arr + 1));//Random value
//The address pointed to after skipping the entire array. When will it encounter \0 later? Unknown, random value
printf("%d\\
", strlen( & amp;arr[0] + 1));//5
printf("%d\\
", strlen(arr + 1));//5
//Point to the address of the second element, and calculate backward until it encounters \0 and stops.
return 0;
}

String pointer char *p

Before that, you can review the character pointer

Advanced Pointers in C Language (1)_Tang Didi’s Blog-CSDN Blog

#include<stdio.h>
int main()
{
char* p = "abcdef";
printf("%d\\
", sizeof(p));
printf("%d\\
", sizeof(p + 1));
printf("%d\\
", sizeof(*p));
printf("%d\\
", sizeof(p[0]));
printf("%d\\
", sizeof( & amp;p));
printf("%d\\
", sizeof( & amp;p + 1));
printf("%d\\
", sizeof( & amp;p[0] + 1));

printf("%d\\
", strlen(p));
printf("%d\\
", strlen(p + 1));
printf("%d\\
", strlen(*p));
printf("%d\\
", strlen(p[0]));
printf("%d\\
", strlen( & amp;p));
printf("%d\\
", strlen( & amp;p + 1));
printf("%d\\
", strlen( & amp;p[0] + 1));
return 0;
}

sizeof

#include<stdio.h>
int main()
{
char arr[] = "abcdef";
char* p = "abcdef";
printf("%d\\
", sizeof(p));//4/8
//p is a character pointer, which stores the address and the size is 4/8
//p refers to the address of the first element
printf("%d\\
", sizeof(arr));//7

printf("%d\\
", sizeof(p + 1));//4/8
//p + 1, calculates the address of the second element, size 4/8

printf("%d\\
", sizeof(*p));//1
//The first element 'a', pointer dereference, look at the pointer type, char*, accesses 1 byte
printf("%d\\
", sizeof(p[0]));//1

printf("%d\\
", sizeof( & amp;p));//4/8
printf("%d\\
", sizeof( & amp;p + 1));//4/8
printf("%d\\
", sizeof( & amp;p[0] + 1));//4/8
return 0;
}
  • Dereference the pointer, look at the type of the pointer, and then decide how many bytes to access.
  • Pointer calculation, look at the type of pointer, and then decide how many bytes to skip.
  • The size of the pointer, no matter what type, is 4/8 bytes

strlen

#include<stdio.h>
int main()
{
char arr[] = "abcdef";
char* p = "abcdef";
printf("%d\\
", strlen(p));//6
printf("%d\\
", strlen(p + 1))//5
printf("%d\\
", strlen(*p));//err
printf("%d\\
", strlen(p[0]));//err
printf("%d\\
", strlen( & amp;p));//Random value
printf("%d\\
", strlen( & amp;p + 1));//Random value
printf("%d\\
", strlen( & amp;p[0] + 1));//5
return 0;
}

sizeof in two-dimensional array

#include<stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%zd\\
", sizeof(a));
printf("%zd\\
", sizeof(a[0][0]));
printf("%zd\\
", sizeof(a[0]));
printf("%zd\\
", sizeof(a[0] + 1));
printf("%zd\\
", sizeof(*(a[0] + 1)));
printf("%zd\\
", sizeof(a + 1));
printf("%zd\\
", sizeof(*(a + 1)));
printf("%zd\\
", sizeof( & amp;a[0] + 1));
printf("%zd\\
", sizeof(*( & amp;a[0] + 1)));
printf("%zd\\
", sizeof(*a));
printf("%zd\\
", sizeof(a[3]));
return 0;
}
//The return value of sizeof is size_t, so it is best to use %zd for printing
//Two-dimensional array
#include<stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%zd\\
", sizeof(a));//4*3*4=48
//The two-dimensional array name is placed separately inside sizeof. The size of the entire array is calculated, and the unit is bytes.
printf("%zd\\
", sizeof(a[0][0]));//4
//Elements in the first row and column, calculate the size of an element, integer, unit byte


printf("%zd\\
", sizeof(a[0]));//16
//The array name a[0] of the first line is placed alone inside sizeof. The size of the entire first line is calculated, 4*4=16
//a[0] represents the entire first row of the one-dimensional array, and sizeof(a[0]) calculates the size of the entire first row of the one-dimensional array.
printf("%zd\\
", sizeof(a[0] + 1));//4/8
//The array name in the first line is not placed inside sizeof alone, and there is no & amp;, indicating the address of the first element of the first line
//That is, the address of the first element in the first row a[0]== & amp;a[0][0] a[0] + 1== & amp;a[0][1]
// + 1 represents the address of the second element in the first row.
printf("%zd\\
", sizeof(*(a[0] + 1)));//4
//* Dereference, indicating the second element



printf("%zd\\
", sizeof(a + 1));//4/8
//a is not placed separately inside sizeof,
//Represents the address of the first element of the two-dimensional array, that is, the address of the first row, the type of a int(*)[4]---array pointer
// + 1 represents the address of the second line.
printf("%zd\\
", sizeof(*(a + 1)));//4*4=16
//Dereference, indicating the size of the entire second line, integer 4*4
//*(a + 1) == a[1]
//sizeof(a[1]) --- a[1] represents the array name of the second line, which is placed separately inside sizeof.
    //That is, the size of the entire second row is calculated.

printf("%zd\\
", sizeof( & amp;a[0] + 1));//4/8
//a[0] represents the array name of the first row, & amp; represents the address of the first row, the type is int(*)[4],
// + 1 represents the address of the second line, type int(*)[4]
printf("%zd\\
", sizeof(*( & amp;a[0] + 1)));//16
//Dereference, indicating the size of the second line


printf("%zd\\
", sizeof(*a));//16
//a is not placed alone inside sizeof. a represents the address of the first element of the two-dimensional array, that is, the address of the first row.
// Dereference indicates the size of the first row
//*a == *(a + 0) == a[0]

printf("%zd\\
", sizeof(a[3]));//4/8
//Same type as a[0] int * [4], address of the entire row, 4/8
//sizeof calculates the size based on the type attribute of the expression. It does not actually access the fourth line and does not cross the boundary.
//a[3] a[0]
//int [4] int[4]

return 0;
}

Summary

One-dimensional array int arr[7]={0}; two-dimensional array int arr[3][4]={0};

  • Putting the array name alone inside sizeof means it is an array (number of array elements? size of space occupied by array element type)
  • &array name retrieves the address of an entire array (the numerical value is the same as the address of the first element, the difference can be seen after + 1)
  • One-dimensional array array name arr, first determine whether it is placed alone inside sizeof, & amp; array name. Except for the above cases, it is the first element address.
  • Two-dimensional array array namearr/arr[0]/arr[1]/arr[2], Same as above
  • Two-dimensional arrays are stored continuously in memory (actual picture), arrays of arrays, and the subscripts start from 0 when looking for rows and columns (picture in mind)
  • Writing methodarr[2] = *(arr + 2)

Pointer

  • Dereference the pointer, look at the type of the pointer, and then decide how many bytes to access.
  • Pointer calculation, look at the type of pointer, and then decide how many bytes to skip.
  • The size of the pointer, no matter what type, is 4/8 bytes

Character and string arrays

  • There is no \0 in the character array. There is a hidden \0 in the string array

sizeof and strlen

  • sizeof

sizeof is an operator.
The size of the memory occupied by sizeof is calculated in bytes.
Counting the string includes \0 and the number of characters before \0.
Counting characters is the number of characters.
The object calculated by sizeof can be of any type. The size of the space occupied by the expression calculated by sizeof is determined by the expression type attribute to determine the space occupied by the value in the memory.

  • strlen

strlen is a library function.
strlen counts the length of a string.
strlen stops calculating when it encounters \0.
strlen can only be used for strings, and the calculated string does not include \0.
When strlen counts characters, it cannot encounter \0, so it has a random value.
strlen cannot calculate the length of integer and character arrays because it stops when it encounters \0.

  • Notice
  • When strlen calculates the length of a string, it counts the number of characters that appear before the string \0.
  • When sizeof calculates the length of a string, it counts the number of characters that appear before \0 and \0.
  • The address must be passed to strlen, and any writing method can be passed to sizeof.

?Finally, thank you all for reading. If there are any errors or shortcomings, please correct me! The above questions have many similarities, so once you understand one group, I believe you will be able to follow them later. less talking, more working

Code——→[gitee: Tang Didi (TSQXG) – Gitee.com]

Contact——→[Email: [email protected]]