One hundred thousand cold knowledge of C language

Table of contents

1. printf return value:

2. scanf

3. sizeof return value

 4. [ ] subscript reference operator

 5. Substitution of { } and [ ]

 6. String concatenation

 7. Arrays and array names


1. printf return value:

Success: returns the number of printed characters

Failure: return EOF, EOF is the end of the file, and the macro definition is -1

#include <stdio.h>
int main() {
	char str[] = "123456789";
	printf("%d\n", printf("%d\n", printf("%s\n", str)));
	return 0;
}

 The innermost printf prints "123456789\n", a total of 10 characters, and the return value is 10, which is printed by the second printf, and so on.

2. scanf

Success: Returns the number of successful inputs, which may be 0

Failure: return EOF, EOF is the end of the file, and the macro definition is -1

#include <stdio.h>
int main() {
	int a = 0, b = 0;
	printf("scanf返回值=%d\n", scanf("%d %d", &a, &b));
	printf("a=%d\nb=%d", a, b);
	return 0;
}

 

 Thus it is possible to write code of the following type:

#include <stdio.h>
int main() {
	int a;
	char arr[10] = { 0 };
	while (scanf("%d %s", &a, arr)==2){
		printf("%d %s\n", a, arr);
	}
	return 0;
}

3. sizeof return value

The return value of sizeof is size_t type, which is an unsigned integer, representing the size of the occupied memory, and the unit is byte.

 size_t is defined in stddef.h by some C/C++ standards. The size_t type represents the maximum length that any object in C can achieve. It is an unsigned integer. It is defined for the convenience of porting between systems, and size_t may be defined differently on different systems. size_t is defined as unsigned int on a 32-bit system, that is, a 32-bit unsigned integer. Defined as unsigned long on a 64-bit system, that is, a 64-bit unsigned integer. The purpose of size_t is to provide a portable way to declare a size consistent with addressable regions of memory in the system.
It is recommended to use %zu to print, and %u and %lu are sometimes available.

#include <stdio.h>
int main() {
	char a[] = "123456789";
	char* p = a;
	printf("%zu", sizeof(p));
	return 0;
}

 

 4. [ ] subscript reference operator

#include <stdio.h>
int main() {
	char a[] = "123456789";
	printf("%c\n", a[5]);
	printf("%c\n", 5[a]);
	printf("%c\n", *(&a[0] + 5));
	printf("%c\n", "123456789"[5]);
	printf("%c\n", 5["123456789"]);
	printf("%c\n", *("123456789"+5));
	return 0;
}

At first glance, what is this thing, what a weird code. First you have to figure out what [ ] means.

There are two ways to define a string:

char* p="123456789"

char a[]="123456789"

Both can define strings, when outputting a character in the string:

*(p+i);

a[i]

The two are equivalent, so *(a+i)=a[i]

The definition of the [ ] operator is given below:

1. When defining an array, apply for a continuous space to the compiler.

2. The pointer [ i ] indicates that starting from the current position of the pointer, skip backward i space of the size of the type pointed to by the pointer.

3.p[q] is equivalent to *(p+q), if pq is not a pointer, an error will be reported!

According to the third clause, we can write the code
 

 5. Substitution of { } and [ ]

Under some compilers, such as dev 5.11, we can use <: and :> instead of [ and ], and <% and %> instead of { and }.

#include <stdio.h>
int main() 
<%
	char a<::>="abcdefghigk";
	printf("%s",a);
	return 0;
%>

 6. String concatenation

When the strings surrounded by "" are put together, a string will be automatically spliced;

#include <stdio.h>
int main() {
	char* str = "aaaa""bbbb"\
				"cccc";
	printf("%s", str);
	return 0;
}

 7. Arrays and array names

Do you really understand arrays and array names? Array names can be tricky. For example, if I define an array int arr[10], do you know what arr stands for? After reading it, you may refresh your knowledge of array names.

1. Represents the address of the first element, note that it represents the address of the first byte of the first element.

2. sizeof(arr) and &arr represent the address of the entire address (two special)

#include <stdio.h>
int main() {
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", arr+1);
	printf("%p\n", &arr);
	printf("%p\n", &arr+1);
	return 0;
}

Print arr and &arr to find that the address is the same, you have to remember that the address is the same but its meaning is very different, arr is the address of the first element, arr+1 represents the address of the second element, the step size is 4 bytes, also It is the size of int type. And &arr is the address of the entire array, and &arr+1 means spanning the entire array, with a step size of 40, which is the size of the entire array.

#include <stdio.h>
int main() {
	int arr[10] = { 0 };
	printf("%d\n",sizeof(arr));
	return 0;
}

 The return value of sizeof(arr) is 40 bytes, which proves that arr is the address of the entire array at this time. The address representing the integer group consists of these two special cases, and the rest of the cases represent the address of the receiving element. Do you think that's it? It's not over yet.

