Specific use of sizeof and strlen + detailed explanation of pointers and arrays written test questions - part 1


foreword

This article introduces the written test questions of pointers and arrays in detail, taking one-dimensional arrays and pointer arrays as examples. The methods used in other arrays are unchanged. It is important for readers to learn the methods and draw inferences from one instance.


Tip: The following is the main text of this article, the following cases are for reference

1. sizeof

1.1 One-dimensional arrays

Before learning this part, let's review a few knowledge points:
1. sizeof (array name) - calculates the size of the entire array
2. & array name - the array name represents the entire array, and the address of the entire array is taken out
3. Except for 1 and 2, all other array names are the addresses of the first elements of the array. The
code is as follows (example):

#include<stdio.h>
int main()
{
    
    
	int a[] = {
    
     1,2,3,4 };
	printf("%d\n", sizeof(a));
	//数组共4个元素,每个元素都是整形占4个字节,打印16
	printf("%d\n", sizeof(a+0));
	//sizeof(a+0),数组名并没有单独放sizeof内部,这里是a是作为数组首元素地址
	//a+0还是首元素地址,大小为4或8个字节,4或8取决于当前环境是32位还是64位
	printf("%d\n", sizeof(*a));
	//*a,a是数组首元素地址,对其解引用也就是数组第一个元素1,占4个字节
	printf("%d\n", sizeof(a+1));
	//a是数组首元素地址,地址加1,也就是数组第二个元素地址,占4或8个字节
	printf("%d\n", sizeof(a[1]));
	//a[1]即数组第2个元素2,占4个字节
	printf("%d\n", sizeof(&a));
	//&a是,a表示的是整个数组
	//这里要注意的是,即使是整个数组的地址,它本质任然是个地址,占4个字节
	printf("%d\n", sizeof(*&a));
	//&a是数组的地址,*&a也就是对数组的地址进行解引用,得到的是整个数组大小,为16
	//类别sizeof(a),打印也是16,*&a也就是拿出地址,再找到地址里的东西,地址里的东西就是a
	printf("%d\n", sizeof(&a+1));
	//&a拿出了数组地址,数组的地址+1是跳过一个数组得到一个地址,只要是一个地址,大小为4或8
	printf("%d\n", sizeof(&a[0]));
	//a[0]是数组首元素,&a[0]即取首元素地址,地址大小4或8
	printf("%d\n", sizeof(&a[0]+1));
	//同上,是取出首元素地址再加1,到第二个元素地址,地址大小4或8
	return 0;
}

ps: Why do addresses occupy 4 or 8 bytes?
Explanation: The address is just a number of the memory in the computer , no matter what type of integer, floating point, etc. you are, or even the address of an array, it is just a number, which is uniformly occupied by 4 or 8 bytes (4 or 8 depending on whether the current environment is 32-bit or 64-bit).

The code is as follows (example):

1.2 Character arrays

#include<stdio.h>
int main()
{
    
    
	char arr[6] = {
    
     'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
	//数组共6个元素,每个元素都是字符型占1个字节,打印6
	printf("%d\n", sizeof(arr + 0));
	//sizeof(arr+0),数组名并没有单独放sizeof内部,这里是arr是作为数组首元素地址
	//arr+0还是首元素地址,大小为4或8个字节,4或8取决于当前环境是32位还是64位
	printf("%d\n", sizeof(*arr));
	//arr是首元素地址,对其解引用,得到字符a,a占1个字节
	printf("%d\n", sizeof(arr[1]));
	//数组首元素a,占1个字节
	printf("%d\n", sizeof(&arr));
	//对数组取地址,本质任然是地址,占4或8个字节
	printf("%d\n", sizeof(&arr+1));
	//对数组取地址,数组的地址+1是跳过一个数组得到一个地址,地址占4或8个字节
	printf("%d\n", sizeof(&arr[0]+1));
	//对数组第一个元素a取地址,地址再加1到元素b的地址,地址占4或8字节
	return 0;
}

1.2.1 String to initialize array

Comparing 2, we can easily find that the two initialization methods of character arrays are {a,b,c,d,e,f}, and the other is "abcdef".
So what is the difference? When using "abcdef" to initialize, a \0 will be automatically added to the end of abcdef.
That is to say, in addition to the 6 characters of abcdef in the array arr, there is also a character of \0, a total of 7 characters. The
codes are as follows (example):

#include<stdio.h>
int main()
{
    
    
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));
	//sizeof求整个数组大小,arr共7个字节即abcdef和\0
	printf("%d\n", sizeof(arr + 0));
	//arr没有单独放sizeof内部,所以这里的arr是作为数组首元素地址出现,+0仍然是首元素地址,地址大小4或8
	printf("%d\n", sizeof(*arr));
	//arr是首元素地址,*arr对首元素地址解引用得到a,占1个字节
	printf("%d\n", sizeof(arr[1]));
	//arr[1]是数组第二个元素b,占1个字节
	printf("%d\n", sizeof(&arr));
	//&arr,得到数组arr地址,本质仍然是地址,占4或8字节
	printf("%d\n", sizeof(&arr+1));
	//&arr+1跳过一个数组长度得到一个地址,本质仍然是地址,占4或8字节
	printf("%d\n", sizeof(&arr[0]+1));
	//对数组第一个元素a取地址,地址再加1到元素b的地址,地址占4或8字节
	return 0;
}

