Must-learn classic exercises in C language

Table of contents

Exercise 1: Related calculations about one-dimensional array sizeof

answer:

Running results (the editor's version is x64 environment)

Exercise 2: Related calculations about character arrays and library function strlen

Note: Introduction to library function strlen

answer:


Exercise 1: Related calculations about one-dimensional array sizeof

int main()
{
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));//(一)
printf("%d\n",sizeof(a+0));//(二)
printf("%d\n",sizeof(*a));//(三)
printf("%d\n",sizeof(a+1));//(四)
printf("%d\n",sizeof(a[1]));//(五)
printf("%d\n",sizeof(&a));//(六)
printf("%d\n",sizeof(*&a));//(七)
printf("%d\n",sizeof(&a+1));//(八)
printf("%d\n",sizeof(&a[0]));//(九)
printf("%d\n",sizeof(&a[0]+1));//(十)
return 0;
}

Note: There are two very important things to know about array names:

①: sizeof (array name), the array name here represents the entire array, so the size of the entire array is calculated.

②: & array name, the array name here represents the entire array.

③: Except for the above two cases, the array names in other cases represent the address of the first element.

answer:

(1), is sizeof(a), where a represents the entire array, so the answer is 16 bytes .

(2) For sizeof(a+0), many partners may think that a and a+0 are not the same thing? It’s really not the same thing. When there is only a single array name in sizeof, the size of the entire array is calculated. Here is a+0, which represents the address of the first element + 0. The result is still the address of the first element, so The answer is 4 or 8 bytes (4 in x86 environment, 8 in x64 environment).

(3) It is sizeof(*a), not the above two special cases, so here is the address dereference of the first element to get the value of the first element, and because this is an integer array, the answer is 4 bytes .

(4) is sizeof(a+1), which is similar to (2). It is the address of the first element + 1, and the address of the second element is obtained. The address size is 4 or 8 bytes, so the answer is 4 or 8 bytes .

(5) It is sizeof(a[1]), which is obviously the second element, so the answer is 4 bytes . Here is a formula to understand

                                                           a[n]=*(a+n)

(6) It is sizeof(&a). Please don’t confuse the above two special cases. Although &a here takes the address of the entire array, isn’t the address of the array still an address? The address size is 4 or 8 bytes, so the answer is 4 or 8 bytes .

(7) For sizeof(*&a), there are two ways of thinking about this question:

①: From the perspective of operators: * and & can cancel each other out, so sizeof(*&a) is equivalent to sizeof(a), so the array name a here represents the entire array, so the answer is 16 bytes .

②: From the perspective of array pointers: &a takes the address of the array, so it should be placed in an array pointer. What do you get by dereferencing the array pointer? We know that dereferencing an integer pointer will result in an integer, and dereferencing a character pointer will result in a character, so dereferencing an array pointer will naturally result in an array, so the answer is 16 bytes .

(8) is sizeof(&a+1), which is similar to (6). &a takes the address of the entire array. Address + 1 is still an address. The address size is 4 or 8 bytes, so the answer is 4 or 8 bytes .

(9) It is sizeof(&a[0]). It is obvious that &a[0] is the address of the first element, and the address size is 4 or 8 bytes, so the answer is 4 or 8 bytes .

(10), is sizeof(&a[0]+1), similar to (9), &a[0] is the address of the first element, &a[0]+1 is the address of the second element, so the answer is 4 or 8 bytes .

Running results (the editor's version is x64 environment)

This ends the first question. How many can you get right?

Exercise 2: Related calculations about character arrays and library function strlen

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

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("(一):%d\n", strlen(arr));//(一)
	printf("(二):%d\n", strlen(arr + 0));//(二)
	printf("(三):%d\n", strlen(*arr));//(三)
	printf("(四):%d\n", strlen(arr[1]));//(四)
	printf("(五):%d\n", strlen(&arr));//(五)
	printf("(六):%d\n", strlen(&arr + 1));//(六)
	printf("(七):%d\n", strlen(&arr[0] + 1));//(七)
	return 0;
}

Note: Introduction to library function strlen

①: The function of the library function strlen is to calculate the length of a string, and the parameter receives the first address of the string.

②: Calculation rules: Count the number of characters before '\0' in the string. If \0 is not found, it will count backwards.

③: Function declaration:

size_t strlen ( const char * str );

answer:

(1) is strlen(arr), where arr represents the address of the first element, but there are many types of character array initialization. For example, use case initialization, many partners will think the answer is 6 , but in fact it is not. This initialization method will not automatically put at the end '\0', so strlen will keep counting until it finds '\0', so the answer is a random value .

(2) is strlen(arr+0), arr represents the address of the first element, and arr+0 also represents the address of the first element, so the same as (1), the answer is also a random value .

(3) It is strlen(*arr). Many people may think this way, arr represents the address of the first element, dereferencing arr represents the first element, and strlen is to find the length of the string, so the result is 1, but in fact it is not . We notice that the formal parameter in the declaration of the s trlen function is "const char* str", which means that the actual parameter we need to pass is the first address of the string whose length is to be found , so when we pass the first element to strlen, That is, the character 'a' is passed to strlen, and the ASCII code of character 'a' is 97, so if the character 'a' is passed to strlen, strlen will count '97' as the address 00 00 00 97, and this The space does not belong to us, so there is the problem of illegal access to memory , so this way of writing is wrong .

(4) is strlen(arr[1]). This writing method is similar to (3). The character 'b' is passed to strlen , so there is a problem of illegal memory access , so this writing method is wrong .

(5) is strlen(&arr), where &arr takes the address of the entire array, and the address of the array is the same as the address of the first element of the array, so strlen will start counting from the first element until '\0' is found, so The situation is the same as (1) with random values .

(6) It is strlen(&arr+1). Many partners here think that &arr+1 is the address of the second element . In fact, it is not the case. First of all, &arr takes the address of the array, and the address of the array should be placed on the array pointer. Inside, we also know that the pointer type determines the pointer dereference access rights and the steps that can be skipped when adding or subtracting integers . Integer dereference accesses an integer, and integer pointer +1 skips the space of an integer (4 words section), so the same principle applies here. The array pointer +1 will skip an array space, so strlen will start counting from the end of the array, that is, the space behind the character 'f', because we don't know when we will encounter '\ 0', so the result is also a random value .

(7) It is strlen(&arr[0]+1). Here &arr[0] takes the address of the first element, so it is received by the character pointer, so the character pointer+1 only skips 1 byte, so &arr[0 ]+1 accesses the address of the second element, but it still doesn't know when it encounters '\0', so the result is also a random value .

This knowledge is here, the editor will continue to update in the future!

Guess you like

Origin blog.csdn.net/hffh123/article/details/132279621