Theory is when you know everything but nothing works. Practice is when everything works but no one knows why. In my lab, theory and practice are combined: nothing works and nobody knows why. (网络段子)
pkg in vim vim /data/data/com.termux/files/usr/etc/apt/sources.list # 添加以下镜像源 deb https://mirrors.ustc.edu.cn/termux/apt/termux-main stable main # 执行 pkg update
+
+
安装必要依赖和软件
pkg in x11-repo pkg in xwayland dpkg -i ./termux-x11.deb
+
+
安装 termux-x11.apk
+
重启termux
+
pkg in proot-distro proot-distro install archlinux
# 安装完成后: proot-distro login archlinux vi /etc/pacman.d/mirrorlist # 添加 Server = https://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo
proot-distro login --user dionysen archlinux --shared-tmp ok | took 8s | at 01:03:12 [3] 11100 /usr/bin/startxfce4: X server already running on display :0 Environment variable $XAUTHORITY not set, ignoring. Failed to import environment: Process org.freedesktop.systemd1 exited with status 1
adb -s <IP address>:<Port> shell settings put global policy_control immersive.status=com.termux.x11,com.termux
+
+
Termux Backup and Restore
termux-setup-storage cd /data/data/com.termux/files tar -zcf /sdcard/termux-backup.tar.gz home usr # Backup termux-setup-storage cd /data/data/com.termux/files tar -zxf /sdcard/termux-backup.tar.gz --recursive-unlink --preserve-permissions # Restore
Our daily life has become inseparable from computers. Whether you are using computers or not, you are using computers consciously or unconsciously, or using the services that computers provide for you. When we are in the use of computer, we are all in the use of computer has some software, so we will go to find the APP, if you searched all the APPs on the market, is there no have the functionality of the APP you want, then you have to write their own one, if you want to do something special, you can’t find the right software, will still have to write their own one. Learning programming is not about writing software for yourself. It is about learning programming to understand how computers work, what they can or are good at doing, what they can’t or aren’t good at doing, and how computers solve problems.
+
+
—— Weng Kai
+
+
Get started
Framework
#include"stdio.h" intmain() {
return0; }
+
+
Any programs programed by C language must have this framework.
+
Output function
You can understand it as function in math, which is a mapping relationship. But they are different.
+
printf is a function, whoes function is output a string by formating printf("......\n") .
+
For example, the Hello, world! :
+
#include"stdio.h" intmain() { printf("Hello,world!\n"); // \n make it wrapping return0; }
+
+
printf can print not only a string, but also the value of the variable, but you need to format the variable.
+
Variables and constants
+
The computer carries on the computation, then participates in the computation is the number, participates in the computation in the C language the number is called the quantity, the quantity divides into the variable and the constant. Use decimal for expression of daily life, because is advantageous for the calculation of the human brain, a computer internal use binary, for convenience of computer calculation, and the computer expression, as a result of bytes in computer internal frequency is higher, if you can use a simple way to express its inner meaning accurately, Will bring us a lot of convenience, so often use hexadecimal expression. But the number itself remains the same no matter which way it is counted.
+
+
Constants
As the name implies, an invariant quantity that, once initialized, cannot be changed.
+
Variables
As the name implies, a variable quantity that, once defined, can be assigned any value to change its size.
+
The way of difination:
+
int i; int j = 1; char k; float h = 1.2; double g = 2.0;
+
+
For example, i is the variable itself, int is an integer variable, whose value can only be an integer, while double is a double-precision floating point number, which can represent a decimal.
+
Different variable types have different value types and value ranges.
+
Character variables:
+
Use to store character constants. A character variable can hold onlyone character constant. The type specifier is char.
+
#include<stdio.h> intmain() { char x,y,z; x = 'b'; y = 'o'; z = 'y'; printf("%c%c%c\n",x,y,z); return0; }
+
+
The result is:
+
boy
+
+
The literal value of a character variable is independent of the character constant it holds, analogous to an integer variable.
+
Character variables can also store integer data, which is universal. You can change %c to %d during input and output.
+
Output and input of a variable
Output
As mentioned above, printf can print a string, and can print the value of a variable, as shown in the following example:
+
#include"stdio.h" intmain() { int i = 1; printf("i = %d\n",i); i = 2; printf("After assignment,i = %d\n",i); return0; }
+
+
Notice that printf prints the value of the variable with a %d inside the double quotes, which is the way the variable is formatted.
+
%d indicates that the output variable is an integer.
+
+
+
+
Variable Types
+
Formatting Symbols
+
+
+
+
int
+
%d
+
+
+
unsigned
+
%u
+
+
+
long long
+
%ld
+
+
+
unsigned long long
+
%lu
+
+
+
float
+
%f
+
+
+
double
+
%lf
+
+
+
You can use scientific notation when you output, and use %e for formatting symbol.
+
printf("%.nf",sum);
+
+
This line of code can preserve n decimal places.
+
The following are escape characters:
+
+
+
+
Symbols
+
Words
+
中文含义
+
+
+
+
\b
+
backspace
+
回退一格
+
+
+
\t
+
tab
+
下一个制表位
+
+
+
\n
+
new line
+
换行
+
+
+
\r
+
return
+
回车
+
+
+
\f
+
f
+
换页
+
+
+
Input
Similarly, the function scanf can read the input according to a certain format.
+
#include<stdio.h> intmain( ) {
char str[100]; int i;
printf( "Enter a value :"); scanf("%s %d", str, &i);
scanf() stops reading a string as soon as it encounters a space, so “this is test” is three strings for scanf().
+
Floating point numbers
In mathematics, the numbers on the number line are continuous, and between any two different points, an infinite number can be found, but this is difficult to achieve in computers, so floating point numbers emerged.
+
Floating point numbers are used to represent fractional numbers between whole numbers, but their accuracy is not infinite, nor is their expressability infinite, so a random decimal may not be able to be expressed by a computer.
+
Operation
Operator
+
+
+
Mathematics
+
Add
+
Substract
+
Multiply
+
Divide
+
Remainder
+
+
+
+
C Language
+
+
+
-
+
*
+
/
+
%
+
+
+
Relational operator
+
+
+
Relation
+
Equal
+
Not Equal
+
Greater
+
Greater or Equal
+
Less-than
+
Less-than or Equal
+
+
+
+
Operator
+
==
+
!=
+
>
+
>=
+
<
+
<=
+
+
+
The relational operator evaluates only zeros and ones.
+
Special operator
count ++ and ++ count both mean to add one, but a = count ++; means to assign the value of count to a and then add one, whereas a = ++count; means to add one to the value of count and then assign the result to a. So you end up adding one to count in both cases, but the value of a differ by 1.
+
count -- and -- count in the same way.
+
, is comma operator that generally has only one purpose: to add multiple conditions to an if statement.
We can add else, so we can do something if the condition doesn’t work.
+
The else always matches the nearest if.
+
while
while (<#condition#>) { <#statements#> }
+
+
The loop continues until the condition fails.
+
dowhile
do { <#statements#> } while (<#condition#>);
+
+
The loop continues until the condition fails.
+
The difference with a while loop is that a dowhile does something and then evaluates the condition, whereas a while evaluates the condition and then loops. While might not do a loop at all, if the condition is not satisfied in the first place.
+
switch
switch (<#expression#>) { case <#constant#>: <#statements#> break; case <#constant#>: <#statements#> break; ...... default: break; }
+
+
switch is judgment statement, the <#expression#> is constant expression that must be a integral type or enum-type.
+
The essence of such a statement is the program evaluates this expression and then compares it to each case at a time. The action after the case is executed when equal.
+
There are an infinite number of cases, each followed by a value to be compared with and a colon.
+
The variables to be compared must be of the same type.
+
When all the case is false, the program will do the action after default . So there can be nothing after defalut.
for (<#initialization#>; <#condition#>; <#increment#>) { <#statements#> }
+
+
for loop applies to loops with a defined number of cycles, such as traverse.
+
There are three sections in parenthesis, separated with semicolons, which are respectively initialization, conditions for loop to proceed and actions to be performed in each cycle.
+
Miscellaneous
+
+
+
Key words
+
Implication
+
+
+
+
Inf
+
Infinity
+
+
+
-Inf
+
Negative infinity
+
+
+
nan
+
Invalid number
+
+
+
fabs(<#expression#>)
+
Absolute value
+
+
+
break
+
Jump out of the loop
+
+
+
continue
+
End the cycle
+
+
+
Function and customizing function
At the beginning of C language program, the implication of #include <stdio.h> is including a function library named stdio.h and then the program can call functions in the library. Both the printf and the scanf used in the previous paragraph are functions of the library.
+
In practice, we often encounter repeated operations, we can copy this code to complete the repeated action, but code copy is a poor quality of the program, because the maintenance may need to change too many places.
+
You can solve this problem by customizing functions:
+
<#type#> (<#type#>,<#type#>,……){ <#statement#> return0; //Depends on the function type,Also visable as:return; }
+
+
+
A function can have multiple return or none. However, multiple return are not recommended for easy modification.
+
+
Each function has its own variable space, namely {} (block), which is independent of each other. Local variables are limited by the block they are in. If the inside of a block has the same name as the outside of a block, the inside of a block takes precedence.
+
+
When a function is called, it can only pass values to functions, not variables to functions. That is, after passing a variable to a function, the function will read the value of the variable for operation, but will not change the value of the variable.
+
+
The first line of a function with a semicolon placed before the entire program code is called a function prototype declaration. The purpose is to tell the compiler what type the function is before it encounters it.
+
+
+
Array
Defination
+
type of variables + character + [number of variables]
+
+
For example:
+
int a[10];
+
+
An array is a container that, once created, cannot be resized, is internally ordered, and can appear on both sides of an assignment symbol.
+
The index of an array is counted from 0.
+
You can think of it as a sequence in mathematics.
+
Use
Integration initialization is easy to use:
+
int a[3] = {1,3,5,}; int a[13] = {[0]=2,[3]=5,6,7,[9]=0,}; //(C99 only)
+
+
If you don’t know how many cells there are in an array, you can use sizeof(a)/sizeof(a[0]) to represent the number of cells in the array, so that you don’t need to change the number of cells in the array.
+
Multidimensional array
A multidimensional array is actually a multidimensional matrix, and the footer increases accordingly.
+
Initialization:
+
int a[][5] = { {0,1,2,3,4}, {2,3,4,5,6}, }
+
+
The number of columns must be given and the number of rows can be counted by the compiler itself.
+
Pointer
Address
Each variable has an address in the computer where it is stored. The value of a variable can change, but its address is constant. The following code can be used to view the address of a variable.
+
int i = 1; printf("%d\n",&i);
+
+
& is the address to access the variable;
+
* is the variable on the access address.
+
Defination
A pointer is a variable, but it cannot be used independently. It must point to a variable. In this case, the value of the pointer variable is the address of the variable to which it points.
+
Use
int *p = &i;
+
+
In this case, p is a pointer to the address of variable i. So the value of p is the address of i, and the value of i can be accessed (read and write) by *p.
+
The * at definition is not the same as the * at access, and the first is only used to distinguish whether a pointer variable or a normal variable is being defined.
+
Here is an example of using a pointer to complete a call to exchange the values of two variables.
+
#include<stdio.h> voidexchange(int *a,int *b) { int i = *a; *a = *b; *b = i; } intmain() { int a = 5; int b = 6; exc(&a, &b); printf("a = %d,b = %d\n",a,b);
return0; }
+
+
This is a clever use of the function, we know that the function cannot input variable parameters, so this code defines the address of the pointer to the variable, the function input pointer variable is also the address of the variable, inside the function by adding a pointer to access the variable, and then achieve the purpose of the function to modify the variable.
+
+
In addition, pointers are often used when a function needs to return multiple values.
+
+
Arrays are special Pointers
#include<stdio.h> intmain() { int a[] = {1,2,3,}; printf("%p\n",a); return0; }
+
+
The result of this code is:
+
0x7ffcac420c3c
+
+
We can see that the array variable a is itself an address, so when we want to use a pointer to array a, we should write int *p = a, without &. But the array unit is variable, therefore int *p = &a[0], at the same time, a == &a[0],&a[x] == &a[0] + 4x = a + 4x(when a is integer).
+
An array is a pointer to a constant and therefore cannot be assigned.
+
Pointer to a constant (const)
int i; intconst *p = &i; // 1 int *const p = &i; // 2
+
+
For the above code, you can think of the following code:
+
int i; intconst(*p) = &i; // 1 int *(const p) = &i; // 2
+
+
1 indicates that the variable at the address pointed to by the pointer p cannot be modified by the pointer.
+
2 indicates that the address (variable’s address certainly) pointed to by p cannot be changed.
+
+
The first whole to the right of const cannot be modified
+
+
constint a[] = {1,2,3,};
+
+
The above code indicates that each cell is const, so it can be used to protect an array when a function argument is entered.
+
Address of a pointer
int a[]; int *p = a;
+
+
*p = a = a[0],
+
*(p+1) = a[1],
+
*(p+2) = a[2],
+
……,
+
*(p+n) = a[n].
+
Allocating Memory Space
The malloc function applies space in bytes from memory, returns void *, converts the desired type, and finally frees the memory. Format, such as:
+
int a[n] = (int *)malloc(n * sizeof(int));
+
+
If the application fails, 0 or NULL is returned.
+
When you no longer use the requested memory space, you should use the free function to free the memory space:
+
free(a[n]);
+
+
String
Overview
Char word[] = {'H','D','e','!'};
+
+
Such an array is an array of characters, but it is not a string, because it cannot be evaluated as a string.
+
Char word[] = {'H','D','e','!','\0'};
+
+
Followed by \0, then word is a string.
+
0 = '\0' != '0'
+
0 marks the end of the string, but this 0 is not part of the string.
+
Strings exist as Arrays and are accessed as arrays or Pointers, but more often as Pointers.
+
string.h has a number of functions that handle strings.
The compiler will turn this into an array of characters somewhere, and the length of the array is 6, because the compiler will put a 0 after it to make it a string.
+
Literals of strings can be used to initialize character arrays.
&i = 0x7fffa827bcf4 s = 0x55c7d8f64004 s2 = 0x55c7d8f64004 Here is s[0] = h Here is s3[0] = h
+
+
You can see that the local variable i is far from where the pointer s is pointing. The address of the variable i is very far back, and the pointer is very far forward. Near the front are important parts of the computer that are not allowed to be modified, such as plus s[0] = 'B' ‘, and the result is:
+
1869 segmentation fault ./a.out
+
+
The program attempted to reassign the initialized string s. The error “segmentation fault“ was reported, meaning that the program was attempting to rewrite the value at 0x55c7d8f64004, which posed a threat to the computer and was not allowed.
+
In fact, for char *s = "hello world"; pointer s is initialized to point to a string constant, which should actually be const char *s = "hello world";, but for historical reasons, compilers accept writing without const, and try to modify the string to which s refers, with serious consequences.
+
s3 is an array, and the strings inside are local variables that can be modified, plus S3[0] = 'b':
+
&i = 0x7fff28d5dd64 s = 0x559da8ac6004 s2 = 0x559da8ac6004 Here is s[0] = h Here is s3[0] = b
+
+
There are two ways to define a string: pointer or array.
+
Arrays know the address of strings, Pointers don’t.
+
A char * or int * is not necessarily a string. It is meant to be a pointer to a character or an array of characters.
+
A char * or int * is a string only if the array of characters to which the pointer points has a zero at the end.
+
char *t = "title"; char *s; s = t;
+
+
For the above code, we have two Pointers, t and s. First, t points to the string “title”, and then we assign a value to s. The result is that s also points to the same string, instead of creating a new string.
+
Input and output of string
For printf and scanf, you can use %s to input and output strings.
+
Each %s in scanf is read until a SPACE or ENTER, which is not safe because you do not know exactly how many characters to read, therefore, the following code is used:
+
char s[8]; scanf("%7s",s);
+
+
Array of strings
char a[][10]; char *a[];
+
+
The first line refers to a as a two-dimensional array, and the second line refers to a as a pointer array. Each unit in the array is a pointer to a string.
+
Each element of the character array holds one character, plus the 0 at the end. An array of length n can hold n-1 characters.
+
Multiple loops are required to input and output all elements of multiple dimensions, whether string arrays or integer arrays.
+
An array is a matrix that can be used to store variables or character variables. All input and output need to be looped, but there are two types of input and output for character arrays.
+
Input and output single characters in format %c
#include<stdio.h> intmain() {
int x,i,j; char a[][20] = { "", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", }; printf("Please input the month:\n"); scanf("%d",&x); if (x > 0 && x < 8) { for (i = x ; i < x + 1; i ++) { for (j = 0; j < 20; j ++) { printf("%c",a[i][j]); } } } elseprintf("Error"); printf("\n"); return0; }
+
+
Input and output whole array with format %s
#include<stdio.h> intmain() { int x,i,j; char a[][20] = { "", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", }; printf("Please input the month:\n"); scanf("%d",&x); if (x > 0 && x < 8) { printf("%s",a[x]); } elseprintf("Error"); printf("\n"); return0; }
+
+
+
Note that input characters with %s that encounter a SPACE, RNTER, and TAB end the string input, so C provides the input function gets() and the output function puts() that are best for strings.
+
+
gets(char *s[]) function is to enter a string from the keyboard that can contain Spaces and end with a ENTER newline character.
+
puts(char *s[]) or puts(string s)function prints a string from the character array to the screen and converts the end-of-string flag to a newline character.
+
In addition, when %s prints a string, it keeps one dimension, and the compiler automatically inputs or outputs all strings in that dimension. Gets is the same as puts.
+
Input and output of character data
Putchar(parameter)
Paremeters can be numerical values, character constants, character variables, and arithmetic or character expressions, but the final output is a character.
So strlen is string Length, which returns the length of the string.
+
strcmp
The function is to compare the size of two strings, and the result of the comparison is expressed by the value returned. 0 means they are equal, 1 means the former greater, and -1 means the latter greater.
Its function is to copy the src string to dst. restrict means that src and dst cannot overlap. The source is in the back, and the copying destination is in the front. Return dst so that the function itself can be evaluated. General usage:
enumtype {num_0,num_1,num_2,……,num_n, number of type};
+
+
That’s just right. The last number of type is exactly the number of type. It’s a little trick.
+
Data structure
#include<stdio.h> structdate { int day; int month; int year; }; //Structure type Declaration structdate { int day; int month; int year; } today; //This is another form
printf("Today is %i-%i-%i.\n", today.year,today.month,today.day);
return0; }
+
+
This means that you declare a data structure type, and when you use it, you define a variable that contains all the variables in the data structure.
+
The structure members of a data structure do not have to be of the same variable type, and an array can only be of one type.
+
Data structures can perform structure operations .
+
Assigning values to or between structure variables is a one-to-one correspondence; the former requires curly braces.
+
The name of the structure variable is not the address of the structure variable, so you need to define the pointer using &.
+
A data structure can be entered as a function parameter, but unlike an array, the entire structure is passed into the function as the value of the parameter, creating a new structure variable inside the function and copying the value of the caller’s structure.
+
You can also return a struct.
+
Custom data types
A typedef can give an alias to a data type.
+
typedeflongint64_t; typedefstructADate { int month; int day; int year; } Date;
int64_t i = 100000000000; Date d = {9, 1, 2005, };
//递增 intmain(){ //后置递增 int a = 10; a++; //等价于a = a + 1 cout << a << endl; // 11 //前置递增 int b = 10; ++b; cout << b << endl; // 11 //区别 //前置递增先对变量进行++,再计算表达式 int a2 = 10; int b2 = ++a2 * 10; cout << b2 << endl; //后置递增先计算表达式,后对变量进行++ int a3 = 10; int b3 = a3++ * 10; cout << b3 << endl; return0; }
+
+
+
总结:前置递增先对变量进行++,再计算表达式,后置递增相反
+
+
3.2 赋值运算符
作用: 用于将表达式的值赋给变量 赋值运算符包括以下几个符号:
+
+
+
+
运算符
+
术语
+
示例
+
结果
+
+
+
+
=
+
赋值
+
a=2; b=3;
+
a=2; b=3;
+
+
+
+=
+
加等于
+
a=0; a+=2;
+
a=2;
+
+
+
-=
+
减等于
+
a=5; a-=3;
+
a=2;
+
+
+
*=
+
乘等于
+
a=2; a*=2;
+
a=4;
+
+
+
/=
+
除等于
+
a=4; a/=2;
+
a=2;
+
+
+
%=
+
模等于
+
a=3; a%2;
+
a=1;
+
+
+
示例:
+
+
+
+
+
+
intmain(){ //赋值运算符 // = int a = 10; a = 100; cout << "a = " << a << endl; // += a = 10; a += 2; // a = a + 2; cout << "a = " << a << endl; // -= a = 10; a -= 2; // a = a - 2 cout << "a = " << a << endl; // *= a = 10; a *= 2; // a = a * 2 cout << "a = " << a << endl; // /= a = 10; a /= 2; // a = a / 2; cout << "a = " << a << endl; // %= a = 10; a %= 2; // a = a % 2; cout << "a = " << a << endl; return0; }
+
+
3.3 比较运算符
作用:用于表达式的比较,并返回一个真值或假值 比较运算符有以下符号:
+
+
+
+
运算符
+
术语
+
示例
+
结果
+
+
+
+
***
+
相等于
+
4 *** 3
+
0
+
+
+
!=
+
不等于
+
4 != 3
+
1
+
+
+
<
+
小于
+
4 < 3
+
0
+
+
+
>
+
大于
+
4 > 3
+
1
+
+
+
<=
+
小于等于
+
4 <= 3
+
0
+
+
+
>=
+
大于等于
+
4 >= 1
+
1
+
+
+
示例:
+
+
+
+
+
+
intmain(){ int a = 10; int b = 20; cout << (a *** b) << endl; // 0 cout << (a != b) << endl; // 1 cout << (a > b) << endl; // 0 cout << (a < b) << endl; // 1 cout << (a >= b) << endl; // 0 cout << (a <= b) << endl; // 1 return0; }
//逻辑运算符 --- 与 intmain(){ int a = 10; int b = 10; cout << (a && b) << endl;// 1 a = 10; b = 0; cout << (a && b) << endl;// 0 a = 0; b = 0; cout << (a && b) << endl;// 0 return0; }
+
+
+
与: 同时真则为真,否则皆为假 示例3:逻辑或
+
+
//逻辑运算符 --- 或 intmain(){ int a = 10; int b = 10; cout << (a || b) << endl;// 1 a = 10; b = 0; cout << (a || b) << endl;// 1 a = 0; b = 0; cout << (a || b) << endl;// 0 return0; }
intmain(){ int a = 10; int b = 20; int c = 0; c = a > b ? a : b; cout << "c = " << c << endl; //cpp中三目运算符返回的是变量,可以继续赋值 (a > b ? a : b) = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; return0; }
+
+
+
总结:和if语句比较,三目运算符优点是短小整洁,缺点是如果用嵌套,结构不清晰
+
+
4.1.3 switch语句
作用: 执行多条件分支语句 语法:
+
switch(表达式) { case 结果1:执行语句;break; case 结果2:执行语句;break; ... default:执行语句;break; }
//函数定义 intadd(int num1, int num2) { int sum = num1 + num2; return sum; }
+
+
6.3 函数的调用
功能: 使用定义好的函数 语法:函数名(参数) 示例:
+
//函数定义 intadd(int num1, int num2)//定义中的num1,num2称为形式参数,简称形参 { int sum = num1 + num2; return sum; } intmain(){ int a = 10; int b = 10; //调用add函数 int sum = add(a, b);//调用时的a,b称为实际参数,简称实参 cout << "sum = " << sum << endl; a = 100; b = 100; sum = add(a, b); cout << "sum = " << sum << endl; return0; }
+
+
+
总结:函数定义里小括号内称为形参,函数调用时传入的参数称为实参
+
+
6.4 值传递
+
所谓值传递,就是函数调用时实参将数值传入给形参
+
+
值传递时,如果形参发生,并不会影响实参 示例:
+
+
+
voidswap(int num1, int num2) { cout << "交换前:" << endl; cout << "num1 = " << num1 << endl; cout << "num2 = " << num2 << endl; int temp = num1; num1 = num2; num2 = temp; cout << "交换后:" << endl; cout << "num1 = " << num1 << endl; cout << "num2 = " << num2 << endl; //return ; 当函数声明时候,不需要返回值,可以不写return } intmain(){ int a = 10; int b = 20; swap(a, b); cout << "mian中的 a = " << a << endl; cout << "mian中的 b = " << b << endl; return0; }
+
+
+
总结: 值传递时,形参是修饰不了实参的
+
+
6.5 函数的常见样式
常见的函数样式有4种
+
+
无参无返
+
有参无返
+
无参有返
+
有参有返 示例:
+
+
//函数常见样式 //1、 无参无返 voidtest01() { //void a = 10; //无类型不可以创建变量,原因无法分配内存 cout << "this is test01" << endl; //test01(); 函数调用 } //2、 有参无返 voidtest02(int a) { cout << "this is test02" << endl; cout << "a = " << a << endl; } //3、无参有返 inttest03() { cout << "this is test03 " << endl; return10; } //4、有参有返 inttest04(int a, int b) { cout << "this is test04 " << endl; int sum = a + b; return sum; }
+
+
6.6 函数的声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
+
+
函数的声明可以多次,但是函数的定义只能有一次 示例:
+
+
//声明可以多次,定义只能一次 //声明 intmax(int a, int b); intmax(int a, int b); //定义 intmax(int a, int b) { return a > b ? a : b; } intmain(){ int a = 100; int b = 200; cout << max(a, b) << endl; system("pause"); return0; }
+
+
6.7 函数的分文件编写
作用: 让代码结构更加清晰 函数分文件编写一般有4个步骤
+
+
创建后缀名为.h的头文件
+
创建后缀名为.cpp的源文件
+
在头文件中写函数的声明
+
在源文件中写函数的定义 示例:
+
+
//swap.h文件 #include<iostream> usingnamespace std; //实现两个数字交换的函数声明 voidswap(int a, int b);
+
+
//swap.cpp文件 #include"swap.h" voidswap(int a, int b) { int temp = a; a = b; b = temp; cout << "a = " << a << endl; cout << "b = " << b << endl; }
+
+
//main函数文件 #include"swap.h" intmain(){ int a = 100; int b = 200; swap(a, b); return0; }
+
+
七、指针
7.1 指针的基本概念
指针的作用: 可以通过指针间接访问内存
+
+
内存编号是从0开始记录的,一般用十六进制数字表示
+
可以利用指针变量保存地址
+
+
7.2 指针变量的定义和使用
指针变量定义语法: 数据类型 * 变量名; 示例:
+
intmain(){ //1、指针的定义 int a = 10; //定义整型变量a //指针定义语法: 数据类型 * 变量名 ; int * p; //指针变量赋值 p = &a; //指针指向变量a的地址 cout << &a << endl; //打印数据a的地址 cout << p << endl; //打印指针变量p //2、指针的使用 //通过*操作指针变量指向的内存 cout << "*p = " << *p << endl; return0; }
//堆区开辟数组 intmain(){ int* arr = newint[10]; for (int i = 0; i < 10; i++) { arr[i] = i + 100; } for (int i = 0; i < 10; i++) { cout << arr[i] << endl; } //释放数组 delete 后加 [] delete[] arr; return0; }
+
+
二、引用
2.1 引用的基本使用
作用: 给变量起别名 语法:数据类型 &别名 = 原名 示例:
+
intmain(){ int a = 10; int &b = a; cout << "a = " << a << endl; cout << "b = " << b << endl; b = 100; cout << "a = " << a << endl; cout << "b = " << b << endl; return0; }
+
+
2.2 引用注意事项
+
引用必须初始化
+
+
引用在初始化后,不可以改变 示例:
+
+
+
intmain(){ int a = 10; int b = 20; //int &c; //错误,引用必须初始化 int &c = a; //一旦初始化后,就不可以更改 c = b; //这是赋值操作,不是更改引用 cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; return0; }
+
+
2.3 引用做函数参数
作用: 函数传参时,可以利用引用的技术让形参修饰实参 优点: 可以简化指针修改实参 示例:
+
//1. 值传递 voidmySwap01(int a, int b){ int temp = a; a = b; b = temp; } //2. 地址传递 voidmySwap02(int* a, int* b){ int temp = *a; *a = *b; *b = temp; } //3. 引用传递 voidmySwap03(int& a, int& b){ int temp = a; a = b; b = temp; } intmain(){ int a = 10; int b = 20; mySwap01(a, b); cout << "a:" << a << " b:" << b << endl; mySwap02(&a, &b); cout << "a:" << a << " b:" << b << endl; mySwap03(a, b); cout << "a:" << a << " b:" << b << endl; return0; }
intfunc(int a, int b = 10, int c = 10){ return a + b + c; } //1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值 //2. 如果函数声明有默认值,函数实现的时候就不能有默认参数 intfunc2(int a = 10, int b = 10); intfunc2(int a, int b){ return a + b; } intmain(){ cout << "ret = " << func(20, 20) << endl; cout << "ret = " << func(100) << endl; return0; }
//交换整型函数 voidswapInt(int& a, int& b){ int temp = a; a = b; b = temp; } //交换浮点型函数 voidswapDouble(double& a, double& b){ double temp = a; a = b; b = temp; } //利用模板提供通用的交换函数 template<typename T> voidmySwap(T& a, T& b) { T temp = a; a = b; b = temp; } voidtest01() { int a = 10; int b = 20; //swapInt(a, b); //利用模板实现交换 //1、自动类型推导 mySwap(a, b); //2、显示指定类型 mySwap<int>(a, b); cout << "a = " << a << endl; cout << "b = " << b << endl; } intmain(){ test01(); return0; }
+
+
+
函数模板利用关键字 template
+
+
使用函数模板有两种方式:自动类型推导、显示指定类型
+
+
模板的目的是为了提高复用性,将类型参数化
+
+
+
1.2.2 函数模板注意事项
注意事项:
+
+
自动类型推导,必须推导出一致的数据类型T,才可以使用
+
模板必须要确定出T的数据类型,才可以使用 示例:
+
+
//利用模板提供通用的交换函数 template<class T> voidmySwap(T& a, T& b) { T temp = a; a = b; b = temp; } // 1、自动类型推导,必须推导出一致的数据类型T,才可以使用 voidtest01() { int a = 10; int b = 20; char c = 'c'; mySwap(a, b); // 正确,可以推导出一致的T //mySwap(a, c); // 错误,推导不出一致的T类型 } // 2、模板必须要确定出T的数据类型,才可以使用 template<class T> voidfunc() { cout << "func 调用" << endl; } voidtest02() { //func(); //错误,模板不能独立使用,必须确定出T的类型 func<int>(); //利用显示指定类型的方式,给T一个类型,才可以使用该模板 } intmain(){ test01(); test02(); return0; }
+
+
+
使用模板时必须确定出通用数据类型T,并且能够推导出一致的类型
+
+
1.2.3 函数模板案例
案例描述:
+
+
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序
+
排序规则从大到小,排序算法为选择排序
+
分别利用char数组和int数组进行测试 示例:
+
+
//交换的函数模板 template<typename T> voidmySwap(T &a, T&b) { T temp = a; a = b; b = temp; } template<classT> // 也可以替换成typename //利用选择排序,进行对数组从大到小的排序 voidmySort(T arr[], int len) { for (int i = 0; i < len; i++) { int max = i; //最大数的下标 for (int j = i + 1; j < len; j++) { if (arr[max] < arr[j]) { max = j; } } if (max != i) //如果最大数的下标不是i,交换两者 { mySwap(arr[max], arr[i]); } } } template<typename T> voidprintArray(T arr[], int len){ for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout << endl; } voidtest01() { //测试char数组 char charArr[] = "bdcfeagh"; int num = sizeof(charArr) / sizeof(char); mySort(charArr, num); printArray(charArr, num); } voidtest02() { //测试int数组 int intArr[] = { 7, 5, 8, 1, 3, 9, 2, 4, 6 }; int num = sizeof(intArr) / sizeof(int); mySort(intArr, num); printArray(intArr, num); } intmain(){ test01(); test02(); return0; }
+
+
模板可以提高代码复用,需要熟练掌握
+
1.2.4 普通函数与函数模板的区别
普通函数与函数模板区别:
+
+
普通函数调用时可以发生自动类型转换(隐式类型转换)
+
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
+
如果利用显示指定类型的方式,可以发生隐式类型转换 示例:
+
+
//普通函数 intmyAdd01(int a, int b) { return a + b; } //函数模板 template<class T> T myAdd02(T a, T b) { return a + b; } //使用函数模板时,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换 voidtest01() { int a = 10; int b = 20; char c = 'c'; cout << myAdd01(a, c) << endl; //正确,将char类型的'c'隐式转换为int类型 'c' 对应 ASCII码 99 //myAdd02(a, c); // 报错,使用自动类型推导时,不会发生隐式类型转换 myAdd02<int>(a, c); //正确,如果用显示指定类型,可以发生隐式类型转换 } intmain(){ test01(); system("pause"); return0; }
+
+
建议使用显示指定类型的方式,调用函数模板,因为可以自己确定通用类型T
+
1.2.5 普通函数与函数模板的调用规则
调用规则如下:
+
+
如果函数模板和普通函数都可以实现,优先调用普通函数
+
可以通过空模板参数列表来强制调用函数模板
+
函数模板也可以发生重载
+
如果函数模板可以产生更好的匹配,优先调用函数模板 示例:
+
+
//普通函数与函数模板调用规则 voidmyPrint(int a, int b) { cout << "调用的普通函数" << endl; } template<typename T> voidmyPrint(T a, T b) { cout << "调用的模板" << endl; } template<typename T> voidmyPrint(T a, T b, T c) { cout << "调用重载的模板" << endl; } voidtest01() { //1、如果函数模板和普通函数都可以实现,优先调用普通函数 // 注意 如果告诉编译器 普通函数是有的,但只是声明没有实现,或者不在当前文件内实现,就会报错找不到 int a = 10; int b = 20; myPrint(a, b); //调用普通函数 //2、可以通过空模板参数列表来强制调用函数模板 myPrint<>(a, b); //调用函数模板 //3、函数模板也可以发生重载 int c = 30; myPrint(a, b, c); //调用重载的函数模板 //4、 如果函数模板可以产生更好的匹配,优先调用函数模板 char c1 = 'a'; char c2 = 'b'; myPrint(c1, c2); //调用函数模板 } intmain(){ test01(); return0; }
+
+
既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性
+
1.2.6 模板的局限性
局限性:
+
+
模板的通用性并不是万能的 例如:
+
+
template<class T> voidf(T a, T b) { a = b; }
+
+
在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了 再例如:
+
template<class T> voidf(T a, T b) { if(a > b) { ... } }
intfind(const string& str, int pos = 0)const;//查找str第一次出现位置,从pos开始查找 intfind(constchar* s, int pos = 0)const;//查找s第一次出现位置,从pos开始查找 intfind(constchar* s, int pos, int n)const;//从pos位置查找s的前n个字符第一次位置 intfind(constchar c, int pos = 0)const;//查找字符c第一次出现位置 intrfind(const string& str, int pos = npos)const;//查找str最后一次位置,从pos开始查找 intrfind(constchar* s, int pos = npos)const;//查找s最后一次出现位置,从pos开始查找 intrfind(constchar* s, int pos, int n)const;//从pos查找s的前n个字符最后一次位置 intrfind(constchar c, int pos = 0)const;//查找字符c最后一次出现位置 string& replace(int pos, int n, const string& str);//替换从pos开始n个字符为字符串str string& replace(int pos, int n,constchar* s);//替换从pos开始的n个字符为字符串s
This is a library conio.h for linux. Just copy file and paste file conio.h on /usr/include/ but don’t forget before you want copy paste on /usr/include/ you must open folder as ADMINISTRATOR first !!
+
git clone https://github.com/zoelabbb/conio.h.git cd conio.h sudo make install
+
+
重启IDE
+
#include<conio.h> voidtoContinue(){ cout << "Press any key to continue ..." << endl; getch(); } //如果在while循环中,可能要用两个getch()才能正常工作
+
+
string一个用法(把字符串当做字符数组)
voidspeechManager::createPlayer(){ string nameSeed; nameSeed = "ABCDEFGHIJKL"; for (int i = 0; i < nameSeed.size(); i++) { string name = "Player - "; name += nameSeed[i]; player tempPlayer; tempPlayer.name = name; for (double &j: tempPlayer.score) j = 0; //看上去高级,可读性降低 this->v1.push_back(i + 10001); this->players.insert(make_pair(i + 10001, tempPlayer)); } }
+
+
遍历容器(使用auto)
for (auto it = vector.begin(); it != vector.end(); it ++){ <expression> }
+
+
特性
using
The modern cpp use more using to define aliases of variables.
+
using byte = unsignedchar; usingarray_t = double[10]; // "array_t" is an array with "double" type and length is ten array_t a; a[0] = 1; // It can be used as a common array usingfunc_t = double(double); func_t* f = sin; std::cout << f(3.1415926 / 4); // Calculate sin(PI/4)
+
+
namespace
When a project was completed by many coders, naming conflicts in so many identifiers may be occurs. Key word namespace can define a namespace with a name or not. The same indentifiers can exist in different namespaces. Using :: access to a namespace. Don’t use ; at the end of namespace.
+
Increment and Decrement
int i = 1; a = i++; // a = 1, i = 2 int i = 1; a = ++i; // a = 2, i = 2
+
+
+
Both i++ and ++i will make i plus 1, but when using them in a class, ++i is more efficienct.
Limit the scope of variables as much as possible. cpp 17 introduced if / switch statements that allow variable initialization.
+
+
if (auto x{ std::cin.get() }; x >= 48 && x <= 57){ std::cout << x << " is a digit." << std::endl; } else{ std::cout << x << " is not a digit." << std::endl; }
+
+
Range-based for
int a[]{ 1, 2, 3, 4, 5, 6, }; for (auto &i : a) // Write by reference i *= 10; for (auto i : a) // Read by value std::cout << i << "\t"; std::cout << std::endl; for (auto i : {12, 25, 67, 43, 89, 54}) // Access the list directly std::cout << i << "\t"; std::cout << std::endl;
To iterate is human, to recurse divine. To recieve multiple data, using initializer_list to send parameters to function. e.g.
+
+
doublesum(std::initializer_list<double> ld){ double s{0}; for (auto i : ld) s += i; return s; } //in main function std::cout << sum({1, 2, 3, 4}) << std::endl; std::cout << sum({1, 2, 3, 4, 5}) << std::endl;
+
+
The result:
+
10 15
+
+
Inline function
Insert the inline keyword in front of the function defination, which is recommanded. When the resouces of codes in a function are less than calling the function, using inline function can increase spending saving. Inlining is at the cost of code bloat(copying), and only saves the overhead of function calls, thereby improving the execution efficiency of functions. Inline should not be used in the following situation:
+
+
If the code in the function body is relatively long, making inlining will lead to higher memory consumption costs.
+
If there is a loop int the function body, the time to execute the code in the function body is greater than the overhead of the function call.
+
+
Default parameter
Provide the default parameters. When calling the function, it can automatically use the default parameters without your actual parameters.
+
Function Template
Function templates implement parameterization of data types. It can use unknown data types as parameters. As long as the type of data meets the requirements defined by the function template, the function template can be called with these types of data as arguments.
+
template <typename T> T my_min(T a, T b){ return a < b ? a : b; } template <typename T> T my_max(T a, T b){ return a < b ? b : a; } doublesum(std::initializer_list<double> ld){ double s{0}; for (auto i : ld) s += i; return s; } template <typename T> std::pair<T, T> my_min_max(T a, T b){ T t_min = my_min(a, b); T t_max = my_max(a, b); return std::make_pair(t_min, t_max); } template <typename T> voidprint(std::pair<T, T> p){ std::cout << typeid(T).name() << ": \t"; std::cout << "(min: " << p.first << ", max: " << p.second << ")\n"; } intmain(int, char **){ print(my_min_max('a', 'b')); print(my_min_max(20, 10)); print(my_min_max(1.5, 2.5)); return0; }
+
+
Lambda Function
intadd(int x, int y){ return x + y; } //in main function int a{1}, b{2}; std::cout << add(a, b) << std::endl; auto f{[](int x, int y) { return x + y; }}; std::cout << f(a, b) << std::endl; auto f2{[=]() { return a + b; }}; std::cout << f2() << std::endl; auto f3{[&](int x) { a *= x; b *= x; }}; f3(10); std::cout << a << std::endl << b << std::endl;
+
+
Lambda function is a function that can capture the variables in a scope autometically. [] means the capture list. There are several commonly used forms of capture lists:
+
+
+
+
Forms
+
Meaning
+
+
+
+
[x]
+
Capture the variable x by value passing
+
+
+
[=]
+
Capture all variables in the parent scope by value passing
+
+
+
[&x]
+
Capture the variable x by reference passsing
+
+
+
[&]
+
Capture all variables in the parent scope by reference passing
+
+
+
[=,&x,&y]
+
Capture the variables x and y by reference passing and the rest by value passing
+
+
+
[&,x]
+
Capture the variable x by value passing and the rest by reference passing
+
+
+
+
Lambda function can have the real parameters.
+
+
Reference
Left-valued reference
+
The reference is a key point and difficulty. A reference is an alias of the referenced object. The two are essentially the same object, but they are displayed as different names and types.
+
+
T& r = t;
+
+
Where T is a data type, & is an operator, r is reference name and t is a variable of type T.
+
+
t cannot be constant or right value expression.
+
r must be initialized when defined. This is excatly where the reference is diferent from the pointer, that is, there is no empty reference. References cannot exist independently, but must be attached to the referenced variable, so it does not take up memory space. If the reference is a named variable, such a reference is called left-valued reference (in cpp98).
+
+
int a = 2; int *p = &a; int &r = a; std::cout << "a:\t" << a << std::endl; std::cout << "*p:\t" << *p << std::endl; std::cout << "r:\t" << r << std::endl; std::cout << "The value of p: \t" << p << std::endl; std::cout << "The address of p:\t" << &p << std::endl; std::cout << "The address of a:\t" << &a << std::endl << "The address of r:\t" << &r << std::endl; a = 3; std::cout << "a:\t" << a << std::endl; std::cout << "*p:\t" << *p << std::endl; std::cout << "r:\t" << r << std::endl; std::cout << "The value of p: \t" << p << std::endl; std::cout << "The address of p:\t" << &p << std::endl; std::cout << "The address of a:\t" << &a << std::endl << "The address of r:\t" << &r << std::endl; r = 4; std::cout << "a:\t" << a << std::endl; std::cout << "*p:\t" << *p << std::endl; std::cout << "r:\t" << r << std::endl; std::cout << "The value of p: \t" << p << std::endl; std::cout << "The address of p:\t" << &p << std::endl; std::cout << "The address of a:\t" << &a << std::endl << "The address of r:\t" << &r << std::endl;
+
+
The result:
+
a: 2 *p: 2 r: 2 The value of p: 0x7fff945b3184 The address of p: 0x7fff945b3178 The address of a: 0x7fff945b3184 The address of r: 0x7fff945b3184 a: 3 *p: 3 r: 3 The value of p: 0x7fff945b3184 The address of p: 0x7fff945b3178 The address of a: 0x7fff945b3184 The address of r: 0x7fff945b3184 a: 4 *p: 4 r: 4 The value of p: 0x7fff945b3184 The address of p: 0x7fff945b3178 The address of a: 0x7fff945b3184 The address of r: 0x7fff945b3184
+
+
It can be seen that the left value reference is only an alias of the variable, so all operations on the lvalue reference are equivalent to the operation on the variable itself. Supplementary explanation:
+
+
Any variable can be reference, such as pointer.
+
+
int m = 3; int* p = &m; int*& rp = p;
+
+
Reference is not variable, so you cannot reference a reference! And at the same time, pointers cannot point to a reference.
+
+
Pointers can be nullptr or void type, but references cannot.
+
+
int m = 3; void* p = &m; p = nullptr; void& r = m; // error! int&r = nullptr; // error!
+
+
+
Cannot build an array of reference.
+
Constant lvalue reference can be initialized by lvalue, constant lvalue and rvalue.
The left reference of the constant is usually used as a formal parameter of the function. At this time, the corresponding actual parameter cannot be modified inside the function through this reference to achieve the purpose of protecting the actual parameter.
+
+
Rvalue reference, move() and Move semantics
template <typename T> voidmy_swap(T &a, T &b){ T t = std::move(a); a = std::move(b); b = std::move(t); }
+
+
Actually it is the swap() in cpp STL. The cpp STL also provides array exchange in the form of overloading.
+
template <classT, std::size_t N> voidmy_swap(T (&a)[N], T (&b)[N]){ if (&a != &b) { T *first1 = a; T *last1 = first1 + N; T *first2 = b; for (; first1 != last1; ++first1, ++first2) { my_swap(*first1, *first2); } } }
intbinarySearch( int arr[], int n , int target){ int l = 0, r = n - 1; while ( l <= r) { int mid = l + (r - l) / 2; if (arr[mid] == target) return mid; if (arr[mid] > target ) r = mid - 1; else l = mid + 1; } return-1; }
+
+
以下代码也是O(logn)的时间复杂度
+
// 整形转成字符串 string intToString( int num ){ string s = ""; // n 经过几次“除以10”的操作后,等于0 while (num ){ s += '0' + num%10; num /= 10; } reverse(s) return s; }
+
+
+
线性对数阶 O(nlogn) 将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logn),也就是了O(nlogn)
+
voidhello(){ for( m = 1 ; m < n ; m++){ i = 1; while( i < n ){ i = i * 2; } } }
+
+
空间复杂度
+
递归与迭代
递归:函数中调用函数本身
+
迭代:每次迭代的结果作为下一次迭代的初始值
+
+
Program = Data Structure + Algorithm
+
+
Complexity
How to judge a algorithm? How to contrast diferent algorithms? Big O Notation: The limiting case of the time or space required by the algorithm as the computational magnitude increases.
+
+
T(n) = O(f(n))
+
+
Time Complexity
+
Example 1:
+
+
for (int i = 1; i <= n; i++){ x++; }
+
+
The time complexity of the for loop is O(n).
+
+
Example 2:
+
+
for (int i = 1; i <= n; i++){ x++; } for (int i = 1; i <= n; i++){ for (int j = 1; j <= n; j++){ x++; } }
+
+
There are a single for loop and a double for loop, and the complexity of the former is O(n) and the latter is O(n$^{2}$) . So when n tends to be infinite, the complexity of whole algorithm is O(n$^{2}$).
+
Analysis of Commonly used time complexity order
+
+
Constant order O(1)
int x = 0; int y = 1; int temp = x; x = y; y = temp;
+
+
As long as there is no complex logic such as loops or recursion, the code is O(1) complex no matter how many lines of code are executed.
+
Linear order O(n)
for (int i = 1; i <= n; i++) { x++; }
+
+
In this code, the for loop is executed n times, so the computation time varies with n, so this kind of code can be expressed by O(n).
+
The logarithmic order O(log n)
int i = 1; while(i < n) { i = i * 2; }
+
+
In the above loop, each time i is multiplied by 2, which means each time i is a step closer to n. So how many cycles does it take for i to be equal to or greater than n, which is solving for 2${^x}$ is equal to n. The answer is x = log 2${^n}$. So after log 2${^n}$ cycles, i is going to be greater than or equal to n, and that’s the end of the code. So the complexity of this code is O(log n).
+
Linear log order O(nlog n)
for(int i = 0; i <= n: i++) { int x = 1; while(x < n) { x = x * 2; } }
+
+
Linear log order O(nlog n) is easy to understand, which means you loop through O(log n) code n times. Each loop is order O(log n), n * log n = n(log n).
+
Squared square order O(n${^2}$)
for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { x++; } }
+
+
O(n${^2}$) is essentially n*n, if we change the number of cycles in the inner layer to m:
+
for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { x++; } }
+
+
The complexity becomes n * m = O(nm).
+
Space Complexity
Since “time complexity” is not the amount of time a program consumes, “space complexity” is not used to calculate the amount of space a program consumes. As the magnitude of the problem increases, the amount of memory a program needs to allocate may also increase, and “space complexity” reflects the tendency of memory space to increase.
+
O(1) Space complexity
int x = 0; int y = 0; x++; y++;
+
+
The space allocated by x and y does not change with the amount of data processed, so the space complexity is O(1).
+
O(n) Space complexity
int[] newArray = newint[n]; for (int i = 0; i < n; i++) { newArray[i] = i; }
+
+
In this code, we create an array of length nand then assign values to the elements in the loop. Therefore, the “space complexity” of this code depends on the length of newArray, which is n, so S(n) = O(n).
+
Sorting Algorithms
Searching is a very important step in computers, but it is often difficult to find a specific number from unordered data. Binary searching, as we mentioned earlier, only works in sorted arrays. So the sorting algorithm is a very important job, and if we can sort the numbers, then we can save a lot of effort when we’re looking for a particular number.
+
There are many sorting algorithms, and each has its own advantages and disadvantages:
+
+
+
+
Algorithm
+
Time Complexity(Best)
+
Time Complexity(Average)
+
Time Complexity(Worst)
+
Space Complexity
+
+
+
+
Quiksort
+
Ω(n log(n))
+
Θ(n log(n))
+
Ω(n${^2}$)
+
O(log(n))
+
+
+
Mergesort
+
Ω(n log(n))
+
Θ(n log(n))
+
O(n log(n))
+
O(n)
+
+
+
Timesort
+
Ω(n)
+
Θ(n log(n))
+
O(n log(n))
+
O(n)
+
+
+
Heapsort
+
Ω(n log(n))
+
Θ(n log(n))
+
O(n log(n))
+
O(1)
+
+
+
Bubble Sort
+
Ω(n)
+
Θ(n${^2}$)
+
O(n${^2}$)
+
O(1)
+
+
+
Insertion Sort
+
Ω(n)
+
Θ(n${^2}$)
+
O(n${^2}$)
+
O(1)
+
+
+
Selection Sort
+
Ω(n${^2}$)
+
Θ(n${^2}$)
+
O(n${^2}$)
+
O(1)
+
+
+
Tree Sort
+
Ω(n log(n))
+
Θ(n log(n))
+
O(n${^2}$)
+
O(n)
+
+
+
Shell Sort
+
Ω(n log(n))
+
Θ(n (log(n))${^2}$)
+
O(n (log(n))${^2}$)
+
O(1)
+
+
+
Bucket Sort
+
Ω(n+k)
+
Θ(n+k)
+
O(n${^2}$)
+
O(n)
+
+
+
Radix Sort
+
Ω(nk)
+
Θ(nk)
+
O(nk)
+
O(n+k)
+
+
+
Counting Sort
+
Ω(n+k)
+
Θ(n+k)
+
O(n+k)
+
O(k)
+
+
+
Cubesort
+
Ω(n)
+
Θ(n log(n))
+
O(n log(n))
+
O(n)
+
+
+
Insertion Sort
Insertion sort is a simple and intuitive sorting algorithm. In insertion sort, we process the unsorted elements from front to back. For each element, we compare it to the previously sorted elements, find the corresponding position, and insert.
+
Essentially, for each element to be processed, we only care about its relationship to the previous element, and we only deal with the elements after the current element in the next round.
+
Specific steps:
+
+
Starting with the second element (the first new element to be sorted), the sequence of previous elements is scanned backwards
+
If the current scanned element is larger than the current element, the scanned element is moved to the next bit
+
Repeat Step 2 until you find a position less than or equal to the new element
+
Insert the new element at that location
+
Repeat Steps 1 through 4 for subsequent elements
+
+
voidinseritonSort(int arr[], int arrayLength){ for (int i = 1; i < arrayLength; i++) { int cur = arr[i]; int inseritonIndex = i - 1; while (inseritonIndex >= 0 && arr[inseritonIndex] > cur) { arr[inseritonIndex + 1] = arr[inseritonIndex]; inseritonIndex--; } arr[inseritonIndex + 1] = cur; } }
+
+
+
T(n) = O(n${^2}$)
+
S(n) = O(1)
+
+
Quick Sort
Quicksort is a Divide and Conquer algorithm in which we turn big problems into small ones, and solve the small ones one by one, so that when the small ones are solved, the big ones will be solved.
+
The basic idea of quicksort is to pick a target element and then put the target element in the correct position in the array. The array is then split into two subarrays based on the sorted elements, using the same method and the same operation for the unsorted range.
+
Specific steps:
+
+
For the current array, we’re going to use the last element as our pivot
+
All elements smaller than the base number are ranked before the base number, and those larger than the base number are ranked after the base number
+
Once the base number is in place, the element is split into two front and back subarrays based on the cardinality position
+
Use steps 1 through 4 recursively for subarrays until the subarray is 1 or less in length
+
+
voidswap(int arr[], int a, int b){ int temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; } intpartition(int arr[], int left, int right){ int pivot = arr[right]; int leftIndex = left; int rightIndex = right - 1; while (1) { while (leftIndex < right && arr[leftIndex] <= pivot) { leftIndex++; } while (rightIndex >= left && arr[rightIndex] > pivot) { rightIndex--; } if (leftIndex > rightIndex) break; swap(arr, leftIndex, rightIndex); } swap(arr, leftIndex, right); return leftIndex; }
voidquickSort(int arr[], int left, int right){ if (left >= right) return; int partitionIndex = partition(arr, left, right); quickSort(arr, left, partitionIndex - 1); quickSort(arr, partitionIndex + 1, right); } voidprintArray(int arr[], int arrayLength){ for (int i = 0; i < arrayLength; i++) { std::cout << arr[i] << " "; } std::cout << "\n"; }
+
+
+
T(n) = O(n${^2}$). Average time complexity is O(n(log n)). S(n) = O(n). Average time complexity is O(log n).
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
char a[5] = {'h', 'e', 'l', 'l', 'o',}; C++ counts food tags from `0`, so `a[0] = 'h'` and `a[1] = 'e'`. Random access using `a[i]` has `O(1)` time complexity. Units of array can be modified.
+
a[0] = 'b';
+
result:
+
bello
+
+
+
Dynamic Allocation of Arrays
A size-n array can be created in this way:
+
char a[n];
+
+
But when writing the code, n must be known.
+
If n is unknown, how dose the program run?
+
char* a = NULL; int n; // array size cin >> n; // read in the size. e.g., get n = 5 a = newchar[n];
+
+
Now a is an empty array whose size is 5.
+
// store somrthing in the array a[0] = 'h'; a[1] = 'e'; a[2] = 'l'; a[3] = 'l'; a[4] = 'o';
+
+
When done, free memory. Otherwise, memory leak can happen.
+
delete [] a; a = NULL;
+
+
+
+
Removing an element in the middle has O(n) time complexity. Require moving the remaining items leftward.
+
Vector
Vector is almost the same as array.
+
The main difference is that vector’s capacity can automatically grow.
+
New elements can be appended using push_back() in O(1) time(on average).
+
The last element can be removed using pop_back() in O(1) time.
When size is going to exceed capacity, program will create a new array of capacity 200, copy the 100 elements from the old array to the new, put the new element in the 101st position and free the old array from memory.
+
List
A Node
A node contains a data and two pointers that one points to the previous node and another points to the next node.
+
Doubly Linked List
std::list<char> l = {'h', 'e', 'l', 'l', 'o'};
+
+
cout << l[2]; // does not work l[0] = 'a'; // does not work
The ascending order must be kept; otherwisem search would take O(n) time. Inserting an item into the middle has O(n) time complexity(on average). Can we perform binary search in the list? No, Given left and right, we cannot get mid efficiently.
There are three ways to create a pointer head. Using first way, you can create a pointer head pointing to a node that has a variable val = 0 and a nullptr (a pointer pointing nothing). And the second way, you create a same head but you must assign a value to val of the node pointed to by head. The last, you even can link a node to the head requiring you give a pointer pointing to the next node.
MAC 地址是出厂分配的,全球唯一,因此引入一个新的地址,每台机器分配一个 32 位(二进制)的编号,即 IP 地址;此时每台电脑既有自己的 MAC 地址又有自己的 IP 地址;IP 地址在软件层面上,可以随时修改,MAC 地址在硬件层面,不能修改
+
此时在两台设备之间传输的信息就包含了两个头部,数据链路层头部和网络层头部
+
两个 IP 处于同一个子网就直接通过交换机发送出去,不在同一个子网就交给路由器处理,192.168.0. xxx 开头一样的属于同一个子网;计算如何判断?答案是通过子网掩码:计算机通过将 IP 地址和子网掩码进行与运算
+
+
+
如某机器的子网掩码为 255.255.255.0,四台电脑的 IP 地址: A 电脑:192.168.0.1 & 225.225.225.0 = 192.168.0.0 B 电脑:192.168.0.2 & 225.225.225.0 = 192.168.0.0 C 电脑:192.168.1.1 & 225.225.225.0 = 192.168.1.0 D 电脑:192.168.1.2 & 225.225.225.0 = 192.168.1.0 计算的结果相等,就属于同一个子网 子网掩码其实是表示 IP 地址前多少位表示子网的网段
+
+
+
当 A 想与 C 通信时,将 A 和 C 的 IP 地址分别与 A 的子网掩码进行 & 运算,发现不相等,则 A 认为 C 和自己不在同一个子网,于是把包发送给路由器
+
+
但是 A 如何知道哪一个是路由器呢?
+
+
对于 A 来说,它只能把包发送到同处于子网下的某一个 IP 上,所以只需要在 A 电脑内配置一个默认网关,也即路由器的 IP 地址 路由器如何知道 C 在哪里?
+
路由器收到包含 IP 地址的数据包,需要判断从哪个端口发送出去,由于子网掩码其实是表示 IP 地址前多少位表示子网的网段,因此可以把 IP 地址与子网掩码合并表示,如 192.168.0.0(255.255.255.0) 可以表示为 192.168.0.0/24(24 表示子网掩码占 24 个字节),路由器通过路由表判断将一个子网下的都转发到对应的端口 发送数据包的数据链路层需要知道 MAC 地址,但是只知道 IP 地址怎么办?
+
答案是 arp 协议;每个电脑都有一张 arp 缓存表,记录着 IP 地址与 MAC 地址的对应关系
+
一开始 arp 缓存表是空的,每台电脑都会广播 arp 请求,收到的电脑会响应也即返回自己的 MAC 地址,此时电脑收到返回会更新自己的 arp 表
QMessageBox mb; mb.setWindowTitle(tr("Black is Win!")); mb.setText(tr("Black is win!")); mb.setInformativeText(tr("Are you want to play again?")); mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Default); mb.setDefaultButton(QMessageBox::Yes); switch (mb.exec()) { case QMessageBox::Yes: newGame(); break; case QMessageBox::No: exit(); break; default: break; }
+
+
or
+
QMessageBox::StandardButton defaultBtn = QMessageBox::NoButton; QMessageBox::StandardButton result; // 返回选择的按钮 result = QMessageBox::question( this, "Black is Win!", "Game over! Are you want to play again?", QMessageBox::Yes | QMessageBox::No, defaultBtn); if (result == QMessageBox::Yes) ui->plainTextEdit->appendPlainText("Question消息框: Yes 被选择"); elseif (result == QMessageBox::No) ui->plainTextEdit->appendPlainText("Question消息框: No 被选择"); else ui->plainTextEdit->appendPlainText("Question消息框: 无选择");
+
+
or
+
QMessageBox::information( this, "Black is Win!", "Game over! Are you want to play again?");
# URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' ## and root as '/child/' url:http://yoursite.com# 你的站点Url root:/# 站点的根目录 permalink::year/:month/:day/:title/# 文章的 永久链接 格式 permalink_defaults:# 永久链接中各部分的默认值
# Category & Tag default_category:uncategorized category_map:# 分类别名 tag_map:# 标签别名
# Date / Time format ## Hexo uses Moment.js to parse and display date ## You can customize the date format as defined in ## http://momentjs.com/docs/#/displaying/format/ date_format:YYYY-MM-DD# 日期格式 time_format:HH:mm:ss# 时间格式
# Pagination ## Set per_page to 0 to disable pagination per_page:10# 分页数量 pagination_dir:page# 分页目录
hexo n "我的博客" == hexo new "我的博客"#新建文章 hexo g == hexo generate #生成 hexo s == hexo server #启动服务预览 hexo d == hexo deploy #部署
hexo server #Hexo会监视文件变动并自动更新,无须重启服务器 hexo server -s #静态模式 hexo server -p 5000 #更改端口 hexo server -i 192.168.1.1 #自定义 IP hexo clean #清除缓存,若是网页正常情况下可以忽略这条命令
# Profile nickname:SincereandFearless ### this variable is MarkDown form. description:Itisthisintellectualactivityofinquiry,seeking,ratherthansummativeanswers,that<br>makeoneaphilosopher,becausesummativeanswerscaneasilybereducedtounthinking<br>dogmasandslogansthatrequirenothoughtorunderstandingatall.
avatar:/image/avatar.jpeg
# main menu navigation ## links key words should not be changed. ## Complete url after key words. ## Unused key can be commented out. links: Blog:/archives # Category: # Tags: # Link: # Resume: # Publish: # Trophy: # Gallery: # RSS: # AliPay: # ZhiHu: https://www.zhihu.com/people/sirice # LinkedIn: # FaceBook: # Twitter: # Skype: # CodeSandBox: # CodePen: # Sketch: # Gitlab: # Dribbble: # YouTube: # QQ: # Weibo: # WeChat: Github:https://github.com/dioysen
# how links show: you have 2 choice--text or icon. links_text_enable:false links_icon_enable:true
# Post page ## Post_meta post_meta_enable:true
post_author_enable:true post_date_enable:true post_category_enable:true ## Post copyright post_copyright_enable:true
# Date / Time format ## Hexo uses Moment.js to parse and display date ## You can customize the date format as defined in ## http://momentjs.com/docs/#/displaying/format/ date_format:MMMMD,YYYY time_format:H:mm:ss
# stylesheets loaded in the <head> stylesheets: -/css/style.css
# scripts loaded in the end of the body scripts: -/js/script.js -/js/tocbot.min.js # tscanlin/tocbot: Build a table of contents from headings in an HTML document. # https://github.com/tscanlin/tocbot
# plugin functions ## Mathjax: Math Formula Support ## https://www.mathjax.org mathjax: enable:true import:demand# global or demand ## global: all pages will load mathjax,this will degrade performance and some grammers may be parsed wrong. ## demand: Recommend option,if your post need fomula, you can declare 'mathjax: true' in Front-matter
Different from hexo g -w ; hexo s, & implicate that the former and the latter will run at the same time. The command in the front of ; priors to the command in the back of ;.
+
给 shell 脚本文件添加可执行权限
chmod +x shell.sh
+
+
Linux 查看磁盘空间
df -hl
+
+
Linux修改中文
vim /etc/locale.gen # Uncommit zh_CN and en_US locale-gen
vim /etc/locale.conf # LANG="zh_CN-UTF-8"
vim .bashrc # Add: # export LANG=zh_CN.UTF-8 # export LANGUAGE=zh_CN:en_US
sudo pacman -Syyu # Update system sudo pacman -S pigz #Install pigz cd / sudo tar --use-compress-program=pigz -cvpf /run/media/icarus/MHD/Systembackup/archlinux-backup@`date +%Y-%m+%d`.tgz --exclude=/proc --exclude=/lost+found --exclude=/mnt --exclude=/sys --exclude=/tmp --exclude=/run/media --exclude=/home / #Backup
sudo tar -cvpzf /run/media/icarus/MHD/Systembackup/archlinux-backup-pureKDE.tgz --exclude=/proc --exclude=/lost+found --exclude=/mnt --exclude=/sys --exclude=/run/media --[[#Clean up Trash in Archlinux]]exclude=/tmp / #Don't use pigz, and network is not necessary
+
+
Restore
# Boot by Live CD iwctl device list # Find wlan0 station wlan0 scan # Scan WIFI station wlan0 get-networks # List network station wlan0 connect WIFI1 # Connect a network exit# Exit after successing ping www.bing.com # Test network
sudo vim /etc/pacman.d/mirrorlist # Add "Server = https://mirrors.ustc.edu.cn/archlinuxcn/$arch" sudo pacman -S pigz # Install pigz lsblk # View disk mkdir /RE # Create a partition of backup files mount /dev/sda1 /RE # Mount the disk where backup files are stored mount /dev/sdb3 /mnt # Mount system root directory of Archlinux to /mnt
rm -rf /mnt/* # Clean old system tar --use-compress-program=pigz -xvpf /RE/Systembackup/archlinux-backup-pureKDE.tgz -C /mnt # Restore system ls /mnt # View the restore umount -R /mnt # Unmount /mnt reboot # Reboot
+
+
It is worth noting that fstab and GRUB boot sequence needs to be regenerated!
+
Add Windows Boot Manager to GRUB
sudo pacman -S grub-customizer
+
+
Add a boot menu in grub-customizer, then modify the configuration:
Can’t Connect Bluetooth Keyboard in Archlinux (GUI)
Using Cli :
+
sudo pacman -S bluez bluez-utils # Install bluez sudo bluetoothctl power on agent on default-agent scan on pair <MAC address of keyboard> trust <MAC address of keyboard> connect <MAC address>
+
+
安装WPS
使用yay安装:
+
yay -S wps-office-mui-zh-cn wps-office ttf-wps-fonts
sudo nginx -t # 显示为 nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
git clone https://github.com/tuanpham-dev/code-server-font-patch.git cd code-server-font-patch
# Run this command (change path-to-code-server to your code-server path, leave it empty if you install code-server from installer or code-server is in /usr/lib/code-server): sudo ./patch.sh [path-to-code-server]
+
+
You may need to set font family in code-server settings:
Open a WSL2 distro and get into a folder, input code . and press enter. Vscode will be started. There is empty in the folder. Press ctrl+shift+p and input cmake: quick start, select the CMake: Quick Start. Choice the clang variant. Input the name of you project. A hello world program will be auto-created. Now, you can build and run your project.
Add a launch.json in the workfolder, and add configuration lldb. Modify the program.
+
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version":"0.2.0", "configurations":[ { "type":"lldb", "request":"launch", "name":"Debug", "program":"${workspaceFolder}/build/</*Your project name/>", "args":[], "cwd":"${workspaceFolder}" } ] }
+
+
MultiFolders
Add the include_directories(./Sources) to CMakeLists.txt .
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version":"0.2.0", "configurations":[ { "type":"lldb", "request":"launch", "name":"Debug", "program":"${workspaceFolder}/myvector/build/myvector", "args":[], "cwd":"${workspaceFolder}/myvector", } ] }
+
+
+
If breakpoint doesn’t work, use cmake build a debug target.
#编辑镜像源,将“China”字样的镜像源复制到镜像首,如“tuna” #使用文本编辑器“VIM”,打开镜像文件 vim /etc/pacman.d/mirrorlist #在该文件中搜索“China”,vim使用符号“/”作为搜索标志,回车后使用“n”/“N”切换搜索“下一个”/“上一个” /China(回车) #停留在字样“tuna”/“aliyun”处,将其复制下来,vim使用“2yy”表示“复制2行” 2yy #跳转到第6行 6gg #粘贴 p #保存退出 :wq
+
+
+
安装基础软件包
+
+
#使用 pacstrap 脚本,安装 base 软件包和 Linux 内核以及常规硬件的固件,此处我选择长期支持版内核 pacstrap /mnt base linux-lts linux-firmware #使用 pacstrap 脚本,安装常用软件 pacstrap /mnt base-devel grub openssh intel-ucode vim man dhcpcd
+
+
+
配置系统
+
+
#生成 fstab 文件 genfstab -U /mnt >> /mnt/etc/fstab #将环境变更至新系统下 arch-chroot /mnt #设置时区(软链接) ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #同步时钟 hwclock --systohc #本地化(语言) vim /etc/locale.gen #移除某些行头的注释符“#”,可通过搜索“en_US”实现 en_US.UTF-8 UTF-8 #保存退出 :wq #生成 local 信息 locale-gen #创建 locale.conf vim /etc/locale.conf #编辑 LANG 变量 LANG=en_US.UTF-8 #保存退出 :wq #创建网络相关文件 vim /etc/hostname #写入你想要用的主机名 myhostname vim /etc/hosts 127.0.0.1 localhost ::1 localhost 127.0.1.1 tencent.localdomain tencent
deb https://mirrors.ustc.edu.cn/termux/apt/termux-main stable main
+
+
debian
deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable main contrib non-free deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free
# deb http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free
+
+
archlinux
Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
# arm Server = https://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo
+
+
ubuntu
# 默认注释了源码仓库,如有需要可自行取消注释 deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# 预发布软件源,不建议启用 # deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
+
+
kali
支持的架构:amd64, armel, armhf, i386
+
deb https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
-- Telescope -- 查找文件 map("n", "<C-p>", ":Telescope find_files<CR>", opt) -- 全局搜索 map("n", "<C-f>", ":Telescope live_grep<CR>", opt) pluginKeys.telescopeList = { i = { -- 上下移动 ["<C-k>"] = "move_selection_next", ["<C-i>"] = "move_selection_previous", ["<Down>"] = "move_selection_next", ["<Up>"] = "move_selection_previous", -- 历史记录 ["<C-n>"] = "cycle_history_next", ["<C-p>"] = "cycle_history_prev", -- 关闭窗口 ["<C-c>"] = "close", ["<Esc>"] = "close", -- 预览窗口上下滚动 ["<C-u>"] = "preview_scrolling_up", ["<C-d>"] = "preview_scrolling_down", }, } -- Lsp Mappings 待看 -- See `:help vim.diagnostic.*` for documentation on any of the below functions vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, opts) vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) vim.keymap.set('n', '<space>q', vim.diagnostic.setloclist, opts) -- Use an on_attach function to only map the following keys -- after the language server attaches to the current buffer local on_attach = function(client, bufnr) -- Enable completion triggered by <c-x><c-o> vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') -- Mappings. -- See `:help vim.lsp.*` for documentation on any of the below functions local bufopts = { noremap=true, silent=true, buffer=bufnr } vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) map("n", "gh", vim.lsp.buf.hover, opt) vim.keymap.set('n', 'gh', vim.lsp.buf.hover, bufopts) vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts) vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, bufopts) vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, bufopts) vim.keymap.set('n', '<space>wl', function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end, bufopts) vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, bufopts) vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, bufopts) vim.keymap.set('n', '<space>ca', vim.lsp.buf.code_action, bufopts) vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) vim.keymap.set('n', '<space>f', function() vim.lsp.buf.format { async = true } end, bufopts) end local lsp_flags = { -- This is the default in Nvim 0.7+ debounce_text_changes = 150, } require('lspconfig')['pyright'].setup{ on_attach = on_attach, flags = lsp_flags, } require('lspconfig')['clangd'].setup{ on_attach = on_attach, flags = lsp_flags, }
-- nvim-cmp 自动补全 pluginKeys.cmp = function(cmp) local feedkey = function(key, mode) vim.api.nvim_feedkeys(vim.api.nvim_replace_termcodes(key, true, true, true), mode, true) end
local has_words_before = function() local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil end
return {
-- 自定义代码段跳转到下一个参数 ["<C-l>"] = cmp.mapping(function(_) if vim.fn["vsnip#available"](1) == 1then feedkey("<Plug>(vsnip-expand-or-jump)", "") end end, { "i", "s" }),
-- 自定义代码段跳转到上一个参数 ["<C-h>"] = cmp.mapping(function() if vim.fn["vsnip#jumpable"](-1) == 1then feedkey("<Plug>(vsnip-jump-prev)", "") end end, { "i", "s" }),
-- Super Tab ["<Tab>"] = cmp.mapping(function(fallback) if cmp.visible() then cmp.select_next_item() elseif vim.fn["vsnip#available"](1) == 1then feedkey("<Plug>(vsnip-expand-or-jump)", "") elseif has_words_before() then cmp.complete() else fallback() -- The fallback function sends a already mapped key. In this case, it's probably `<Tab>`. end end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function() if cmp.visible() then cmp.select_prev_item() elseif vim.fn["vsnip#jumpable"](-1) == 1then feedkey("<Plug>(vsnip-jump-prev)", "") end end, { "i", "s" }), -- end of super Tab } end
LxRunOffline i -n <自定义名称> -f <Arch镜像位置> -d <安装系统的位置> -r root.x86_64
+
+
example:
+
LxRunOffline i -n ArchLinux -f C:\Users\dionysen\Downloads\archlinux-bootstrap-2020.10.01-x86_64.tar.gz -d C:\Users\dionysen\Linux -r root.x86_64
+
+
2. Change WSL2 version in Archlinux
wsl --set-version ArchLinux 2
+
+
Configuration
Basic Configuration
wsl -d Archlinux rm /etc/resolv.conf exit
+
+
The terminal window will be unavailable, so you should reopen a new terminal window, then:
+
wsl --shutdown Archlinux wsl -d Archlinux cd /etc vi pacman.conf
+
+
Add following code in the end of pacman.conf:
+
[archlinuxcn] Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
+
+
And change the mirrorlist:
+
vi ./pacman.d/mirrorlist
+
+
Remove the comment of a Chinese source.
+
pacman -Syy pacman-key --init pacman-key --populate pacman -S archlinuxcn-keyring pacman -S base base-devel vim git wget
passwd # input the password of root useradd -m -G wheel -s /bin/bash <username> passwd <username> vim /etc/sudoers
+
+
Use /wheel find the line wheel ALL=(ALL) ALL and remove the comment.
+
id -u <username> exit
+
+
Execute the command in powershell to set default user of Archlinux:
+
lxrunoffline su -n Archlinux -v <username>
+
+
Install Ubuntu20.02 in WSL2
wsl --list--online# 查看可直接安装的发行版列表 # 显示如下: PS C:\Windows\system32> wsl -l--online The following is a list of valid distributions that can be installed. Install using'wsl.exe --install <Distro>'.
NAME FRIENDLY NAME Ubuntu Ubuntu Debian Debian GNU/Linux kali-linux Kali Linux Rolling SLES-12 SUSE Linux Enterprise Server v12 SLES-15 SUSE Linux Enterprise Server v15 Ubuntu-18.04 Ubuntu 18.04 LTS Ubuntu-20.04 Ubuntu 20.04 LTS OracleLinux_8_5 Oracle Linux 8.5 OracleLinux_7_9 Oracle Linux 7.9
# 安装ubuntu 20.04 wsl --install Ubuntu-20.04
+
+
然后打开终端,打开ubuntu-20.04,创建用户和密码
+
换源+更新
+
然后安装anaconda
+
Install Anaconda on Ubuntu
wget https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-5.3.0-Linux-x86_64.sh chmod +x Anaconda3-5.3.0-Linux-x86_64.sh ./Anaconda3-5.3.0-Linux-x86_64.sh yes ENTER
It uses ssh for data transfer, and uses the same authentication and provides the same security as a login session.
+
scp will ask for passwords or passphrases if they are needed for authentication.
+
The source and target may be specified as a local pathname, a remote host with optional path in the form [user@]host:[path], or a URI in the form scp://[user@]host[:port][/path].
+
+
Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file names containing ‘:‘ as host speacifiers.
+
+
When copying between two remote hosts, if the URI format is used, a port cannot be specified on the target if the -R option is used.
+
+
+
+
Options
+
Implication
+
+
+
+
-3
+
Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts.
+
+
+
-4
+
Forces scp to use IPv4 addresses only
+
+
+
-6
+
Forces scp to use IPv6 addresses only
+
+
+
-A
+
Allows forwarding of ssh-agent(1) to the remote system. The default is not to forward an authentication agent.
cd /etc/apt/sources.list.d;wget https://xpra.org/repos/jammy/xpra.list # ubuntu 22.04 doesn't work cd /etc/apt/sources.list.d;wget https://xpra.org/repos/focal/xpra.list # ubuntu 20.04
structoption { constchar *name; // name is the name of the long option. int has_arg; //has_arg is: no_argument (or 0) if the option does not take an argument; //required_argument (or 1) if the option requires an argument; //or optional_argument (or 2) if the option takes an optional argument. int *flag; //flag specifies how results are returned for a long option. If flag is NULL, then getopt_long() returns val. (For example, the calling program may set val to the equivalent short option character.) Otherwise, getopt_long() returns 0, and flag points to a variable which is set to val if the option is found, but left unchanged if the option is not found. int val; //val is the value to return, or to load into the variable pointed to by flag. // The last element of the array has to be filled with zeros. };
Vim using Coc-nvim plugin clangd-lsp need to read CMakeLists.txt so that it can auto-complete your code. If your project builds with CMake, it can generate this file. You should enable it with:
+
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1
+
+
Or add to CMakeLists.txt:
+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+
compile_commands.json will be written to your build directory. If your build directory is $SRC or $SRC/build, clangd will find it. Otherwise, symlink or copy it to $SRC, the root of your source tree.
echo"Input path: $1" echo"With subset: $2" echo"Custom text file: $3"
# Get current file directory current_dir=$(dirname"$0")
text_file="$current_dir/common-text.txt"
if [ -f "$3" ]; then text_file="$3" fi
# Compress font compress() { # Get file basename file_basename=$(basename"$1") # Get file extension file_extension="${file_basename##*.}" # Get file name without extension file_name="${file_basename%.*}"
if [ "$2" = "true" ]; then echo"Make subset for $1 with $text_file" fonttools subset "$1" --text-file="$text_file" --output-file="$file_name.subset.$file_extension" echo"Compressing $1.subset" fonttools ttLib.woff2 compress "$file_name.subset.$file_extension" -o "$file_name.subset.woff2" else echo"Compressing $1" fonttools ttLib.woff2 compress "$1" -o "$file_name.woff2" fi }
# Is directory? if [ -d "$1" ]; then echo"Directory" for file in"$1"/*.{ttf,otf}; do compress "$file""$2" done else echo"File" compress "$1""$2" fi # ---------- 脚本边界 ----------
# Font family, customize font family. (you don't usually have to fill) # e.g. font_family: STKaiti, STSong, STHeiti font_family:LXGWBright,LXGWBrightSemiLight,Simsun,STSong
git clone https://gitee.com/sential/vim_config_cpp.git cd vim_config_cpp mv ./.vim ~/.vim
+
+
完成后打开vim,按:PlugInstall,然后回车,即可安装插件(需梯子)。
+
+
+
配置文件
+
以下为vimrc的全部内容:
+
" ------ Basic Setting ------ set ts=4 set shiftwidth=4 set softtabstop=4 set number set expandtab set autoindent set noeb set scrolloff=5 set t_Co=256 set wildmenu set smartcase set cursorline set encoding=utf-8 " ------ Theme Setting ------ set background=dark
hi cursorLine cterm=underline ctermbg=darkred ctermfg=white set relativenumber
# Enable Hot Reload for MSVC compilers if supported. if (POLICY CMP0141) cmake_policy(SET CMP0141 NEW) set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>") endif()
「对象的独立存在 vs 感知它它才存在」一节中讲到「有只狗熊扑过来,我闭上眼睛,狗熊就没了……这在物理上是相当困难的」,这无法说明对象是可以独立存在的,因为感知并非只有眼睛,闭上眼睛,狗熊扑过来,身上的触觉感受到狗熊,依然能证明狗熊的存在。因此问题的关键仍然是感知到等于存在,但感知不到的时候无法对是否存在下结论,因为它可能存在只是没有感知到(这意味只要感知就一定能感知到),也可能是不存在的(感知也感知不到)。是否可以以此作为存在的定义呢?既存在是只要感知就能感知到的东西,不存在是无论如何也感知不到的东西。
// --------------- 7. 窗口绘制循环 --------------- while (!glfwWindowShouldClose(window)) { // input // ----- processInput(window); // render // ----- glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); //glBindVertexArray(VAO); // seeing as we only have a single VAO there's //// no need to bind it every time, but we'll do //// so to keep things a bit more organized //glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glfwSwapBuffers(window); glfwPollEvents(); }
// glfw: terminate, clearing all previously allocated GLFW resources. // ------------------------------------------------------------------ glfwTerminate(); return0; } // process all input: query GLFW whether relevant keys are pressed/released this // frame and react accordingly // --------------------------------------------------------------------------------------------------------- voidprocessInput(GLFWwindow* window){ if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
// glfw: whenever the window size changed (by OS or user resize) this callback // function executes // --------------------------------------------------------------------------------------------- voidframebuffer_size_callback(GLFWwindow* window, int width, int height){ // make sure the viewport matches the new window dimensions; note that width // and height will be significantly larger than specified on retina // displays. glViewport(0, 0, width, height); }
+
+
概念与作用
第一个三角形涉及到一些概念和特性,最引人注目的是三个对象,即:
+
+
顶点数组对象:Vertex Array Object,VAO
+
顶点缓冲对象:Vertex Buffer Object,VBO
+
元素缓冲对象:Element Buffer Object,EBO 或 索引缓冲对象 Index Buffer Object,IBO
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version":"0.2.0", "configurations":[ { "type":"lldb", "request":"launch", "name":"Debug", "program":"${workspaceFolder}/path/to/your-debug-program",// 要制定需要debug的程序 "args":[], "cwd":"${workspaceFolder}" } ] }
PS D:\proj\build> cmake .. -- Building for: Visual Studio 172022 -- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19045. -- The C compiler identification is MSVC 19.36.32534.0 -- The CXX compiler identification is MSVC 19.36.32534.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: E:/VS2022/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: E:/VS2022/VC/Tools/MSVC/14.36.32532/bin/Hostx64/x64/cl.exe - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Configuring done (7.5s) -- Generating done (0.1s) -- Build files have been written to: D:/proj/build
+
+
输入命令cmake --build .编译:
+
PS D:\proj\build> cmake --build . MSBuild version 17.6.3+07e294721 for .NET Framework
1>Checking Build System Building Custom Rule D:/proj/CMakeLists.txt main.cpp win32.vcxproj -> D:\proj\build\Debug\win32.exe Building Custom Rule D:/proj/CMakeLists.txt
xmake create -t qt.console test xmake create -t qt.static test xmake create -t qt.shared test xmake create -t qt.quickapp test xmake create -t qt.widgetapp test
// set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float vertices[] = { -0.5f, -0.5f, 0.0f, // left 0.5f, -0.5f, 0.0f, // right 0.0f, 0.5f, 0.0f// top };
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). glBindVertexArray(VAO); gVertexArrayObject = VAO;
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. glBindVertexArray(0);
// draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized glDrawArrays(GL_TRIANGLES, 0, 3);
// set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float vertices[] = { -0.5f, -0.5f, 0.0f, // left 0.5f, -0.5f, 0.0f, // right 0.0f, 0.5f, 0.0f// top };
GLuint VBO, VAO;
glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). glBindVertexArray(VAO);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other // VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary. glBindVertexArray(0);
// draw our first triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized glDrawArrays(GL_TRIANGLES, 0, 3);
glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // set the texture wrapping parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // set texture wrapping to GL_REPEAT (default wrapping method) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // load image, create texture and generate mipmaps data = stbi_load("C:\\Users\\zhaoys-c\\source\\repos\\Dionysen\\LearnOpenGL\\OpenGL\\OpenGL\\Resources\\awesomeface.png", &width, &height, &nrChannels, 0); if (data) { // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed to load texture2" << std::endl; } stbi_image_free(data);
glfwTerminate(); return0; } // process all input: query GLFW whether relevant keys are pressed/released this // frame and react accordingly // ----------------------- voidprocessInput(GLFWwindow* window){ if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); }
// glfw: whenever the window size changed (by OS or user resize) this callback // function executes // ---------------------- voidframebuffer_size_callback(GLFWwindow* window, int width, int height){ // make sure the viewport matches the new window dimensions; note that width // and height will be significantly larger than specified on retina // displays. glViewport(0, 0, width, height); }
int width, height, nrComponents; unsignedchar* data = stbi_load(path, &width, &height, &nrComponents, 0); if (data) { GLenum format = {}; if (nrComponents == 1) format = GL_RED; elseif (nrComponents == 3) format = GL_RGB; elseif (nrComponents == 4) format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D);
// An abstract camera class that processes input and calculates the // corresponding Euler Angles, Vectors and Matrices for use in OpenGL classCamera { public: // 摄像机属性 glm::vec3 Position; // 摄像机位置向量 glm::vec3 Front; // 方向向量,摄像机指向的目标的方向 glm::vec3 Up; // 上向量,也即y轴正方向,叉乘方向向量可得右向量 glm::vec3 Right; // 右向量,摄像机空间x轴的正方向 glm::vec3 WorldUp; // 上向量 // 有了三个互相垂直的轴,外加一个平移向量,即可创建一个矩阵,可以用这个矩阵乘以任何向量来将其变换到那个空间
// returns the view matrix calculated using Euler Angles and the LookAt // Matrix glm::mat4 GetViewMatrix()// 生成观察矩阵 { // return glm::lookAt(Position, Position + Front, Up); // // // lookat函数只需要一个位置,一个目标,和一个上向量,它会自己创建一个观察矩阵,此观察矩阵点乘空间中的物体,即可将物体变换到此观察空间中
// ------------ 以下为自己的lookat: // 1. Position = known // 2. Calculate cameraDirection glm::vec3 zaxis = glm::normalize(-Front); // 3. Get positive right axis vector glm::vec3 xaxis = glm::normalize(glm::cross(glm::normalize(WorldUp), zaxis)); // 4. Calculate camera up vector glm::vec3 yaxis = glm::cross(zaxis, xaxis);
// Create translation and rotation matrix // In glm we access elements as mat[col][row] due to column-major layout glm::mat4 translation = glm::mat4(1.0f); // Identity matrix by default translation[3][0] = -Position.x; // Third column, first row translation[3][1] = -Position.y; translation[3][2] = -Position.z; glm::mat4 rotation = glm::mat4(1.0f); rotation[0][0] = xaxis.x; // First column, first row rotation[1][0] = xaxis.y; rotation[2][0] = xaxis.z; rotation[0][1] = yaxis.x; // First column, second row rotation[1][1] = yaxis.y; rotation[2][1] = yaxis.z; rotation[0][2] = zaxis.x; // First column, third row rotation[1][2] = zaxis.y; rotation[2][2] = zaxis.z; return rotation * translation; }
// processes input received from any keyboard-like input system. Accepts // input parameter in the form of camera defined ENUM (to abstract it from // windowing systems) voidProcessKeyboard(Camera_Movement direction, float deltaTime){ float velocity = MovementSpeed * deltaTime; // 设定速度 // 根据方向调整方向向量 if (direction == FORWARD) Position += Front * velocity; if (direction == BACKWARD) Position -= Front * velocity; if (direction == LEFT) Position -= Right * velocity; if (direction == RIGHT) Position += Right * velocity; if (direction == UP) Position.y += velocity; if (direction == DOWN) Position.y -= velocity; // Position.y = 0.0f; // 确保不会偏离xz平面
// Setting faster if (direction == FASTER_FORWARD) Position += Front * (velocity * 10); if (direction == FASTER_BACKWARD) Position -= Front * (velocity * 10); if (direction == FASTER_LEFT) Position -= Right * (velocity * 10); if (direction == FASTER_RIGHT) Position += Right * (velocity * 10); }
// processes input received from a mouse input system. Expects the offset // value in both the x and y direction. voidProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true){ xoffset *= MouseSensitivity; // x方向的鼠标偏离 yoffset *= MouseSensitivity; // y方向的鼠标偏离
Yaw += xoffset; // 偏航 Pitch += yoffset; // 仰角
if (constrainPitch) // 确保仰角足够大时屏幕不会被翻转 { if (Pitch > 89.0f) Pitch = 89.0f; if (Pitch < -89.0f) Pitch = -89.0f; }
// update Front, Right and Up Vectors using the updated Euler angles updateCameraVectors(); }
// processes input received from a mouse scroll-wheel event. Only requires // input on the vertical wheel-axis voidProcessMouseScroll(float yoffset)// 处理缩放 { Zoom -= (float)yoffset; if (Zoom < 1.0f) Zoom = 1.0f; if (Zoom > 45.0f) Zoom = 45.0f; }
private: // 从更新后的相机的欧拉角计算方向向量 voidupdateCameraVectors(){ // calculate the new Front vector glm::vec3 front; front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch)); front.y = sin(glm::radians(Pitch)); front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch)); Front = glm::normalize(front); // 同时重新计算了右向量和上向量 Right = glm::normalize(glm::cross(Front, WorldUp)); // 将向量归一化,因为你向上或向下看的次数越多,它们的长度就越接近0,这会导致移动速度变慢。 Up = glm::normalize(glm::cross(Right, Front)); } }; #endif
User @wachidadinugroho has worked out the details on how to setup a shared folder to be used between Waydroid and your host filesystem.
+
Setting up a shared folder will allow the user to copy/paste files from the host and they appear inside waydroid/android. sudo mount --bind <source> ~/.local/share/waydroid/data/media/0/<target>
+
Then verify that the target folder exists:
+
sudo ls ~/.local/share/waydroid/data/media/0/Examples:
+
sudo mount --bind ~/Documents ~/.local/share/waydroid/data/media/0/Documents sudo mount --bind ~/Downloads ~/.local/share/waydroid/data/media/0/Download sudo mount --bind ~/Music ~/.local/share/waydroid/data/media/0/Music sudo mount --bind ~/Pictures ~/.local/share/waydroid/data/media/0/Pictures sudo mount --bind ~/Videos ~/.local/share/waydroid/data/media/0/Movies
+
+
You can also make your own custom mount point to cater to your needs.
By default ogre will build the recommended dependencies automatically when you run cmake configure the first time. Ogre will install the dependencies into the subfolder Dependencies in the build dir by default. You can configure it by setting OGRE_DEPENDENCIES_DIR in cmake.
+
+
文档的意思是Ogre会在配置cmake的时候自动安装依赖
+
+
拉取源码
git clone https://github.com/OGRECave/ogre.git
+
+
配置cmake
cd ogre mkdir build cd build cmake ..
+
+
编译
cmake --build . --config Release
+
+
安装到系统中
想要使用它,最好将头文件和库文件放置到干净的地方。
+
cmake --build . --config Release --target install
+
+
你可能需要root权限才能完成这个操作。
+
测试
使用官方示例:
+
// This file is part of the OGRE project. // It is subject to the license terms in the LICENSE file found in the top-level // directory of this distribution and at https://www.ogre3d.org/licensing. // SPDX-License-Identifier: MIT
//! [setup] // get a pointer to the already created root Ogre::Root *root = ctx.getRoot(); // root->createRenderWindow("w",800,600,false,0); Ogre::SceneManager *scnMgr = root->createSceneManager();
// register our scene with the RTSS Ogre::RTShader::ShaderGenerator *shadergen = Ogre::RTShader::ShaderGenerator::getSingletonPtr(); shadergen->addSceneManager(scnMgr);
// without light we would just get a black screen Ogre::Light *light = scnMgr->createLight("MainLight"); Ogre::SceneNode *lightNode = scnMgr->getRootSceneNode()->createChildSceneNode(); lightNode->setPosition(0, 15, 25); lightNode->attachObject(light);
// also need to tell where we are Ogre::SceneNode *camNode = scnMgr->getRootSceneNode()->createChildSceneNode(); camNode->setPosition(50, 50, 50); camNode->lookAt(Ogre::Vector3(0, 0, -1), Ogre::Node::TS_PARENT);
// create the camera Ogre::Camera *cam = scnMgr->createCamera("myCam"); cam->setNearClipDistance(5); // secific to this sample cam->setAutoAspectRatio(true); camNode->attachObject(cam);
// and tell it to render into the main window ctx.getRenderWindow()->addViewport(cam);
# required for Ogre 1.11+ set(CMAKE_CXX_STANDARD 11)
## [discover_ogre] # The COMPONENTS part checks that OGRE was built the way we need it # The CONFIG flag makes sure we get OGRE instead of OGRE-next find_package(OGRE REQUIRED COMPONENTS Bites CONFIG)
CREATETABLE mytable ( id INTPRIMARY KEY, name VARCHAR(50) );
+
+
插入数据:
+
INSERTINTO mytable (id, name) VALUES (1, 'John');
+
+
查询数据:
+
SELECT*FROM mytable;
+
+
更新数据:
+
UPDATE mytable SET name ='Alice'WHERE id =1;
+
+
删除数据:
+
DELETEFROM mytable WHERE id =1;
+
+
客户端常用命令
连接到mysql
+
mysql -u root -p
+
+
输入\h查看帮助:
+
List of all client commands: Note that all text commands must be first on line and end with ';' ? (\?) Synonym for `help'. clear (\c) Clear the current input statement. connect (\r) Reconnect to the server. Optional arguments are db and host. delimiter (\d) Set statement delimiter. edit (\e) Edit command with $EDITOR. ego (\G) Send command to MariaDB server, display result vertically. exit (\q) Exit mysql. Same as quit. go (\g) Send command to MariaDB server. help (\h) Display this help. nopager (\n) Disable pager, print to stdout. notee (\t) Don't write into outfile. pager (\P) Set PAGER [to_pager]. Print the query results via PAGER. print (\p) Print current command. prompt (\R) Change your mysql prompt. quit (\q) Quit mysql. costs (\Q) Toggle showing query costs after each query rehash (\#) Rebuild completion hash. source (\.) Execute an SQL script file. Takes a file name as an argument. status (\s) Get status information from the server. system (\!) Execute a system shell command. tee (\T) Set outfile [to_outfile]. Append everything into given outfile. use (\u) Use another database. Takes database name as argument. charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets. warnings (\W) Show warnings after every statement. nowarning (\w) Don't show warnings after every statement.
For server side help, type 'help contents'
+
+
简单使用
连接:
+
mysql -u root -p
+
+
数据库操作:
+
CREATE DATABASE </database_name>; # 创建 DROP DATABASE </database_name>; # 删除 USE </database_name>; # 选择
+
+
数据表操作:
+
CREATE TABLE </table_name> (column_name column_type); # 创建表 CREATE TABLE IF NOT EXISTS </table_name> (column_name column_type); # 不存在则创建表 DROP TABLE </table_name>; # 删除表 INSERT INTO </table_name> ( field1, field2,...fieldN ) VALUES ( value1, value2,...valueN ); # 表中插入数据 SELECT * FROM </table_name>; # 从表中读取数据
HTMLCanvasElement:Provides properties and methods for manipulating the layout and presentation of elements. The HTMLCanvasElement interface also inherits the properties and methods of the HTMLElement interface.
+
CanvasRenderingContext2D:The CanvasRenderingContext2D interface, part of the Canvas API, provides the 2D rendering context for the drawing surface of a element. It is used for drawing shapes, text, images, and other objects.
在CanvasRenderingContext2D接口中,clearRect(x, y, width, height)方法用于清除指定矩形区域内的像素。它接受四个参数,分别是矩形左上角的x坐标、y坐标,以及矩形的宽度和高度。调用clearRect()方法会将指定矩形区域内的像素设为透明,从而清除该区域的内容。
+
Pinia订阅
store.$subscribe((_, state) => { if (state.shouldClear) { clearCanvas(); } });
ImGui::Begin("Cube and Lighting"); // Create a window called "Cube and Lighting" and append into it.
ImGui::Text("Here can be adjust some params of the sence."); // Display some text (you can use a format strings too) ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::SliderFloat("ambientStrength", &ambientStrength, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::SliderFloat("specularStrength", &specularStrength, 0.0f, 1.0f);
ImGui::ColorEdit3("Cube color", (float*)&objectColor); // Edit 3 floats representing a color ImGui::Text("Cube color = %f, %f, %f", objectColor.x, objectColor.y, objectColor.z);
if (ImGui::Button("Button")) counter++;// Buttons return true when clicked (most widgets return true when edited/activated)
// draw skybox as last glDepthFunc(GL_LEQUAL); // change depth function so depth test passes when values are equal to depth buffer's content skyboxShader.use(); view = glm::mat4(glm::mat3(camera.GetViewMatrix())); // remove translation from the view matrix skyboxShader.setMat4("view", view); skyboxShader.setMat4("projection", projection); // skybox cube glBindVertexArray(skyboxVAO); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glDepthFunc(GL_LESS); // set depth function back to default
ImGui::Begin("Cube and Lighting"); // Create a window called "Cube and Lighting" and append into it.
ImGui::Text("Here can be adjust some params of the sence."); // Display some text (you can use a format strings too) ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::SliderFloat("ambientStrength", &ambientStrength, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::SliderFloat("specularStrength", &specularStrength, 0.0f, 1.0f);
ImGui::ColorEdit3("Cube color", (float*)&objectColor); // Edit 3 floats representing a color ImGui::Text("Cube color = %f, %f, %f", objectColor.x, objectColor.y, objectColor.z);
if (ImGui::Button("Button")) counter++;// Buttons return true when clicked (most widgets return true when edited/activated)
// an example of something we will control from the javascript side bool background_is_black = true;
// the function called by the javascript code extern"C"void EMSCRIPTEN_KEEPALIVE toggle_background_color(){ background_is_black = !background_is_black; }
// Create and compile the vertex shader unsignedint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexSource, nullptr); glCompileShader(vertexShader);
// Create and compile the fragment shader unsignedint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentSource, nullptr); glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program unsignedint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glUseProgram(shaderProgram);
// Specify the layout of the vertex data unsignedint posAttrib = glGetAttribLocation(shaderProgram, "position");
PS C:\Users\dionysen\test\hello> xmake project -k compile_commands checking for platform ... windows checking for architecture ... x64 checking for Microsoft Visual Studio (x64) version ... 2022 checking for Microsoft C/C++ Compiler (x64) version ... 19.37.32825 create ok!
float x = (2.0f * Input::GetMouseX()) / app.GetWindow().GetWidth() - 1.0f; float y = 1.0f - (2.0f * Input::GetMouseY()) / app.GetWindow().GetHeight(); // Mouse always in z plane, so z === 1.0 float z = 1.0f;
● clash.service - A rule based proxy in Go for shitao. Loaded: loaded (/usr/lib/systemd/system/clash.service; disabled; vendor preset: disabled) Active: failed (Result: exit-code) since Tue 2019-06-18 17:27:18 CST; 4s ago Process: 6777 ExecStart=/usr/bin/clash (code=exited, status=203/EXEC) Main PID: 6777 (code=exited, status=203/EXEC)
Jun 18 17:27:18 localhost.localdomain systemd[1]: Started A rule based proxy in Go for shitao.. Jun 18 17:27:18 localhost.localdomain systemd[6777]: clash.service: Failed to execute command: Permission denied Jun 18 17:27:18 localhost.localdomain systemd[6777]: clash.service: Failed at step EXEC spawning /usr/bin/clash: Permission denied Jun 18 17:27:18 localhost.localdomain systemd[1]: clash.service: Main process exited, code=exited, status=203/EXEC Jun 18 17:27:18 localhost.localdomain systemd[1]: clash.service: Failed with result 'exit-code'.
#进入Yporaject项目 cd Yporaject #运行编译命令 cargo build #查看二进制是否生成,程序名称为 node_inject ls target/debug #尝试运行该二进制程序 cargo run output: no node_modules.asar found move me to the root of your typora installation(the same directory as executable of electron)
📚 Notes and personal understanding of the process of learning C language, used to find.
+
+
+
+
+
+
Introduction
+
Our daily life has become inseparable from computers. Whether you are using computers or not, you are using computers consciously or unconsciously, or using the services that computers provide for you. When we are in the use of computer, we are all in the use of computer has some software, so we will go to find the APP, if you searched all the APPs on the market, is there no have the functionality of the APP you want, then you have to write their own one, if you want to do something special, you can’t find the right software, will still have to write their own one. Learning programming is not about writing software for yourself. It is about learning programming to understand how computers work, what they can or are good at doing, what they can’t or aren’t good at doing, and how computers solve problems.
+
+
—— Weng Kai
+
+
+
+
Get started
Framework
#include"stdio.h" intmain() {
return0; }
+
+
Any programs programed by C language must have this framework.
+
Output function
You can understand it as function in math, which is a mapping relationship. But they are different.
+
printf is a function, whoes function is output a string by formating printf("......\n") .
+
For example, the Hello, world! :
+
#include"stdio.h" intmain() { printf("Hello,world!\n"); // \n make it wrapping return0; }
+
+
printf can print not only a string, but also the value of the variable, but you need to format the variable.
+
Variables and constants
+
The computer carries on the computation, then participates in the computation is the number, participates in the computation in the C language the number is called the quantity, the quantity divides into the variable and the constant. Use decimal for expression of daily life, because is advantageous for the calculation of the human brain, a computer internal use binary, for convenience of computer calculation, and the computer expression, as a result of bytes in computer internal frequency is higher, if you can use a simple way to express its inner meaning accurately, Will bring us a lot of convenience, so often use hexadecimal expression. But the number itself remains the same no matter which way it is counted.
+
+
Constants
As the name implies, an invariant quantity that, once initialized, cannot be changed.
+
Variables
As the name implies, a variable quantity that, once defined, can be assigned any value to change its size.
+
The way of difination:
+
int i; int j = 1; char k; float h = 1.2; double g = 2.0;
+
+
For example, i is the variable itself, int is an integer variable, whose value can only be an integer, while double is a double-precision floating point number, which can represent a decimal.
+
Different variable types have different value types and value ranges.
+
Character variables:
+
Use to store character constants. A character variable can hold onlyone character constant. The type specifier is char.
+
#include<stdio.h> intmain() { char x,y,z; x = 'b'; y = 'o'; z = 'y'; printf("%c%c%c\n",x,y,z); return0; }
+
+
The result is:
+
boy
+
+
The literal value of a character variable is independent of the character constant it holds, analogous to an integer variable.
+
Character variables can also store integer data, which is universal. You can change %c to %d during input and output.
+
Output and input of a variable
Output
As mentioned above, printf can print a string, and can print the value of a variable, as shown in the following example:
+
#include"stdio.h" intmain() { int i = 1; printf("i = %d\n",i); i = 2; printf("After assignment,i = %d\n",i); return0; }
+
+
Notice that printf prints the value of the variable with a %d inside the double quotes, which is the way the variable is formatted.
+
%d indicates that the output variable is an integer.
+
+
+
+
Variable Types
+
Formatting Symbols
+
+
+
+
int
+
%d
+
+
+
unsigned
+
%u
+
+
+
long long
+
%ld
+
+
+
unsigned long long
+
%lu
+
+
+
float
+
%f
+
+
+
double
+
%lf
+
+
+
You can use scientific notation when you output, and use %e for formatting symbol.
+
printf("%.nf",sum);
+
+
This line of code can preserve n decimal places.
+
The following are escape characters:
+
+
+
+
Symbols
+
Words
+
中文含义
+
+
+
+
\b
+
backspace
+
回退一格
+
+
+
\t
+
tab
+
下一个制表位
+
+
+
\n
+
new line
+
换行
+
+
+
\r
+
return
+
回车
+
+
+
\f
+
f
+
换页
+
+
+
Input
Similarly, the function scanf can read the input according to a certain format.
+
#include<stdio.h> intmain( ) {
char str[100]; int i;
printf( "Enter a value :"); scanf("%s %d", str, &i);
scanf() stops reading a string as soon as it encounters a space, so “this is test” is three strings for scanf().
+
Floating point numbers
In mathematics, the numbers on the number line are continuous, and between any two different points, an infinite number can be found, but this is difficult to achieve in computers, so floating point numbers emerged.
+
Floating point numbers are used to represent fractional numbers between whole numbers, but their accuracy is not infinite, nor is their expressability infinite, so a random decimal may not be able to be expressed by a computer.
+
Operation
Operator
+
+
+
Mathematics
+
Add
+
Substract
+
Multiply
+
Divide
+
Remainder
+
+
+
+
C Language
+
+
+
-
+
*
+
/
+
%
+
+
+
Relational operator
+
+
+
Relation
+
Equal
+
Not Equal
+
Greater
+
Greater or Equal
+
Less-than
+
Less-than or Equal
+
+
+
+
Operator
+
==
+
!=
+
>
+
>=
+
<
+
<=
+
+
+
The relational operator evaluates only zeros and ones.
+
Special operator
count ++ and ++ count both mean to add one, but a = count ++; means to assign the value of count to a and then add one, whereas a = ++count; means to add one to the value of count and then assign the result to a. So you end up adding one to count in both cases, but the value of a differ by 1.
+
count -- and -- count in the same way.
+
, is comma operator that generally has only one purpose: to add multiple conditions to an if statement.
We can add else, so we can do something if the condition doesn’t work.
+
The else always matches the nearest if.
+
while
while (<#condition#>) { <#statements#> }
+
+
The loop continues until the condition fails.
+
dowhile
do { <#statements#> } while (<#condition#>);
+
+
The loop continues until the condition fails.
+
The difference with a while loop is that a dowhile does something and then evaluates the condition, whereas a while evaluates the condition and then loops. While might not do a loop at all, if the condition is not satisfied in the first place.
+
switch
switch (<#expression#>) { case <#constant#>: <#statements#> break; case <#constant#>: <#statements#> break; ...... default: break; }
+
+
switch is judgment statement, the <#expression#> is constant expression that must be a integral type or enum-type.
+
The essence of such a statement is the program evaluates this expression and then compares it to each case at a time. The action after the case is executed when equal.
+
There are an infinite number of cases, each followed by a value to be compared with and a colon.
+
The variables to be compared must be of the same type.
+
When all the case is false, the program will do the action after default . So there can be nothing after defalut.
for (<#initialization#>; <#condition#>; <#increment#>) { <#statements#> }
+
+
for loop applies to loops with a defined number of cycles, such as traverse.
+
There are three sections in parenthesis, separated with semicolons, which are respectively initialization, conditions for loop to proceed and actions to be performed in each cycle.
+
Miscellaneous
+
+
+
Key words
+
Implication
+
+
+
+
Inf
+
Infinity
+
+
+
-Inf
+
Negative infinity
+
+
+
nan
+
Invalid number
+
+
+
fabs(<#expression#>)
+
Absolute value
+
+
+
break
+
Jump out of the loop
+
+
+
continue
+
End the cycle
+
+
+
Function and customizing function
At the beginning of C language program, the implication of #include <stdio.h> is including a function library named stdio.h and then the program can call functions in the library. Both the printf and the scanf used in the previous paragraph are functions of the library.
+
In practice, we often encounter repeated operations, we can copy this code to complete the repeated action, but code copy is a poor quality of the program, because the maintenance may need to change too many places.
+
You can solve this problem by customizing functions:
+
<#type#> (<#type#>,<#type#>,……){ <#statement#> return0; //Depends on the function type,Also visable as:return; }
+
+
+
A function can have multiple return or none. However, multiple return are not recommended for easy modification.
+
+
Each function has its own variable space, namely {} (block), which is independent of each other. Local variables are limited by the block they are in. If the inside of a block has the same name as the outside of a block, the inside of a block takes precedence.
+
+
When a function is called, it can only pass values to functions, not variables to functions. That is, after passing a variable to a function, the function will read the value of the variable for operation, but will not change the value of the variable.
+
+
The first line of a function with a semicolon placed before the entire program code is called a function prototype declaration. The purpose is to tell the compiler what type the function is before it encounters it.
+
+
+
Array
Defination
+
type of variables + character + [number of variables]
+
+
For example:
+
int a[10];
+
+
An array is a container that, once created, cannot be resized, is internally ordered, and can appear on both sides of an assignment symbol.
+
The index of an array is counted from 0.
+
You can think of it as a sequence in mathematics.
+
Use
Integration initialization is easy to use:
+
int a[3] = {1,3,5,}; int a[13] = {[0]=2,[3]=5,6,7,[9]=0,}; //(C99 only)
+
+
If you don’t know how many cells there are in an array, you can use sizeof(a)/sizeof(a[0]) to represent the number of cells in the array, so that you don’t need to change the number of cells in the array.
+
Multidimensional array
A multidimensional array is actually a multidimensional matrix, and the footer increases accordingly.
+
Initialization:
+
int a[][5] = { {0,1,2,3,4}, {2,3,4,5,6}, }
+
+
The number of columns must be given and the number of rows can be counted by the compiler itself.
+
Pointer
Address
Each variable has an address in the computer where it is stored. The value of a variable can change, but its address is constant. The following code can be used to view the address of a variable.
+
int i = 1; printf("%d\n",&i);
+
+
& is the address to access the variable;
+
* is the variable on the access address.
+
Defination
A pointer is a variable, but it cannot be used independently. It must point to a variable. In this case, the value of the pointer variable is the address of the variable to which it points.
+
Use
int *p = &i;
+
+
In this case, p is a pointer to the address of variable i. So the value of p is the address of i, and the value of i can be accessed (read and write) by *p.
+
The * at definition is not the same as the * at access, and the first is only used to distinguish whether a pointer variable or a normal variable is being defined.
+
Here is an example of using a pointer to complete a call to exchange the values of two variables.
+
#include<stdio.h> voidexchange(int *a,int *b) { int i = *a; *a = *b; *b = i; } intmain() { int a = 5; int b = 6; exc(&a, &b); printf("a = %d,b = %d\n",a,b);
return0; }
+
+
This is a clever use of the function, we know that the function cannot input variable parameters, so this code defines the address of the pointer to the variable, the function input pointer variable is also the address of the variable, inside the function by adding a pointer to access the variable, and then achieve the purpose of the function to modify the variable.
+
+
In addition, pointers are often used when a function needs to return multiple values.
+
+
Arrays are special Pointers
#include<stdio.h> intmain() { int a[] = {1,2,3,}; printf("%p\n",a); return0; }
+
+
The result of this code is:
+
0x7ffcac420c3c
+
+
We can see that the array variable a is itself an address, so when we want to use a pointer to array a, we should write int *p = a, without &. But the array unit is variable, therefore int *p = &a[0], at the same time, a == &a[0],&a[x] == &a[0] + 4x = a + 4x(when a is integer).
+
An array is a pointer to a constant and therefore cannot be assigned.
+
Pointer to a constant (const)
int i; intconst *p = &i; // 1 int *const p = &i; // 2
+
+
For the above code, you can think of the following code:
+
int i; intconst(*p) = &i; // 1 int *(const p) = &i; // 2
+
+
1 indicates that the variable at the address pointed to by the pointer p cannot be modified by the pointer.
+
2 indicates that the address (variable’s address certainly) pointed to by p cannot be changed.
+
+
The first whole to the right of const cannot be modified
+
+
constint a[] = {1,2,3,};
+
+
The above code indicates that each cell is const, so it can be used to protect an array when a function argument is entered.
+
Address of a pointer
int a[]; int *p = a;
+
+
*p = a = a[0],
+
*(p+1) = a[1],
+
*(p+2) = a[2],
+
……,
+
*(p+n) = a[n].
+
Allocating Memory Space
The malloc function applies space in bytes from memory, returns void *, converts the desired type, and finally frees the memory. Format, such as:
+
int a[n] = (int *)malloc(n * sizeof(int));
+
+
If the application fails, 0 or NULL is returned.
+
When you no longer use the requested memory space, you should use the free function to free the memory space:
+
free(a[n]);
+
+
String
Overview
Char word[] = {'H','D','e','!'};
+
+
Such an array is an array of characters, but it is not a string, because it cannot be evaluated as a string.
+
Char word[] = {'H','D','e','!','\0'};
+
+
Followed by \0, then word is a string.
+
0 = '\0' != '0'
+
0 marks the end of the string, but this 0 is not part of the string.
+
Strings exist as Arrays and are accessed as arrays or Pointers, but more often as Pointers.
+
string.h has a number of functions that handle strings.
The compiler will turn this into an array of characters somewhere, and the length of the array is 6, because the compiler will put a 0 after it to make it a string.
+
Literals of strings can be used to initialize character arrays.
&i = 0x7fffa827bcf4 s = 0x55c7d8f64004 s2 = 0x55c7d8f64004 Here is s[0] = h Here is s3[0] = h
+
+
You can see that the local variable i is far from where the pointer s is pointing. The address of the variable i is very far back, and the pointer is very far forward. Near the front are important parts of the computer that are not allowed to be modified, such as plus s[0] = 'B' ‘, and the result is:
+
1869 segmentation fault ./a.out
+
+
The program attempted to reassign the initialized string s. The error “segmentation fault“ was reported, meaning that the program was attempting to rewrite the value at 0x55c7d8f64004, which posed a threat to the computer and was not allowed.
+
In fact, for char *s = "hello world"; pointer s is initialized to point to a string constant, which should actually be const char *s = "hello world";, but for historical reasons, compilers accept writing without const, and try to modify the string to which s refers, with serious consequences.
+
s3 is an array, and the strings inside are local variables that can be modified, plus S3[0] = 'b':
+
&i = 0x7fff28d5dd64 s = 0x559da8ac6004 s2 = 0x559da8ac6004 Here is s[0] = h Here is s3[0] = b
+
+
There are two ways to define a string: pointer or array.
+
Arrays know the address of strings, Pointers don’t.
+
A char * or int * is not necessarily a string. It is meant to be a pointer to a character or an array of characters.
+
A char * or int * is a string only if the array of characters to which the pointer points has a zero at the end.
+
char *t = "title"; char *s; s = t;
+
+
For the above code, we have two Pointers, t and s. First, t points to the string “title”, and then we assign a value to s. The result is that s also points to the same string, instead of creating a new string.
+
Input and output of string
For printf and scanf, you can use %s to input and output strings.
+
Each %s in scanf is read until a SPACE or ENTER, which is not safe because you do not know exactly how many characters to read, therefore, the following code is used:
+
char s[8]; scanf("%7s",s);
+
+
Array of strings
char a[][10]; char *a[];
+
+
The first line refers to a as a two-dimensional array, and the second line refers to a as a pointer array. Each unit in the array is a pointer to a string.
+
Each element of the character array holds one character, plus the 0 at the end. An array of length n can hold n-1 characters.
+
Multiple loops are required to input and output all elements of multiple dimensions, whether string arrays or integer arrays.
+
An array is a matrix that can be used to store variables or character variables. All input and output need to be looped, but there are two types of input and output for character arrays.
+
Input and output single characters in format %c
#include<stdio.h> intmain() {
int x,i,j; char a[][20] = { "", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", }; printf("Please input the month:\n"); scanf("%d",&x); if (x > 0 && x < 8) { for (i = x ; i < x + 1; i ++) { for (j = 0; j < 20; j ++) { printf("%c",a[i][j]); } } } elseprintf("Error"); printf("\n"); return0; }
+
+
Input and output whole array with format %s
#include<stdio.h> intmain() { int x,i,j; char a[][20] = { "", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", }; printf("Please input the month:\n"); scanf("%d",&x); if (x > 0 && x < 8) { printf("%s",a[x]); } elseprintf("Error"); printf("\n"); return0; }
+
+
+
Note that input characters with %s that encounter a SPACE, RNTER, and TAB end the string input, so C provides the input function gets() and the output function puts() that are best for strings.
+
+
gets(char *s[]) function is to enter a string from the keyboard that can contain Spaces and end with a ENTER newline character.
+
puts(char *s[]) or puts(string s)function prints a string from the character array to the screen and converts the end-of-string flag to a newline character.
+
In addition, when %s prints a string, it keeps one dimension, and the compiler automatically inputs or outputs all strings in that dimension. Gets is the same as puts.
+
Input and output of character data
Putchar(parameter)
Paremeters can be numerical values, character constants, character variables, and arithmetic or character expressions, but the final output is a character.
So strlen is string Length, which returns the length of the string.
+
strcmp
The function is to compare the size of two strings, and the result of the comparison is expressed by the value returned. 0 means they are equal, 1 means the former greater, and -1 means the latter greater.
Its function is to copy the src string to dst. restrict means that src and dst cannot overlap. The source is in the back, and the copying destination is in the front. Return dst so that the function itself can be evaluated. General usage:
enumtype {num_0,num_1,num_2,……,num_n, number of type};
+
+
That’s just right. The last number of type is exactly the number of type. It’s a little trick.
+
Data structure
#include<stdio.h> structdate { int day; int month; int year; }; //Structure type Declaration structdate { int day; int month; int year; } today; //This is another form
printf("Today is %i-%i-%i.\n", today.year,today.month,today.day);
return0; }
+
+
This means that you declare a data structure type, and when you use it, you define a variable that contains all the variables in the data structure.
+
The structure members of a data structure do not have to be of the same variable type, and an array can only be of one type.
+
Data structures can perform structure operations .
+
Assigning values to or between structure variables is a one-to-one correspondence; the former requires curly braces.
+
The name of the structure variable is not the address of the structure variable, so you need to define the pointer using &.
+
A data structure can be entered as a function parameter, but unlike an array, the entire structure is passed into the function as the value of the parameter, creating a new structure variable inside the function and copying the value of the caller’s structure.
+
You can also return a struct.
+
Custom data types
A typedef can give an alias to a data type.
+
typedeflongint64_t; typedefstructADate { int month; int day; int year; } Date;
int64_t i = 100000000000; Date d = {9, 1, 2005, };
+
+
Union
带参数的宏一定要有括号,结尾不能加分号。
+
+
+
+
+
+
+
+
+
+ Post title: C Language
+
+
+ Post author: Dionysen
+
+
+ Create time: 2022-05-25 17:34:01
+
+
+ Post link: 2022/05/25/note/Computer/Programming/Language/C/
+
+
+ Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.
+
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
Heading 2
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
Heading 3
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
Heading 4
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
Heading 5
Array has fixed size and contiguous memory. New elemenots cannot be appended. You can use memory address to access elements of Array.
+
Heading 6
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array. 这是粗体 这是斜体 这是粗斜体 dasdad The .mdonly be used to open Note files in Typora.
+
+
And it is a sample now!
+
+
#include<iostream> da
+
+
+
+
+
Command
+
Full name
+
Do somthing
+
+
+
+
gdb output
+
+
+
+
+
r
+
run
+
Run current program
+
+
+
b
+
break
+
Set a breakpoint at [function] or [line] (in file)
Array has fixed size and contiguous memory. New elements cannot be appended. You can use memory address to access elements of Array.
+
char a[5] = {'h', 'e', 'l', 'l', 'o',};
+
+C++ counts food tags from `0`, so `a[0] = 'h'` and `a[1] = 'e'`.
+Random access using `a[i]` has `O(1)` time complexity.
+Units of array can be modified.
+
a[0] = 'b';
+result:
+
bello
+
+### Dynamic Allocation of Arrays
+
+
A size-n array can be created in this way:
+
char a[n];
+
+
But when writing the code, n must be known.
+
If n is unknown, how dose the program run?
+
char* a = NULL; int n; // array size cin >> n; // read in the size. e.g., get n = 5 a = newchar[n];
+
+
Now a is an empty array whose size is 5.
+
// store somrthing in the array a[0] = 'h'; a[1] = 'e'; a[2] = 'l'; a[3] = 'l'; a[4] = 'o';
+
+
When done, free memory. Otherwise, memory leak can happen.
+
delete [] a; a = NULL;
+
+
+
+
Removing an element in the middle has O(n) time complexity. Require moving the remaining items leftward.
+
Vector
Vector is almost the same as array.
+
The main difference is that vector’s capacity can automatically grow.
+
New elements can be appended using push_back() in O(1) time(on average).
+
The last element can be removed using pop_back() in O(1) time.
When size is going to exceed capacity, program will create a new array of capacity 200, copy the 100 elements from the old array to the new, put the new element in the 101st position and free the old array from memory.
+
List
A Node
A node contains a data and two pointers that one points to the previous node and another points to the next node.
+
Doubly Linked List
std::list<char> l = {'h', 'e', 'l', 'l', 'o'};
+
+
cout << l[2]; // does not work l[0] = 'a'; // does not work
The ascending order must be kept; otherwisem search would take O(n) time. Inserting an item into the middle has O(n) time complexity(on average). Can we perform binary search in the list? No, Given left and right, we cannot get mid efficiently.
+
+
+
+
+
Search
+
Insertion
+
+
+
+
Vector
+
O(log n)
+
O(n)
+
+
+
List
+
O(n)
+
O(1)
+
+
+
Skip List
+
O(log n)
+
O(log n)
+
+
+
Skip List
Linked list does not support binary search.
+
+
Skip list allows fast search and fast inertion.
+
+
Search:O(log n) time complexcity on average.
+
Insertion:O(log n) time complexcity on average.
+
Build a skip list(待补充)
Initially, a linked list contains n numbers in ascending order.
+
Search
Insertion
+
+
+
+
+
+
+
+
+ Post title: Data Structure
+
+
+ Post author: Dionysen
+
+
+ Create time: 2023-05-25 17:34:01
+
+
+ Post link: 2023/05/25/note/Computer/Programming/Algorithm and Data structure/DataStrucuture_en/
+
+
+ Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.
+
There are three ways to create a pointer head. Using first way, you can create a pointer head pointing to a node that has a variable val = 0 and a nullptr (a pointer pointing nothing). And the second way, you create a same head but you must assign a value to val of the node pointed to by head. The last, you even can link a node to the head requiring you give a pointer pointing to the next node.
It uses ssh for data transfer, and uses the same authentication and provides the same security as a login session.
+
scp will ask for passwords or passphrases if they are needed for authentication.
+
The source and target may be specified as a local pathname, a remote host with optional path in the form [user@]host:[path], or a URI in the form scp://[user@]host[:port][/path].
+
+
Local file names can be made explicit using absolute or relative pathnames to avoid scp treating file names containing ‘:‘ as host speacifiers.
+
+
When copying between two remote hosts, if the URI format is used, a port cannot be specified on the target if the -R option is used.
+
+
+
+
Options
+
Implication
+
+
+
+
-3
+
Copies between two remote hosts are transferred through the local host. Without this option the data is copied directly between the two remote hosts.
+
+
+
-4
+
Forces scp to use IPv4 addresses only
+
+
+
-6
+
Forces scp to use IPv6 addresses only
+
+
+
-A
+
Allows forwarding of ssh-agent(1) to the remote system. The default is not to forward an authentication agent.
+
+
+
-C
+
Compression enable
+
+
+
-l
+
Limits the used bandwidth, specified in Kbit/s
+
+
+
+
+
+
+
+
+
+
+
+ Post title: SCP protocol
+
+
+ Post author: Dionysen
+
+
+ Create time: 2023-05-25 17:34:01
+
+
+ Post link: 2023/05/25/note/Wiki/SCP/
+
+
+ Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.
+
deb https://mirrors.ustc.edu.cn/termux/apt/termux-main stable main
+
+
debian
deb http://mirrors.ustc.edu.cn/debian stable main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable main contrib non-free deb http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-updates main contrib non-free
# deb http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free # deb-src http://mirrors.ustc.edu.cn/debian stable-proposed-updates main contrib non-free
+
+
archlinux
Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch
# arm Server = https://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo
+
+
ubuntu
# 默认注释了源码仓库,如有需要可自行取消注释 deb https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-backports main restricted universe multiverse
# 预发布软件源,不建议启用 # deb https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse # deb-src https://mirrors.ustc.edu.cn/ubuntu/ focal-proposed main restricted universe multiverse
+
+
kali
supported:amd64, armel, armhf, i386
+
deb https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
+
+
+
+
+
+
+
+
+
+ Post title: Source Lists
+
+
+ Post author: Dionysen
+
+
+ Create time: 2023-05-25 17:34:01
+
+
+ Post link: 2023/05/25/note/Wiki/Source List/
+
+
+ Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.
+
LxRunOffline i -n <自定义名称> -f <Arch镜像位置> -d <安装系统的位置> -r root.x86_64
+
+
example:
+
LxRunOffline i -n ArchLinux -f C:\Users\dionysen\Downloads\archlinux-bootstrap-2020.10.01-x86_64.tar.gz -d C:\Users\dionysen\Linux -r root.x86_64
+
+
2. Change WSL2 version in Archlinux
wsl --set-version ArchLinux 2
+
+
Configuration
Basic Configuration
wsl -d Archlinux rm /etc/resolv.conf exit
+
+
The terminal window will be unavailable, so you should reopen a new terminal window, then:
+
wsl --shutdown Archlinux wsl -d Archlinux cd /etc vi pacman.conf
+
+
Add following code in the end of pacman.conf:
+
[archlinuxcn] Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
+
+
And change the mirrorlist:
+
vi ./pacman.d/mirrorlist
+
+
Remove the comment of a Chinese source.
+
pacman -Syy pacman-key --init pacman-key --populate pacman -S archlinuxcn-keyring pacman -S base base-devel vim git wget
passwd # input the password of root useradd -m -G wheel -s /bin/bash <username> passwd <username> vim /etc/sudoers
+
+
Use /wheel find the line wheel ALL=(ALL) ALL and remove the comment.
+
id -u <username> exit
+
+
Execute the command in powershell to set default user of Archlinux:
+
lxrunoffline su -n Archlinux -v <username>
+
+
Install Ubuntu20.02 in WSL2
wsl --list--online# 查看可直接安装的发行版列表 # 显示如下: PS C:\Windows\system32> wsl -l--online The following is a list of valid distributions that can be installed. Install using'wsl.exe --install <Distro>'.
NAME FRIENDLY NAME Ubuntu Ubuntu Debian Debian GNU/Linux kali-linux Kali Linux Rolling SLES-12 SUSE Linux Enterprise Server v12 SLES-15 SUSE Linux Enterprise Server v15 Ubuntu-18.04 Ubuntu 18.04 LTS Ubuntu-20.04 Ubuntu 20.04 LTS OracleLinux_8_5 Oracle Linux 8.5 OracleLinux_7_9 Oracle Linux 7.9
# 安装ubuntu 20.04 wsl --install Ubuntu-20.04
+
+
然后打开终端,打开ubuntu-20.04,创建用户和密码
+
换源+更新
+
然后安装anaconda
+
Install Anaconda on Ubuntu
wget https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-5.3.0-Linux-x86_64.sh chmod +x Anaconda3-5.3.0-Linux-x86_64.sh ./Anaconda3-5.3.0-Linux-x86_64.sh yes ENTER
Vim using Coc-nvim plugin clangd-lsp need to read CMakeLists.txt so that it can auto-complete your code. If your project builds with CMake, it can generate this file. You should enable it with:
+
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1
+
+
compile_commands.json will be written to your build directory. If your build directory is $SRC or $SRC/build, clangd will find it. Otherwise, symlink or copy it to $SRC, the root of your source tree.
In Greek mythology, Apollo and Dionysus are both sons of Zeus. Apollo, son of Leto, is the god of the sun, art, music, poetry, plague and disease, of rational thinking and order, and appeals to logic, prudence and purity and stands for reason. Dionysus, son of Semele, is the god of wine, dance and pleasure, of irrationality and chaos, representing passion, emotions and instincts. The ancient Greeks did not consider the two gods to be opposites or rivals, although they were often entwined by nature.
+
“he glimpsed the supernatural reality through the Ghost; he has gained true knowledge and knows that no action of his has the power to change this. For the audience of such drama, this tragedy allows them to sense what Nietzsche called the Primordial Unity, which revives Dionysian nature. He describes primordial unity as the increase of strength, the experience of fullness and plenitude bestowed by frenzy. Frenzy acts as intoxication and is crucial for the physiological condition that enables the creation of any art.[citation needed] Stimulated by this state, a person’s artistic will is enhanced:
+
+
In this state one enriches everything out of one’s own fullness: whatever one sees, whatever wills is seen swelled, taut, strong, overloaded with strength. A man in this state transforms things until they mirror his power—until they are reflections of his perfection. This having to transform into perfection is—art.”
It is this intellectual activity of inquiry, seeking, rather than summative answers, that make one a philosopher, because summative answers can easily be reduced to unthinking dogmas and slogans that require no thought or understanding at all.
Vim using Coc-nvim plugin clangd-lsp need to read CMakeLists.txt so that it can auto-complete your code. If your project builds with CMake, it can generate this file.
+
+