2. strlen

Regarding the strlen library function, we need to know that it is used to find the length of the string. Give it a starting address, and it will look for it by itself . Where does it stop when it finds it? When \0 appears, strlen ends the search

2.1 General array initialization

The code is as follows (example):

#include<stdio.h>
int main()
{
    
    
	char arr[] = {
    
     'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));
	//这里会打印一个随机值
	//因为我们数组arr开辟了一块空间里面放abcdef,但是内存中arr后面的空间有什么,我们是不知道的,所以对于\0什么时候出现,我们也是不知道的
	printf("%d\n", strlen(arr + 0));
	//arr+0,数组首元素地址+0,任然是数组首元素地址,strlen从arr开始往后数,到出现\0结束,但我们仍不知道\0何时出现,所以这里也是随机值
	printf("%d\n", strlen(*arr));
	//arr是数组首元素a的地址,*arr即对a地址解引用得到a
	//那我们知道strlen是给一个地址往后找,直到\0出现
	//给一个字符‘a’是什么意思?——字符a在ascll码表中对应号码97,计算机会自认为是地址97,然后从97这个地址往后找\0,所以这里也是随机值
	printf("%d\n", strlen(arr[1]));
	//这里同理,arr[1]是b,其ascll码为98,计算机会自认为是地址98,然后从98这个地址往后找\0,所以这里也是随机值
	printf("%d\n", strlen(&arr));
	//这里&arr,得到数组arr的地址,然后strlen往后找\0,是随机值
	printf("%d\n", strlen(&arr+1));
	//数组的地址加1,是跳过一个数组的地址,然后strlen往后找\0,是随机值,该随机值和上一个随机值会差6(1个数组长度)
	printf("%d\n", strlen(&arr[0]+1));
	//a的地址加1,跳过一个字符到b的地址,往后找\0,也是一个随机值
	return 0;
}

ps1: Regarding strlen(&arr), when we look for the specific library function strlen, we will find that the function definition is
strlen(char *)
, that is to say, it receives a pointer of type char*, and &arr passes char
A pointer of type ( * )[] . Although the compiler will report a warning, this pointer can still be passed
. After passing it, a forced type conversion will be performed, and this address is the address of the array arr. We know that the address of the array arr and the address of the first element a of the array The essence is different, but the address is the same, the compiler will consider this address to be the address of character a , and then look backward until it finds \0

ps2: When we access memory out of bounds, the compiler may report an error . The above example is for readers to learn clearly, and they should be aware of the problem during specific programming operations.

2.2 String to initialize array

#include<stdio.h>
int main()
{
    
    
	char arr[] = "abcdef";
	printf("%d\n", strlen(arr));
	//因为数组arr初始化方法为"abcdef",所以f后会自动跟一个\0,而strlen即是找到\0结束,所以这里是6
	printf("%d\n", strlen(arr + 0));
	//arr+0,是a的地址,从a的地址开始找,到\0结束,这里是6
	printf("%d\n", strlen(*arr));
	//*arr拿到字符a,ascll码97
	//注意!!!:这里找到的是一个野指针,是会报错的
	printf("%d\n", strlen(arr[1]));
	//arr[1]是b,ascll码98,同上,也是一个野指针
	printf("%d\n", strlen(&arr));
	//&arr取出的是数组的地址,类型char(*)[]但传过去会被强制类型转换,被默认为是字符a的地址,从a到\0共6字符
	printf("%d\n", strlen(&arr+1));
	//&arr+1取出数组地址后再往后跳一个数组长度得到地址,该地址后什么时候出现\0是未知的,所以是随机值
	printf("%d\n", strlen(&arr[0]+1));
	//&arr[0]+1是先取出数组首元素地址,往后跳一个元素地址,也就是b的地址,从b往后找到\0,是5
	return 0;
}

ps: Note the difference between strlen(*arr) and sizeof(*arr) here:

strlen(*arr):
*arr gets the character a, ascll code 97, and then looks back from the address of 97. We have not used the address of 97 before, so we don't know what is in the address of 97. After it, there is What, this is a typical wild pointer , the compiler will report an error.

sizeof(*arr):
*arr gets the character a, sizeof calculates the size of the character a, which is 1 byte


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324127256&siteId=291194637
Recommended