How much do you know about sizeof and strlen

 

1. The difference between sizeof() and strlen()

1. sizeof() is a monocular operator, not a function. It calculates the size of the space occupied by the parameter , that is, the number of bytes (note: the string usually ends with'\0', so the space occupied by the string is calculated When the size of, also include'\0')

2.strlen () is a function for calculating a character string of the actual length (the actual length of the string does not contain the calculated '\ 0', if the definition of a character array char arr [] = "helloworld" , '\ 0' It is the last element of the array. Although we cannot see it, it is also part of the string, but what we actually see is "helloword", so the actual length means the length of the string we actually see. Contains'\0')

2. Other concepts

1. The difference between pointers and arrays

In order to facilitate the calculation of the following exercises, first of all, we should also figure out the difference between pointers and arrays

In fact, pointers and arrays are completely unrelated concepts, so it is unscientific to say what is the difference between the two.

The reasons that confuse us are:

       The array itself has only subscript removal operations, but in some cases it will be implicitly converted to pointers (in C language):

     ① Function parameter transfer

     ②Addition and subtraction

     ③ Dereference

     ④Comparison operation

     However, the pointer can be subscripted by [], which is very similar to an array in behavior

2. The difference between int* const p and const int* p

①int * const p is equivalent to const * int p, where the content of p cannot be modified , that is, the address saved in p cannot be modified, so the following operation result is wrong (for the convenience of memory, I came up with a Appropriate way to understand, * does not follow p immediately, so it means the pointer variable p itself, that is, the content of the p variable cannot be changed)

int a = 5;
int b = 10;
int* const p = &a; //p保存的地址不能被修改
p = &b;
printf("%d\n", *p);

②const int* p, where the content pointed to by p cannot be modified , so the following operation result is wrong (for the convenience of memory, I came up with a method that may not be appropriate to understand, *following p is equivalent to pointer p Dereference, that is, the content pointed to by p cannot be changed)

int a = 5;
int b = 10;
const int* p = &a; //p中保存的地址所指向的内容不能被修改,即a的值不能被修改
*p = 20;
printf("%d\n", *p);

Three, practice

1. Exercises for one-dimensional integer arrays

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

arr is an integer array with a length of 4. In a 32-bit system, an int occupies 4 bytes, and a pointer type occupies 4 bytes. Let’s follow the 32-bit system to practice~ (under the 16-bit operating system, an int occupies 2 bytes, and the pointer type occupies 2 bytes; under the 64-bit system, int occupies 4 bytes, and the pointer type occupies 8 bytes)

①sizeof()

printf("%d\n", sizeof(arr));//数组名表示首元素的地址,因为数组中的元素在内存中是连续存放的,所以我们可以通过首元素的地址访问整个数组,即要求整个数组所占的空间大小,即sizeof(arr)=4*4=16
printf("%d\n", sizeof(arr + 0));//前面提到数组名+操作会触发隐式转换,arr表示首元素的地址,隐式转换成为指向首元素的指针,即sizeof(int*)=4
printf("%d\n", sizeof(*arr));//数组名表示首元素的地址,*使其隐式转化成为指针int*,对其解引用就是sizeof(int)=4
printf("%d\n", sizeof(arr + 1));//32位系统下,指针类型一律占4个字节,sizeof(int *)=4
printf("%d\n", sizeof(arr[1]));//数组的第二个元素所占空间的大小即sizeof(int)=4
printf("%d\n", sizeof(&arr));//对数组的首元素的地址取地址得到一个数组指针即sizeof(int(*)[4])=4
printf("%d\n",sizeof(*&arr));//根据操作符的优先级和结合性,&arr得到数组指针int(*)[4],再对其解引用得到int[4],即sizeof(int[4])=16
printf("%d\n", sizeof(&*arr));//首先触发隐式转换得到int*,解引用得到int,再对其取地址得到int*,即sizeof(int*)=4
printf("%d\n", sizeof(&arr + 1));//sizeof(int(*)[4]+1)=4,指针类型~
printf("%d\n", sizeof(&arr[0]));//sizeof(int *)=4,指针类型~
printf("%d\n", sizeof(&arr[0] + 1));//sizeof(int *)=4	指针类型~

2. The practice of two-dimensional integer array

int arr[3][4] = { 0 };

①sizeof()

printf("%d\n", sizeof(arr)); //sizeof(int[3][4]))=12*4=48
printf("%d\n", sizeof(arr[0]));//sizeof(int[4])=4*4=16
printf("%d\n", sizeof(arr[0]+1));//sizeof(int*[4])=4
printf("%d\n", sizeof(&arr[0]+1));//sizeof(int**[4])=4
printf("%d\n", sizeof(arr[0][0]));//sizeof(int)=4
printf("%d\n", sizeof(*arr[0]));//sizeof(int)=4
printf("%d\n", sizeof(*arr));//sizeof(int[4])=4*4=16
printf("%d\n", sizeof(*(arr + 1)));//sizeof(int[4])=16
printf("%d\n", sizeof(&arr[0] + 1));//sizeof(int*[4])=4
printf("%d\n", sizeof(*(arr[0]) + 1));//sizeof(int)=4

3. Practice of character array (1)

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };

Note: the character array above, there is no'\0' when initializing

            Only when char arr[]="abcdef" is initialized,'\0' will be automatically added