#include <stdio.h>
int main() {
	int arr[10][10] = {0};
	printf("%d\n",sizeof(arr));
	printf("%d\n",sizeof(arr[0]));
	printf("%d\n",sizeof(arr[0][0]));
	return 0;
}

 understand? arr is a two-dimensional array, arr represents the size of the entire array, so it is 400 bytes, arr[0] represents the size of the first row, so it is 40, arr[0][0] is the size of the first element, so it is 4; Let's keep watching.

#include <stdio.h>
int main() {
	int arr[10][10] = {0};
	printf("&arr:        %u\n", &arr);
	printf("&arr+1:      %u\n", &arr+1);
	printf("arr:         %u\n", arr);
	printf("arr+1:       %u\n", arr+1);
	printf("arr[0]:      %u\n", arr[0]);
	printf("arr[0]+1:    %u\n", arr[0]+1);
	printf("&arr[0]:     %u\n", &arr[0]);
	printf("&arr[0]+1:   %u\n", &arr[0]+1);
	printf("&arr[0][0]:  %u\n", &arr[0][0]);
	printf("&arr[0][0]+1:%u\n", &arr[0][0] + 1);

	return 0;
}

 

 &arr represents the address of the entire array, so &arr+1 has a step size of 400, and arr represents the address of the first element. Note that the array is a two-dimensional array, and the first element is 10 int-type numbers in the first line, so the step size is 40. arr[0] represents the first element in the first element of arr, which is a[0][0], so the step size is 4. &arr[0] represents the entire arr[0], so the step size is 40, &a[0][0] represents the address of the first row and first column, and the step size is 4. You can see that &arr, arr, arr[0], &a[0], &a[0][0] print the same address, but their meanings are completely different. You thought that was it? Come on.

#include <stdio.h>
int main() {
	int arr[3][4] = { 
		 {1,22,333,444},
		 {5,66,777,8888},
		 {99,130,113,123}
	};
	printf("&arr:\t%u\n", &arr);
	printf("&arr+1:\t%u\n", &arr+1);
	printf("*arr:\t%u\n", *arr);
	printf("*arr+1:\t%u\n", *arr+1);
	printf("**arr:\t%u\n", **arr);
	printf("**arr+1:\t%u\n", **arr+1);
	printf("*arr[2]:\t%u\n", *arr[2]);
	printf("*arr[2]:\t%u\n", *arr[2]+1);
	return 0;
}

 

 *arr represents the entire arr[0], why? *arr=*(arr+0)=a[0] , understand, so the step is the element size of a line, that is, 12 bytes, **arr represents a[0][0], because *arr=a [0] is already known. so             

**arr=*arr[0]=*(arr[0]+0)=a[0][0], the value of a[0][0] is 1, so it is printed as 1, followed by 1 to represent the value Adding 1 is not address addition or subtraction. The same goes for *arr[2]. You thought it was done? Don't worry, there are more.

#include <stdio.h>
int main()
{
	int i, j;
	int arr[3][4] = { 1,22,3333,4,55,666,7,88,999,101,1167,12242 };
	
	printf("*(arr+4*i+j)\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%d   ",**(arr + 4 * i + j));
		}

	}
	printf("\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%d   ",**arr + 4 * i + j);
		}
	}
	return 0;
}

 **(arr + 4 * i + j), arr represents the first element, and the step size is 12 bytes of a row of elements, so the first three are the first elements of each row, and the subsequent address is out of bounds and is a random value. **arr + 4 * i + j, **arr is also arr[0][0], so add 1 each time. Let's continue watching.

 

#include <stdio.h>
int main()
{
	int i, j;
	int arr[3][4] = { 1,22,3333,4,55,666,7,88,999,101,1167,12242 };
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("arr[%d][%d]=%d\t", i, j, *(&arr[0][0] + 4 * i + j));
		}
		printf("\n");
	}
	printf("\n");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("arr[%d][%d]=%d\t", i, j, *(*(i + arr) + j));//i[a][j]
		}
		printf("\n");
	}
	return 0;
}

  *(&arr[0][0] + 4 * i + j), take the element address step size of the first row and first column as 1, then add 1 to dereference, and print all the values ​​of the array. *(*(i + arr) + j) is actually a[i][j], how did you ask? a[i][i]=*(a[i]+j)=*(*(arr+i)+j) , very simple, right? Only here can I dare to say that I am familiar with the application of array names, pay attention to familiarity. 

Guess you like

Origin blog.csdn.net/m0_73731708/article/details/130920173
Recommended