Command substitution allows the output of a command to replace the command itself in a shell script or command line.
Example:
echo "Today is $(date)"
echo "Nested: $(echo $(date))"
如果需要巢狀的情況,用 ` 會混淆,用 $() 會比較好
-
: dash, minus+
: plus, sign_
: underscore`
: backtick 或 backquote'
: single quote"
: double quote{
: curly brace 或 brace[
: square bracket 或 bracket(
: parenthesis 或 round bracket!
: exclamation mark, NOT, reverse~
: tilde, bitwise not?
: question mark:
: colon#
: hash 或 pound&
: ampersand^
: caret, XOR*
: asterisk 或 star=
: assign==
: comparison/
: slash\
: backslashapt
跟 apt-get
的差別sources:
apt
and apt-get
are command line tools. You can use them to manage software packages like applications and libraries on Debian-based Linux servers and server instances.apt-get
and apt
are the system default.apt
command line tool provides a higher-level user interface for end users with intuitive commands, resulting behaviors, and security features. In contrast, the command apt-get
is a low-level interface that communicates more closely with core Linux processes.apt
command is a more user-friendly package manager than apt-get
.In 1998, apt-get
was released with the Debian 2.0 (Hamm) distribution, while apt
was released in 2014 with the Debian 8 (Jessie) distribution. After 2014, apt
replaced apt-get
as the default package manager tool for all Debian-based Linux distros.
Search for a package by name by using the apt search <package_name>
command. This command gives a detailed description of all packages containing the searched package_name. This operation was not possible with apt-get
. Instead you had to use the apt-cache
command.
Any software package typically comes with a list of software dependencies, such as libraries or tools it needs to operate correctly. You have to install all dependencies before you can install the package.
Both apt
and apt-get
handle dependency resolution, however apt
is far superior. It determines complex dependency chains where it installs packages in the correct order and recommends suggested packages to install.
By default, the apt
upgrade command removes old versions of installed or upgradeable packages on the system that are no longer needed when upgrading. In contrast, the apt-get
upgrade command does not. This efficiency can make apt
upgrade better for freeing up system memory.
Both apt-get
and apt
print status information to the terminal, giving insight into what the system is doing after the input command. The apt
command provides slightly more detailed information to the user, including a progress bar on each task.
某些命令,像是 search, show, policy,apt-get
必須搭配 apt-cache
才能使用,而在 apt
中可以直接使用
可以說 apt
是 apt-get
的進階版工具
太久沒用每次都不知道怎麼寫
sources:
%
: wildcard pattern:=
: append assignment?=
: assignment operator; if not define, then define itdir
: 取得檔案的 directorywildcard
patsubst
: $(patsubst %.c, %.o, <SRC>)addprefix
addsuffix
$@
: target files$^
, $|
, $~
, $+
, `` : all dependencies / prerequisite$?
: all dependencies newer than target$<
: first dependency / prerequisite$*
: stem of target$%
: target member nameifeq (), ifneq (), endif
$(warning) , $(error)
$(shell <command>)
只給基本範例,如果有多個 header files 或是其他 libraries 要一起編譯,再自己查資料
# C
CC = gcc
CC := $(CC) -std=c99
CFLAGS = -Wall -Wextra -O2 -g
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)
OUT = a.out
# phony targets; indicate some targets that are not files
.PHONY: all clean
all: $(OUT)
$(OUT): $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJ) $(OUT)
# CPP
CC = g++
CC := $(CC) -std=c++11
CFLAGS = -Wall -g -O2
SRC = $(wildcard *.cc)
OBJ = $(SRC:.cc=.o)
OUT = a.out
.PHONY: all clean
all: $(OUT)
$(OUT): $(OBJ)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.cc
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJ) $(OUT)
sources:
-MMD
See references:
.o
files are already present, and you've changed a .h
file. The first time you run Make, all .o
files will need to be built anyway, and the .d
files are generated at the same time..d
files will give dependency information. If a header is changed, the dependency information will tell Make which .o
files need rebuilding. If a source file is changed, the .o
will always need to be rebuilt, and updated dependency information will be generated at the same time.-
-std=<standard>
-ansi
: Same as -std=c89
See references:
可以
man clang
或man gcc
來看
Supported values for the C language are:
c89
c90
iso9899:1990
ISO C 1990
iso9899:199409
ISO C 1990 with amendment 1
gnu89
gnu90
ISO C 1990 with GNU extensions
c99
iso9899:1999
ISO C 1999
gnu99
ISO C 1999 with GNU extensions
c11
iso9899:2011
ISO C 2011
gnu11
ISO C 2011 with GNU extensions
c17
iso9899:2017
ISO C 2017
gnu17
ISO C 2017 with GNU extensions
The default C language standard is gnu17, except on PS4, where
it is gnu99.
Supported values for the C++ language are:
c++98
c++03
ISO C++ 1998 with amendments
gnu++98
gnu++03
ISO C++ 1998 with amendments and GNU extensions
c++11
ISO C++ 2011 with amendments
gnu++11
ISO C++ 2011 with amendments and GNU extensions
c++14
ISO C++ 2014 with amendments
gnu++14
ISO C++ 2014 with amendments and GNU extensions
c++17
ISO C++ 2017 with amendments
gnu++17
ISO C++ 2017 with amendments and GNU extensions
c++20
ISO C++ 2020 with amendments
gnu++20
ISO C++ 2020 with amendments and GNU extensions
c++23
ISO C++ 2023 with amendments
gnu++23
ISO C++ 2023 with amendments and GNU extensions
c++2c
Working draft for C++2c
gnu++2c
Working draft for C++2c with GNU extensions
The default C++ language standard is gnu++98.
-Wall
-Wextra
-w
(小寫 w)-Werror
-Werror=switch
-Wfatal-errors
-Wformat-security
-Wfloat-equal
-Wdiv-by-zero
-Wshadow
-Wmissing-prototypes
-O2
-O2
包含了大多數的 optimization flag,不過有一些例外,像是 -ffast-math
(因為這可能會導致結果有誤差)或是 -funroll-loops
(因為這會讓執行檔案大小變大很多,但卻不保證能夠加速編譯速度)-O3
: 開啟 level 3 的最佳化編譯,通常會比 -O2
再快一點(編譯速度)-O3
不保證一定會比 -O2
更快(編譯速度)-ffast-math
-ffast-math
時,compiler 會把它重新變成 (a*a*a)*(a*a*a),這樣只需要做 3 次乘法,速度就比較快,但也導致結果可能有準確性的問題-funroll-loops
-funroll-all-loops
來強制展開所有迴圈,但開啟這個很有可能反而減慢速度-funroll-loops
不保證一定會加快(執行)速度-march=native
This tells the compiler what code it should produce for the system's processor architecture (or arch); it tells GCC that it should produce code for a certain kind of CPU. Different CPUs have different capabilities, support different instruction sets, and have different ways of executing code. The
-march
flag will instruct the compiler to produce specific code for the system's CPU, with all its capabilities, features, instruction sets, quirks, and so on provided the source code is prepared to use them. For instance, to take benefit from AVX instructions, the source code needs to be adapted to support it.
int g_variable1; /* Static Storage Duration */
int g_variable2 = 5; /* Static Storage Duration */
int g_array[10]; /* Static Storage Duration */
int main() {
static int local_static_variable; /* Static Storage Duration */
return EXIT_SUCCESS;
}
g_variable1 = 0
local_static_variable = 0
g_variable2 = 5
a = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
int main() {
int variable1; /* Automatic Storage Duration */
int variable2 = 0; /* Automatic Storage Duration */
int array1[4]; /* Automatic Storage Duration */
int array2[4] = {1, 2, 3, 4}; /* Automatic Storage Duration */
int array3[4] = {1, 2}; /* Automatic Storage Duration */
{
int i; /* Automatic Storage Duration */
}
/* Now, "i" is dead */
return EXIT_SUCCESS;
}
/* Now, "variable1", "variable2", "array1", "array2" is dead. */
根據第4點
array3 = { 1, 2, 0, 0 }
有時候我們會在宣告的後面加上 int a[3] = {0} 來將整個陣列初始化為 0
不過要注意的是 int a[3] = {10} 並非把所有的元素初始化為 10,只有第一個會是 10,其他的都會是 0。
int main() {
int *my_array = (int *)malloc(sizeof(int) * 10);
free(my_array);
return EXIT_SUCCESS;
}
需要注意的是 my_array 這一個指標本身是屬於 automatic storage duration,是may_array 所指向的變數才是 heap storage duration。
sources:
A character, a short integer, or an integer bit-field, all either signed or not, or an object of enumeration type, may be used in an expression wherever an integer maybe used. If an int can represent all the values of the original type, then the value is converted to int; otherwise the value is converted to unsigned int. This process is called integral promotion.
C 語言中規定
sizeof(char) ≤ sizeof(short) ≤ sizeof(int)
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if (a == 0xb6); // false
if (b == 0xb600); // false
if (c == 0xb6000000); // true
unsigned int + signed int 會被 promoted 成 unsigned
unsigned int a = 6;
int b = -20;
(a + b > 6) ? puts("big") : puts("small");
// output: big
sources:
char a[] = "string literal";
char *p = "string literal";
A string literal (the formal term for a double-quoted string in C source) can be used in two slightly different ways:
Some compilers have a switch controlling whether string literals are writable or not (for compiling old code), and some may have options to cause string literals to be formally treated as arrays of const char (for better error catching).
sources:
if(p)
to test for non-null pointers valid? What if the internal representation for null pointers is nonzero?null pointers and null pointer constants are formally defined in C17 6.3.2.3/3:
An integer constant expression with the value
0
, or such an expression cast to typevoid *
, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
The macro
NULL
is defined in<stddef.h>
(and other headers) as a null pointer constant
NULL which expands to an implementation-defined null pointer constant
If a pointer is being compared to the constant literal 0
, then this is a check to see if the pointer is a null pointer. This 0
is then referred to as a null pointer constant. The C standard defines that 0
cast to the type void *
is both a null pointer and a null pointer constant.
Here are some valid ways to check for a null pointer:
if (pointer == NULL) // valid
NULL
is defined to compare equal to a null pointer. It is implementation defined what the actual definition of NULL is, as long as it is a valid null pointer constant.
if (pointer == 0) // valid
0
is another representation of the null pointer constant.
if (!pointer) // valid
This if
statement implicitly checks "is not 0", so we reverse that to mean "is 0".
int mynull = 0;
// some code here
if (pointer == mynull) // is an invalid way to check for a null pointer
\0
is defined to be a null character, that is a character with all bits set to zero.\0
is (like all character literals) an integer constant, in this case with the value zero. So \0
is completely equivalent to an unadorned 0 integer constant\0
可以告訴 programmer 說:"我在這裡使用空字元"簡介 Memory Access, cache coherence protocol and memory barrier
Cache Coherency & I/O ordering
What is the difference b/w int (*p) [10] and int *p [10]?
Ch7 Search & Sort
Ch8 Hashing
Ch9 Advanced Tree Structure