①sizeof()

printf("%d\n", sizeof(arr));//sizeof(char[6])=6
printf("%d\n", sizeof(arr + 0));//sizeof(char*)=4
printf("%d\n", sizeof(*arr));//sizeof(char)=1
printf("%d\n", sizeof(arr+1));//sizeof(char*)=4
printf("%d\n", sizeof(arr[1]));//sizeof(char)=1
printf("%d\n", sizeof(&arr));//sizeof(char(*)[6])=4
printf("%d\n", sizeof(*&arr)); //sizeof(char[6])=6
printf("%d\n", sizeof(&*arr)); //sizeof(char*)=4
printf("%d\n", sizeof(&arr[1]+1));//sizeof(char*)=4
printf("%d\n", sizeof(&arr + 1));//sizeof(char(*)[6])=4

②strlen()

Note: strlen() calculates the actual length of the string

printf("%d\n", strlen(arr));//???未定义行为
printf("%d\n", strlen(arr+0));//strlen(char*)???未定义行为
printf("%d\n", strlen(*arr));//strlen(arr[0])???
printf("%d\n", strlen(arr[1]));//???
printf("%d\n", strlen(&arr));//???
printf("%d\n", strlen(&arr + 1));//???
printf("%d\n", strlen(&arr[0]) + 1);//???

4. Practice of character array (2)

char arr[] = "abcdef";

Note: At this time, we store a string in the array, ending with'\0'

①sizeof()

printf("%d\n", sizeof(arr));//sizeof(char[7])=7
printf("%d\n", sizeof(arr+0));//sizeof(char*)=4
printf("%d\n", sizeof(*arr));//sizeof(char)=1
printf("%d\n", sizeof(arr[1]));//sizeof(char)=1
printf("%d\n", sizeof(&arr[0]+1));//sizeof(char*)=4
printf("%d\n", sizeof(&arr));//sizeof(char(*)[7])=4
printf("%d\n", sizeof(*&arr));//sizeof(char[7])=7
printf("%d\n", sizeof(&*arr));//sizeof(char*)=4
printf("%d\n", sizeof(&arr+1));//sizeof(char(*)[4])=4

②strlen()

printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr+1));//5
printf("%d\n", strlen(&arr+1));//类型不匹配
printf("%p\n", strlen(&arr));//6  类型不匹配  strlen(char(*)[7])=6
printf("%d\n", strlen(&arr[0]));//strlen(char*arr[7])=6
printf("%d\n", strlen(*&arr));//char(*)[7]->char[7]  strlen(char[7])=6
printf("%d\n", strlen(&*arr));//char*arr[0]->char arr[0]->char *arr[0] strlen(char *arr[0])=6
printf("%d\n", strlen(&arr[1]+1));//char* arr[1]->char* arr[2] strlen(char* arr[2])=4 

5. The exercise of the pointer to the first element of the string

char* p = "abcdef";

Note: At this time, p is a pointer variable, pointing to the first element of the string, and its content is the address of the first element of the string

①sizeof()

printf("%d\n", sizeof(p));//sizeof(char*)=4
printf("%d\n", sizeof(p + 1));//sizeof(char*)=4
printf("%d\n", sizeof(*p));//sizeof(char)=1
printf("%d\n", sizeof(p[0]));//sizeof(char)=1
printf("%d\n", sizeof(&p));//sizeof(char**)=4
printf("%d\n", sizeof(&p[1]+1));//sizeof(char*)=4
printf("%d\n", sizeof(*&p));//sizeof(char*)=4
printf("%d\n", sizeof(&*p));//sizeof(char**)=4

②strlen()

printf("%d\n",strlen(p));//strlen(char*[0])=6	
printf("%d\n", strlen(p + 1));//strlen(char*[1])=5
printf("%d\n", strlen(*p));//strlen(char[0]) 类型不匹配
printf("%d\n", strlen(p[1]));//类型不匹配
printf("%d\n", strlen(&p));//类型不匹配
printf("%d\n", strlen(&p[1] + 1));//strlen(char *p[2])=4
printf("%d\n", strlen(*&p));//strlen(char*)=6
printf("%d\n", strlen(&*p));//strlen(char*)=6

6. Other topics

Find the output result of the following code

#include<stdio.h>
#include<windows.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);
   system("pause");
   return 0;
}

About ptr1[-1]: After a lot of exercises above, we can know that &a is an array pointer int(*a)[4], and +1 to it means skip the entire array, ptr1 points to the last element of the array Position is also a special position, so ptr[-1] is actually the last element of the array, which is 4

Regarding *ptr2: the array name a represents the address of the first element of the array, (int)a means that this address is forced to be converted to int type, assuming the address of the first element of the array is 0x100, then the result of (int)a is 0x100 , And +1 the result is 0x101, and finally the pointer of ptr2 points to 0x101, which is printed, because it is coerced to (int *) type, which occupies 4 bytes, so four words are read backward The section is shown in the figure below:

 

Finally get 00 00 00 02

According to the little-endian byte order (the high order is at the high address), the output result is  2000000

 

The above is some of my understanding of sizeof() and strlen(), the description is a bit rough, you can point out what is wrong~~

 

 

Guess you like

Origin blog.csdn.net/weixin_43939602/article/details/109704098