1. Linux operating system
(1) Know the Linux operating system
1. Operating system
Definition: Essentially a software program that runs on a computer
Composition: kernel + shell (graphical interface + software tools...)
Role: Provide users with an operation interface and manage computer hardware and software resources.
Mainstream operating systems include Windows, MacOS, Linux
2、GNU/Linux Linux1.0
1. Linux is also known as the Unix-like operating system Minux
2. The characteristics of Linux are free, open source, tailorable, and good portability.
3. Released in 1991 by Linus Torvalds.
4. Strictly speaking, Linux is the kernel of the operating system.
Question 1: What is the relationship between Linux and Unix?
- UNIX is a multi-user and multi-tasking operating system while Linux is a UNIX-based operating system.
- Linux is open source and free to use; Unix is not open source and is an authorized operating system.
- Linux is used more widely from desktops, servers, smartphones to mainframes while Unix is mostly used on servers, workstations or PCs
Question 2. What is the relationship between Linux and GNU?
The Linux operating system is a perfect combination of GNU and the Linux kernel . They all abide by the GPL agreement and belong to open source code. ) GNU is a free software engineering project. GNU software abides by a set of agreements called GPL, which stipulates that GNU software must be open source. .
Question 3. What is the relationship between Linux and Ubuntu?
Linux这个词是指操作系统的内核,ubuntu是指基于这种内核的操作系统,就是在linux这个内核上又加上了一种界面系统,就像你看到的windows的界面一样。. 而因为 Linux是开放源代码的,所以网上会出现各种各样的发行版本,Ubuntu Linux只是其中一种。. Ubuntu采用Linux内核,图形界面采用GNOME(Kubuntu使用KDE)。. 简而言之,Linux系统是个统称,它有RedHat、Debian、Suse、Ubuntu等发行版本,它们都是用的Linux内核,都是Linux系统。. 这两个最大的区别在包管理模式上。.
3、Ubuntu操作系统
终端:命令行解释器
linux @ ubuntu : ~ $
用户名 @ 操作系统名 :当前路径 命令提示符
hqyj@CentOS:~$
/ :根目录
/home :存放所有普通用户主目录
/home/hq :~ 家目录(当前用户主目录)
pwd :查看当前绝对路径
4、Linux文件管理形式
windows:分盘符 C\D\E\F...
linux:倒置树形结构管理文件 FHS标准
根目录:
/bin: 二进制文件,存放普通用户的命令。
/dev: 系统的设备文件,设备驱动程序。
/home:存放用户目录
/lib: 存放与系统运行相关的库文件
/mnt: 挂载目录
/etc: 系统配置文件
/root:超级用户目录
/boot:引导linux启动的核心文件
/lost-found:这个目录平时是空的,当系统非正常关机而留下的“无家可归”的文件便会储存在这里
/misc:储存着一些特殊的字符的定义
/proc:存放着用户与内核的交互信息
/sbin:系统的管理命令,这里存放的是系统管理员使用的程序
/srv: 系统启动服务时可以访问的数据库目录
/tmp: 临时文件,重启后自动清空
/var: 某些大文件的溢出区,比如各种服务的日志文件
/media:存放着可移除的设备,比如软盘,光盘
/opt: (option: free choice) mainly for the location of the installation directory selected when installing the software from the source code
/selinux: Mainly used to strengthen the operating system and improve system security
/sys: manage device files
/usr: the largest directory, storing applications and files
5. User operation
1) User switching
su + username
root : superuser
Linux: normal user
su root: Switch to the root user with administrator privileges.
su linux: switch to linux user
2) Create a user
adduser username//Administrator privileges are required for execution
root@ubuntu:/home/linux# adduserfaright
Adding user `faright' ...
Adding new group `faright' (1002) ...
Adding new user `faright' (1002) with group `faright' ...
Creating home directory `/home/faright' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: //Enter the password for the new user
Retype new UNIX password: //Repeat to confirm the password
passwd: password updated successfully //Password updated successfully Z
Changing the user information for faright //Enter user information
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n] y //Is the information correct? y yes n no
3) Delete user
sudo userdel username: delete user only
sudo userdel -r username: delete user and user directory
//Administrator privileges are required for execution
sudotools
sudo + command: obtain administrator privileges when executing this command
4) Modify user password
sudo passwd username: modify user password
linux@ubuntu:~$ sudo passwd linux
[sudo] password for linux: //Enter the original password
Enter new UNIX password: //Enter the new password
Retype new UNIX password: //Repeat confirmation
passwd: password updated successfully //password updated successfully
6. File operation
1. ls list list
Basic function: list the files in the current path
ls -a : View all files in the current path (including hidden files)
ls -i : View the inode number of the file (each file has a unique identity number)
ls -l : View detailed information about a file
d rwxr-xr-x 8 linux linux 4096 Sep 17 17:02 ARM
[File Type] [File Permissions] [Number of Hard Links] [User Name] [Group Name] [File Size] [Last Modified Date] [File Name]
1) File type (7 types)
- Normal files - .c .txt .zip .exe .bin .jpg .mp3
d directory files - folder
l link file - shortcut
s socket file - network programming
p pipe file - process thread
b block device file
c character device file - driver development
2) File permissions
r : read permission 4
w : write permission 2
x : executable permission 1
- : no permission 0
rwx r-x r-x
[Current User Permissions] [Group Member Permissions] [Other User Permissions]
111 101 101
7 5 5
chmod permission value filename
practise:
Modify the folder permission of Music to be readable, writable and non-executable by the current user,
Members of the group can only read, and other users can write and execute.
-wx r-- -wx
3 4 3
chmod 643 Music
2.cd change directory to change the path
switch path
cd absolute path: start indexing from the root directory
linux@ubuntu:~$ cd /home/linux/Music/
cd relative path: index relative to the current path
linux@ubuntu:~$ cd ./Music
. current path
.. The upper level path (the inode number of .. is the same as the inode number of the upper level path)
3.touch
touch Common file name. Suffix: Create a new normal file
touch 1.c 2.jpg 3.mp3 4.mp4 5.zip : Create multiple files at the same time
Touch creates an ordinary file with the same name and updates the last modification time of the file.
4.mkdir
mkdir directory file name: new directory file
When mkdir creates a directory file with the same name, an error will be reported:: File exists
mkdir -m permission value directory file name: specify permission to create directory file
mkdir -p Folder 1/Folder 2/Folder 3.... : Create a directory with a hierarchical relationship
Default permissions for files:
umask file mask 0002
Default permissions for directory files: 0777 - 0002 = 0775
Default permissions for normal files: 0666 - 0002 = 0664
5.rm
rm ordinary filename: remove ordinary files
rm -r directory file name: delete directory file
rm -rf dir-filename: Force delete write-protected empty dir files
sudo rm -rf dir-filename: Force delete write-protected non-empty dir files
rm *. format: specify to delete a certain type of file * wildcard
rm *.txt : delete all files in txt format
rm * -r : Delete ordinary files and directory files in the current path
sudo rm !(3.txt) -rf : Delete all files except 3.txt
6.cp
cp ordinary file target path: copy and paste ordinary files to the target path
cp normal file new filename: save normal file as new filename
cp -r directory file target path: copy and paste the directory file to the target path
7.mv
mv filename target path: move the specified file to the target path
mv original filename new filename: rename
7. Commonly used shortcut keys
Open a terminal:
ctrl + alt + t : open a new terminal in the home directory by default
ctrl + shift + n : open a terminal at the same path as an open terminal (cursor)
Close the terminal:
ctrl + d
Zoom terminal:
ctrl + shift + “+”
Minified terminal:
ctrl + “-”
Qingping:
ctrl + l
clear command
View historical commands:
up and down keys
Completion:
Tab
8. vi compiler
A command-line based document editor
vi + filename: open the file with vi editor
Three working modes:
Command line mode: text copy, paste, undo, redo, delete...
Insert Mode: TextEdit
Bottom row modes: save, exit, find, replace, split screen...
Working mode switching:
1. Open the document in the command line mode by default
2. In the command line mode, switch to insert mode (insert) through a, A, i, I, o, O
3. First press Esc to return to the command line mode, and switch to the bottom line mode by shift+":"
Command line mode:
Single line copy yy
Multi-line copy nyy (n is the number of lines)
single line cut dd
multiline cut ndd
paste p
undo u
restore ctrl+r
Move the cursor:
gg move the cursor to the first line
G cursor moves to the last line
0 cursor moves to the beginning of the line
$ move the cursor to the end of the line
Organize code format gg = G
Insert mode:
a : type after the cursor position
A : Type at the end of the line where the cursor is located
i : type in front of the cursor position
I : Type at the beginning of the line where the cursor is
o : Create a new line below the line where the cursor is located and type
O : Create a new line above the line where the cursor is located and type
Bottom row mode:
Save: w
exit: q
Save and exit: wq
Mandatory operation: !
Force save: w!
Force quit: q!
Copy specified line: 1,10y (copy 1-10 line content)
Specifies line cut: 1,10d
Search: /str (str is the string to be searched) n key to search down
Unhighlight: noh
replace:
s/str1/str2 : Replace the first str1 of the line where the cursor is located with str2
s/str1/str2/g : Replace all str1 in the line where the cursor is located with str2
1,100s/str1/str2/g : Replace all str1 in lines 1-100 with str2
1, $s/str1/str2/g : Replace all str1 with str2 in the full text
Split screen: vsp filename
Save all and exit: wqa
9. Simple C programming steps
1) Create a C program file
touch hello.c
2) Open the file with vi editor for programming
we hello.c
3) Write code
#include<stdio.h> //header file
int main(int argc, const char *argv[]) //main function
{
printf("HelloWorld!\n"); //print statement
return 0; //return value
}
4) compile
Compile the C program file into a binary executable program that the machine can recognize
gcc hello.c
5) Execute the executable program
./a.out //The default executable file name is a.out
linux@ubuntu:~/21101$ gcc hello.c -o abc //Generate the specified executable file name
linux@ubuntu:~/21101$ ls
abc a.out day1.txt hello.c passwd.txt
linux@ubuntu:~/21101$ ./abc
HelloWorld!
(2) Compiler
1. Function
Compile the high-level language into a binary language that the machine can recognize.
2. Stages of programming language development
first generation computer language
machine language
Tape punching programming 0 no punching 1 punching
Binary sequence 010101101010010101011
advantage:
1. Can be run directly by the machine
2. Flexible and fast
shortcoming:
1. Not easy to read
2. Difficult to memorize and write inefficiently
3. It is difficult to ensure the correctness of the program
4. Poor portability and poor reusability
second generation computer language
Assembly language
Replace some specific instructions with some abbreviated words that are easy to understand and remember
MOV R1,#1
MOV R2,#2
ADD R3,R1,R2
It is close to human natural language, which improves the coding efficiency, but programming for registers depends on specific computer hardware, resulting in poor compatibility.
third generation computer language
high level language
C、C++、Java、Python....
3. gcc four-step compilation process
1. Pretreatment
Expand the header file, delete useless content such as comments and blank lines, and replace macro definitions.
gcc -E hello.c -o hello.i
2. compile
Check for grammatical errors, report an error if there is an error, and generate an assembly file if there is no error.
gcc -S hello.i -o hello.s
3. Compilation
Generate binary object files from assembly files
gcc -c hello.s -o hello.o
4. Links
Link the object file to the library file, and finally generate a binary executable program that the machine can run.
gcc hello.o -o hello
4. Computer memory representation
The smallest unit of memory in a computer is a bit
The basic unit of computer memory is byte
1byte byte = 8bit
1KB = 1024Byte
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
1PB = 1024TB
2. Basics of C
(1) Computer data representation
Any data is stored in the computer in binary form.
1. Data type value range
Data storage form:
1. All data is stored in memory in two's complement form.
2. The original code, inverse code and complement code of positive numbers are the same
3. The original code of the negative number retains the sign bit, and the other bits are inverted to get the complement code, and the complement code is obtained by +1.
Data type: variable memory size
sizeof (variable name or type name) = occupied memory size
type name | Bytes (32bit-OS) | Ranges |
char character type | 1 byte | -2^7 ~ 2^7 -1 |
short short integer | 2 bytes | -2^15 ~ 2^15-1 |
int integer | 4 bytes | -2^31 ~ 2^31-1 |
long long integer | 4 bytes | -2^31 ~ 2^31-1 |
float single-precision floating-point type | 4 bytes | -3.4*10^-38 ~3.4*10^38 |
double double precision floating point | 8 bytes | -1.7*10^-308~1.7*10^308 |
Take char as an example
1 byte = 8 bits
unsigned unsigned modification
unsigned char unsigned char type
8 data bits
Minimum: 0000 0000
Maximum: 1111 1111
Value range: 0 ~ 2^8-1
signed signed decoration (default)
1 bit sign + 7 data bits
A sign bit of 0 indicates a positive number and a sign bit of 1 indicates a negative number
(signed) char signed char type
Minimum: 1000 0000 (special: sign bit and data bit coincide)
Max: 0111 1111
Value range: -2^7 ~ 2^7-1
(signed) char ch = 130
Positive original code 1000 0010
Positive number complement 1000 0010
Negative complement 1000 0010
Negative original code 1111 1110
= -126
2. Numeric data
Binary (BIN) 0 1 10 11 100 101 110 111 1000 ...
Octal (OCT) 0 - 7 10 - 17 20 - 27 ... 77 100 ...
Decimal (DEC) 0 - 9 10 - 19 20 - 29 ... 99 100 ...
Hexadecimal (HEX) 0 - 9 a - f 10 - 1f 20 - 2f ... ff 100 ...
The identification of each base:
binary 0b
octal 0
hex 0x
Conversion form between bases:
decimal to binary
1) Short division: divide by 2 and take the remainder
66 => 1000010
98 => 1100010
2) Split method: split into powers of 2 and
66 => 64 + 2 => 2^6 + 2^1 => 1000010
98 => 64 + 32 + 2 => 2^6 + 2^5 + 2^1 => 1100010
3) Calculator method
Start Menu - Calculator - Programmer
binary to decimal
10011001 => 2^7 + 2^4 + 2^3 + 2^0 = 128 + 16 + 8 + 1 = 153
Octal to Binary
A maximum of 7 in octal requires a maximum of three in binary to represent 111
One octal corresponds to three binary bits (code 421)
067 => 110 111
0153 => 001 101 011
0526 => 101 010 110
binary to octal
Starting from the low bit, a group of three digits indicates a one-bit octal
1011001101 => 001 011 001 101 => 01315
10111101 => 010 111 101 => 0275
hexadecimal to binary
A hexadecimal value up to f requires a maximum four-digit binary representation of 1111
One hexadecimal corresponds to four binary bits (8421 code)
0xab => 1010 1011
0x3ac => 0011 1010 1100
0xbf8 => 1011 1111 1000
二进制转十六进制
从低位开始四位一组表示一位十六进制
100111010110 => 1001 1101 0110 => 0x9d6
11010110001 => 0110 1011 0001 => 0x6b1
3、非数值型数据
'!' '#' '%'
ascii码(美国信息交换标准代码)
空 ‘\0’
换行 ‘\n’
回车 ‘\r’
'\\' '\"'
字符0 48
字符9 57
'A' 65
'Z' 90
'a' 97
'z' 122
(二)变量
概念: 在程序运行过程中其值会发生变化的量
定义变量:
[存储类型] [数据类型] 变量名;
(auto) int num;
存储类型:变量存储位置
1、auto(自动型)
在缺省存储类型定义变量时,一般将存储类型默认为auto类型。
2、static(静态型)
延长生命周期,限制作用域。
static修饰局部变量:
未初始化初值为0
存储位置:全局区(静态区)
生命周期:同程序共存亡
static修饰全局变量:
将全局变量的作用域限制在了本文件中
3、extern(外部引用类型)
在使用同一程序不同文件的全局变量,通常加extern进行外部引用。
extern引用语句放在全局,引用到该文件的所有的函数均可访问这个全局变量。
extern引用语句放在局部,仅能在所在函数体内部使用。
4、register(寄存器类型)
寄存器是集成在CPU内部的一块很小的存储空间,而内存是挂载在CPU的数据总线 上的大型存储设备。
当一个变量需要被反复多次读取时,为了提高程序执行效率,通常可将该变量定义成寄存器类型。
类型名 | 字节数(32bit-OS) | 取值范围 |
char 字符型 | 1字节 | -2^7 ~ 2^7 -1 |
short 短整型 | 2字节 | -2^15 ~ 2^15-1 |
int 整 型 | 4字节 | -2^31 ~ 2^31-1 |
long 长整型 | 4字节 | -2^31 ~ 2^31-1 |
float 单精度浮点型 | 4字节 | -3.4*10^-38 ~3.4*10^38 |
double double precision floating point | 8 bytes | -1.7*10^-308~1.7*10^308 |
5. Local variables and global variables
Variable classification:
local variable
Definition location: defined inside the function body
Storage location: stack area
global variable
Definition location: defined outside the function body
Storage location: global zone
Difference 1: The uninitialized initial values of global variables and local variables are different
Difference 2: The storage locations of global variables and local variables are different
Difference 3: The life cycle of global variables and local variables is different
Local variables are released after the execution of the function, and global variables are released after the execution of the entire program.
(3) Constants
Concept: A quantity whose value does not change during program execution
Classification:
1. Character constants
ID: ' '
Generally, variables of type char are used to store character constants.
'A' 'Z' '\\' ‘\' '\0'
' !'
Escape characters: '\041' '\x21'
2. String constants
ID: ""
"hello" "a" "0"
All strings end with '\0'
Generally, an array of char type is used to store string constants
char ch[10] = "hello";
3. Integer constants and mandatory type conversion
Integer constants:
Integer 0 100 1000
Generally, variables of type short, int, long, long int, and long long are used to store integer constants
floating point constant
Decimal 0.0 3.1415926
Generally, variables of type float and double are used to store floating-point constants
cast
Format:
(type name to convert) variable name;
Note: implicit conversion
char > short > int > long > float > double
Example 1:
int a = 3,b = 2;
float num = (float)a/b; //Forcibly convert variable a to float type
Example 2:
int num = 0x12345678;
char ch = (char)num; //When 0x78 high byte data is forced to low byte data, it will cause data loss
4. Index constant
3*10^8 => 3E+8
2*10^-5 => 2E-5
Generally, variables of type double are used to store exponential constants
5. Identification constants
Macro definition: for identification
#define macro name constant or expression
#define PI 3.1415926
Features: replace first and then calculate
example:
#define N 2
#define M N+3
#define NUM N+M/2+1
int main()
{
printf("NUM = %d\n",NUM); // 6 5 6.5 5.5
return 0;
}
(4) Lexical symbols of C language
Concept: In a programming language, a meaningful minimum grammatical unit composed of several characters.
Categories: Keywords, Identifiers, Operators, Separators, Punctuation
1. Keywords
Concept: A lexical symbol with a specific function is predefined by the system and cannot be changed by the user.
Classification:
Storage type: auto, static, extern, register
Data type: char, short, int, long, float, double, signed, unsigned
Construction type: struct (structure), union (union), enum (enumeration type)
Branch structure: if, else, switch, case, default
Loop structure: for, while, do, goto, break, continue
Others: return (return), void (empty type), sizeof (occupancy space size), typedef (type redefinition), const (read-only modification), volatile (prevent compiler optimization)
Supplementary note:
typedef
Role: redefine the type name (alias)
Format: typedef prototype typename alias;
Example:
#include<stdio.h>
typedef unsigned int uint;
int main()
{
uint num = 10;
printf("%u\n",num);
return 0;
}
2. Identifier
Concept: user-defined lexical symbols with identification functions, such as: variable names, function names, macro names...
Identifier naming rules:
1. Composed of numbers, letters, and underscores
2. Cannot start with a number
3. The name cannot be the same as the keyword
3. Operators (arithmetic, logical, bit, relational, assignment, conditional)
3.1. Arithmetic operators
+ - * / % ++ --
/ : Integer division should be rounded
% : The remainder operation can only be an integer operation
10 % 3 = 1
++: add 1
1) In an assignment statement:
Scenario 1:
int a = 3,b;
b = a++; //After ++, first take out the value of a to participate in other operations, and then add 1 to a.
Scenario 2:
int a = 3,b;
b = ++a; //++ first, let a self-increment by 1, and then assign the value of a to b.
2) In the print statement:
Scenario 1:
int a = 3;
printf("%d\n",a++); //After ++, take out the value of a and output it, and then add 1 to a.
Scenario 2:
int a = 3;
printf("%d\n",++a); //++ comes first, let a increment by 1 first, and then output the value of a.
3) Stand alone as a statement:
Scenario 1:
int a = 3;
a++;
printf("%d\n",a); //4
Scenario 2:
int a = 3;
++a;
printf("%d\n",a); //4
--: decrement by 1
the same way.
Short answer question: Let i=3, please analyze the result of (++i)+(++i)+(++i)?
This behavior is an undefined behavior of the C language, and the operation result is affected by the compiler.
3.2. Logical operators
&& || !
True or false: look at the result of the formula, if it is not 0, it is true, and if it is 0, it is false.
&& Logical AND
Algorithm:
All true is true, false is false.
|| Logical OR
Algorithm:
Anything true is true, all false is false.
Truncation rule:
&& : If the previous expression is false, the following expression will not be executed.
|| : If the previous expression is true, the following expression will not be executed.
Example 1: OR truncation rule
Example 2: AND operation truncation rule
3.3. Bitwise operators
& | ~ ^ << >>
Bit operations are performed on binary bits
& bit and
Algorithm:
All 1s are 1, and all 0s are 0.
Example:
0xab & 0x5f
1010 1011
& 0101 1111
= 0000 1011 = 0xb
| bitwise or
Algorithm:
1 is 1, all 0 is 0.
Example:
0xab | 0x5f
1010 1011
| 0101 1111
= 1111 1111 = 0xff
~ bitwise inversion
algorithm;
Inversion of 1 is 0, inversion of 0 is 1
~0xab
1010 1011
~=0101 0100 = 0x54
~1
Positive original code 0000 0001
Positive number complement 0000 0001
~= 1111 1110
Negative complement 1111 1110
Negative original code 1000 0010
= -2
~(-20)
Negative original code 1001 0100
Negative complement 1110 1100
~= 0001 0011
Positive number complement 0001 0011
Positive original code 0001 0011
= 19
Invert a decimal number:
~x => -(x+1)
^ bitwise XOR
Algorithm:
Same as 0, different as 1
Example:
0xab ^ 0x5f
1010 1011
^ 0101 1111
= 1111 0100 = 0xf4
<< move left
Operation law:
Shift x to the left by n bits => x multiplied by 2 to the nth power
Move a few bits to the left and add a few 0s to the right
>> move right
Operation law:
Shift x to the right by n bits => x divided by 2 to the nth power (rounded down)
Shift right a few bits left complement sign bit
-25 >> 2 =>
Negative original code 1001 1001
Negative complement 1110 0111
>>2 1111 1001
Negative complement 1111 1001
Negative original code 1000 0111
= -7
Set operation:
a:oxab
1. Set the fourth position of variable a to 1
a:1010 1011
| 0001 0000 -->(1<<4)
1011 1011
2. Set the fifth position of variable a to 0
a:1010 1011
& 1101 1111 -->~(1<<5)
1000 1011
3.4. Relational operators
> < >= <= == !=
3.5. Assignment operator
= += -= *= /= %= ...
a+=1 => a = a + 1
a*=3 => a = a * 3
3.6, conditional operator
Ternary operator? :
expression 1? expression2: expression3
Algorithm:
First judge whether expression 1 is true, if true, take the value of expression 2, otherwise take the value of expression 3.
4. Operator precedence
Priority from highest to lowest:
Unary operator! ~ ++ --
Arithmetic operators * / % + -
shift operator <<>>
Relational operators < <= > >= == !=
bitwise AND operator &
XOR operator ^
bitwise OR operator |
Logical operator && ||
conditional operator? :
assignment operator = += *= /= ...
Mouth formula: single calculation and transfer, XOR logical endowment
Associativity right to left: single assignment
(5) Memory partition
1. Diagram of memory partition location
high address
-------------------------------------------------
Stack area: The system automatically opens up and automatically releases space for storing local variables
-------------------------------------------------
Heap area: the space manually released by the user, malloc and free
-------------------------------------------------
Full .bss Uninitialized global and static variables
Bureau -------------------------------------------------
Area.data Initialized global variables and static variables
-------------------------------------------------
Constant area: store constants
-------------------------------------------------
Code segment: store user code
-------------------------------------------------
low address
2. Big and small endian (three methods)
Concept : Multi-byte data will have different storage forms during storage.
Little-endian mode: High address stores high-order data, and low address stores low-order data.
Big-endian mode: High addresses store low-order data, and low addresses store high-order data.
Big and small endian verification method:
method one:
#include<stdio.h>
int main(int argc, const char *argv[])
{
int num = 0x12345678;
char ch = (char)num;
printf("%#x\n",ch); //The low address of 0x78 stores low-order data, so it is a little-endian storage mode.
return 0;
}
Method 2:
Verify by union
#include<stdio.h>
union data
{ char a; int b; }; int main(int argc, const char *argv[]) { union data s; sb = 0x12345678; printf(" %#x\n",sa); return 0; }
方法三:
利用指针
#include<stdio.h>
int main(int argc, const char *argv[])
{
int num = 0x12345678;
void *p = #
printf("%#x\n",*(char *)p);
return 0;
}
(六)控制语句
1、输入输出语句
1.1格式化输出语句printf
#include<stdio.h>
返回值类型 函数名(参数)
int printf(const char *format, ...);
功能:按照用户指定的格式输出数据
参数: const char *format 指定格式
%c -- 字符
%s -- 字符串
%o -- 八进制整数 %#o
%d -- 十进制整数 %ld %lld
%x -- 十六进制整数 %#x
%f -- 浮点型小数 %lf
%e -- 指数
%u -- 无符号数
%p -- 地址
... 要输出的数据
返回值:实际输出的字符个数
1.2格式化输入函数scanf
int scanf(const char *format, ...);
功能:按照用户指定的格式从终端输入数据
参数:const char *format 格式
同printf
... 要输入的数据的地址
返回值:成功输入的数据的个数
应用示例:
int num1 = 0,num2 = 0;
printf("请输入两个整数:");
scanf("%d %d",&num1,&num2);
printf("两数之和为:%d\n",num1+num2);
注意:
1.scanf中不要出现\n \r \t
scanf("%d\n",&a);
scanf("%d\t",&a);
scanf("%d\r",&a);
输入整型数后按回车并不能结束,只有再次输入一个字符才能结束。
或者结束进程:ctrl + c
2.输入字符时
char a,b;
scanf("%c%c",&a,&b); //两个字符紧挨着输入
// 若输入abc,只能成功输入字符a和字符b。
// 如果输入a空格b,那么空格会被输入给b。
3.输入整数和字符时
int a;
char b;
scanf("%d%c",&a,&b);
//输入1空格a或者1回车a,会将空格符或换行符赋给b。
scanf("%d %c",&a,&b);
//输入1空格a或者1回车a都可以成功输入。
scanf("%d,%c",&a,&b);
//输入1,a可以成功输入。
scanf("%*c%c",&b);
//%*c吞掉任意一个字符
//空格为scanf输入结束的标志
1.3 字符输出函数putchar
int putchar(int c);
功能:向终端输出一个字符
参数:要输出字符的ascii
返回值:同参数
输出换行符:
putchar('\n')
putchar(10)
1.4 字符输入函数getchar
int getchar(void);
功能:从终端输入一个字符
参数:void 无
返回值:输入字符的ascii
练习:实现大小写转换 (用getchar实现输入,用putchar输出)
如果输入的是大写字母,则输出小写字母
如果输入的是小写字母,则输出大写字母
如果输入的不是字母,则输出“输入有误”
2、分支结构语句
1. if -else
基本结构:
if(表达式)
{
语句块1;
}else
{
语句块2;
}
练习:任意输入一个年份,判断是平年还是闰年。
置闰规则:
普通闰年:公历年份是4的倍数,且不是100的倍数的,为闰年(如2004年、2020年等就是闰年)。
世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是闰年,2000年是闰年)。
嵌套结构:
if(表达式1)
{
if(表达式2)
{
语句块1;
}else
{
语句块2;
}
}else
{
语句块3;
}
分层结构:
if(表达式1)
{
语句块1;
}else if(表达式2)
{
语句块2;
}else
{
语句块3;
}
练习.输入三角形边长,求面积(开平方sqrt)
s = 1/2 * (a+b+c);
____________________
面积:area = √ s*(s-a)*(s-b)*(s-c)
提供开方函数如下:
#include <math.h>
double sqrt(double x);
功能:开根号
参数:double x 被开根号的值
返回值:开根号后得到的结果
编译时注意连接math库 即gcc xxx.c -lm
编程思路:
1.定义三个变量,从终端输入数据。
2.判断三边长是否能构成三角形
如果能够构成三角形
代入s = 1/2 * (a+b+c)算出s
通过调用sqrt函数对s*(s-a)*(s-b)*(s-c)开方算出面积
输出面积
如果不能构成三角形
输出“三边长无法构成三角形”
2.switch-case
基本结构:
switch(变量或表达式)
{
case 常量1 : 语句块1;break;
case 常量2 : 语句块2;break;
...
case 常量n : 语句块n;break;
default :语句块n+1;
}
示例:终端输入一个数,输出对应星期几。
练习:实现简易计算器,能进行加减乘除运算。 (用switch-case实现)
要求:输入 1 + 1
输出 2
3、循环语句
1.for
基本结构
for(表达式1;表达式2;表达式3)
{
语句块;
}
表达式1:赋初值
表达式2:循环判断条件
表达式3:增值或减值语句
执行顺序:
先执行表达式1赋初值,再判断表达式2是否成立,如果成立则执行语句块;语句块执行完毕后再执行表达式3,再次判断表达式2是否成立,成立则执行语句块,依次循环;直到表达式2不成立,则循环结束。
练习1:由用户控制循环次数,输出hello world
练习2:求100以内最大能被17整除的数
思考:如何找出所有能被17整除的数?
如何只输出最大的那个?
方法1:从小往大找
方法2:从大往小找
练习2:输出200-400之间能被3整除且个位数字为6的整数。
思考:如何利用循环限制数据范围? 200-400
如何判断这个数据能被3整除?
如何判断数据的个位为6?
嵌套结构
for(表达式1;表达式2;表达式3)
{
for(表达式4;表达式5;表达式6)
{
语句块;
}
}
外层循环执行n次,内层循环执行m次,语句块共执行n*m次
图形题:
输出以下图形
行数由终端输入
for嵌套: 外层循环控制行数,内层循环控制每行星的个数
练习:用户输入行数,打印菱形
注:菱形行数为奇数。
练习:3、4、5三个数能组成多少互不相同且无重复的数
2.while
基本结构:
while(表达式)
{
语句块;
}
执行顺序:
判断表达式是否成立,如果表达式成立则执行语句块,
执行完毕后再次判断表达式是否成立,如果成立则再次执行语句块,依次循环。
直到表达式不成立,则循环结束。
面试题:
找到所有水仙花数:水仙花数是一个三位数,个位、十位、百位的立方和等于其本身。
3.do...while
do
{
语句块;
}while(表达式);
执行顺序:
先执行语句块,再判断表达式是否成立。如果成立则再次执行语句块,依次循环。
直到表达式不成立则跳出循环。
4.goto语句
标签:
语句;
...
goto 标签;
执行规则:当遇到goto语句时,程序跳转到标签位置继续执行。
注意事项:
1.标签一般用大写字母定义。
2.goto只能在函数体内部跳转。
3.goto会破坏程序的顺序性,一般不建议使用。
死循环:
while(1) //永真循环
for(;;)
5.循环控制语句
break:跳出循环
continue:跳出本次循环,继续下次循环。
continue后面的语句不再执行。
continue用法示例:
(七)、数组
1、概念
一组同种类型的数据的集合
定义格式:
[存储类型] [数据类型] 数组名[大小];
(auto) int arr[10];
大小:元素个数 arr[0] ~ arr[9]
数组名:1) 遵守标识符的命名规则
2) 数组名即代表数组的首地址
arr <=> &arr[0]
2、数组初始化
(1)全部初始化
int num[5] = {1,2,3,4,5};
初始化完的效果;
num[0] = 1
num[1] = 2
num[2] = 3
num[3] = 4
num[4] = 5
(2)部分初始化
int num[5] = {1,2};
初始化完的效果;
num[0] = 1
num[1] = 2
num[2] = 0
num[3] = 0
num[4] = 0
数组部分初始化时,未被初始化的元素值为0
3.未初始化
int num[5];
数组未初始化,其值均为随机值。(局部)
3、数组清零
int num[5] = {0,0,0,0,0};
int num[5] = {0};
4、数组大小
元素个数 * 数据类型大小
示例:
int a[5] = {1,2}; //20字节
char b[10]; //10字节
double c[3] = {1.1,2.2,3.3}; //24字节
5. Array input and output
int num[5] = {0};
scanf("%d",&num[0]);
scanf("%d",&num[1]);
....
scanf("%d",&num[4]);
Loop optimization:
int i;
for(i=0;i<5;i++)
{
scanf("%d",&num[i]);
}
Array traversal:
for(i=0;i<5;i++)
{
printf("num[%d] = %d\n",i,num[i]);
}
6. Bubble sort
Sort 5 4 3 2 1 from small to large
original sequence
5 4 3 2 1
first round:
4 5 3 2 1
4 3 5 2 1
4 3 2 5 1
4 3 2 1 5
second round:
3 4 2 1 5
3 2 4 1 5
3 2 1 4 5
Third round:
2 3 1 4 5
2 1 3 4 5
Fourth round:
1 2 3 4 5
Summarize:
N numbers compare N-1 rounds
The number of comparisons in each round decreases from N-1
accomplish:
For loop nesting implementation, the outer loop controls the number of comparison rounds, and the inner loop controls the number of comparisons.
Core code:
N numbers are sorted from large to small:
for(i=0;i<N-1;i++)
{
for(j=0;j<N-1-i;j++)
{
if(num[j]<num[j+1])
{
tmp = num[j];
num[j] = num[j+1];
num[j+1] = tmp;
}
}
}
7. Selection sort
Sort from smallest to largest
Red arrow i: lock position from the first to the penultimate number
Blue arrow j: Find the most value from the data pointed by arrow i to the last data
Green arrow k: Temporarily mark if the arrow j finds a smaller one, call k to mark it
Sorting ideas:
First let i lock a position, let k record the position of i, then j starts to find a smaller number from the next data of i, when it is found, let k temporarily mark it, and j continues to search for a smaller number until it reaches the last one data, j task completed.
It is only necessary to exchange the position data of the i mark and the position data of the k mark, and the smallest number can be put in front.
Algorithm implementation:
N numbers are sorted from small to large:
for(i=0;i<N-1;i++)
{
k=i;
for(j=i+1;j<N;j++)
{
if(num[j]<num[k])
{
k=j;
}
}
if(i!=k)
{
tmp=num[i];
num[i] = num[k];
num[k]=tmp;
}
}
Code:
8. Two-dimensional array
Concept: an array with rows and columns
Definition format:
[storage type] [data type] two-dimensional array name [row number] [column number];
(auto) int num[2][3];
Number of elements: number of rows * number of columns
initialization:
1. All initialization
int num[2][3] = {1,2,3,4,5,6};
int num[2][3] = { {1,2,3},{4,5,6}};
After initialization:
| 1 2 3 |
| 4 5 6 |
2. Partial initialization
int num[2][3] = {1,2};
After initialization:
| 1 2 0 |
| 0 0 0 |
int num[2][3] = { {1},{2}};
After initialization:
| 1 0 0 |
| 2 0 0 |
3. Uninitialized
int num[2][3]; (local)
// Uninitialized are random values
Array size:
number of rows * number of columns * data type size
int num[2][3]; //24 bytes = 2 * 3 * 4
Array input and output:
int num[2][3] = {0};
enter:
for(i=0;i<3;i++)
{
scanf("%d",&num[0][i]);
}
for(i=0;i<3;i++)
{
scanf("%d",&num[1][i]);
}
Optimize with loop nesting ideas:
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&num[i][j]);
}
}
output:
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("%d ",num[i][j]);
}
putchar(10);
}
Exercise: Define an array of three rows and four columns, enter data from the terminal, find out its maximum value, minimum value, and output its subscript.
For example:
max : num[1][2] = 99
min : num[0][2] = 1
Exercise: There is a matrix with three rows and three columns, as follows:
| 1 2 3 |
| 4 5 6 |
| 7 8 9 |
Finds the sum of the values of its off-diagonal elements.
Exercise: Enter the grades of Xiao Zhang, Xiao Wang, and Xiao Liu from the terminal for the three courses of C language, C++, and data structure.
Find the average score of each subject and the average score of the three students.
9. Character array
Concept: An array used to store strings is called a character array.
char s[10] = {"hello"};
char s[10] = {'a','b','c'};
char s[10] = "hello";
char s[ ] = "hello"; //6 bytes
//The end of the string is '\0'
char s1[3] = {"abc"}; //Illegal
char s2[3] = {'a','b','c'}; //legal
//If the output is in the form of a string, neither of the above two writing methods has an end mark.
Character array input:
1) Input in units of characters
char str[10] = {0},i;
for(i=0;i<5;i++)
{
scanf("%c",&str[i]);
}
//The number of input characters is determined by the number of cycles, and the input is not flexible enough.
2) Enter in the form of a string
scanf("%s",str);
// space cannot be entered
solution:
Using scanf("%[^\n]", str); can read a line of string until the end of the newline character \n
Format control method for %[]: %[scanfset]
The scanfset starting with the ^ character means that when reading the string, it will match all the characters that do not appear in the scanfset, and the input of the characters in the scanfset will end.
3) String input function
char *gets(char *s);
Function: Get a string of characters from the terminal
Parameters: char *s The first address of the target character array
Return value: same parameter
//Note: The gets function does not check the size of the array, which is likely to cause stack overflow problems caused by out-of-bounds assignments, so there will be dangerous warnings when compiling.
You can use fgets to enter strings later.
Character array output:
1) Output in units of characters
char str[10] = "hello";
for(i=0;i<5;i++)
{
printf("%c",str[i]);
}
2) Output in the form of a string
printf("%s\n",str);
//Take '\0' as the output end mark
3) String output function
int puts(const char *s);
Function: output a string of characters to the terminal
Parameters: const char *s The first address of the string to be output
Return value: successful execution - non-negative number
Today's homework:
1) Print the first fifteen rows of Yang Hui's triangle (the first column is known to be 1)
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
....
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a[15][15]={
{0}};
int i,j;
for(i=0;i<15;i++)
{
a[i][0]=1;
for(j=1;j<=i;j++)
a[i][j]=a[i-1][j-1]+a[i-1][j];
for(i=0;i<15;i++){
for(j=0; j<=i;j++)
printf("%8d",a[i][j]);
printf("\n");
}
return 0;
2) Enter a string of strings from the terminal, count the number of numeric characters in it, and output the sum of the numeric characters.
#include <stdio.h>
int main(int argc, const char *argv[]){
char s[100];
int i=0;
int j=0;
int sum=0 ;
gets(s);
/ /puts(s);
while(s[i]!='\0'){
if('0'<=s[i]&&s[i]<='9'){
j++;
sum+=(s[i]-'0');
i++ ;
}
printf("字符串中数字字符的个数为: %d\n", j);
printf("字符串中数字字符求和为: %d\n",sum);
return 0;
10. String family functions
#include <string.h> Prototype of
strlen function: size_t strlen(const char *s); Function: Calculate the actual length of the string (up to '\0') Parameter: const char *s The first address of the string Return value: size_t string actual length interview question: the difference between strlen and sizeof? Answer: strlen is a function that calculates the actual length of the string (up to '\0'). And sizeof is a keyword, which calculates the size of memory occupied by variables or types. char str[10] = "hello"; sizeof(str) = 10; strlen(str) = 5; Exercise: imitate strlen function. Input any string of characters from the terminal and output its actual length. strcpy char *strcpy(char *dest, const char *src); Function: implement string copy (including '\0') Parameters: char *dest destination string address const char *src source string address return value: dest destination string address
char *strncpy(char *dest, const char *src, size_t n)
//According to the specified number of characters to realize the copying of strings
Thinking questions: char s1[32] = "hello", how to store "world" in s1 ?
s1 = "world" ; //Error, because s1 is an address constant, constant cannot be assigned.
s1[0] = 'w';
s1[1] = 'o';
...
//It is possible, but not necessary
to use strcpy:
strcpy(s1,"world");
strcat
char *strcat(char *dest , const char *src);
Function: implement string concatenation (including '\0')
Parameters: char *dest destination string address
const char *src source string address
Return value: dest destination string address
char *strncat(char *dest, const char *src, size_t n)
//Concatenate according to the specified number of characters
strcmp
int strcmp(const char *s1, const char *s2);
功能:比较首个不相同的字符的ascii(包含'\0')
参数:要比较的两个字符串的首地址
返回值: s1 > s2 1
s1 = s2 0
s1 < s2 -1
int strncmp(const char *s1, const char *s2, size_t n);
//按照指定字符个数进行比较
(八)指针
1、概念
地址:内存中每个字节都有一个编号,这个编号就是地址(一般用十六进制表示)
指针:指针就是地址,地址是个常量。
指针变量:用于存放指针(地址)的变量称为指针变量
2、定义格式
[存储类型] [数据类型] *指针变量名;
(auto) int *p;
// 在定义指针,*起标识作用。
//定义指针时,数据类型表示的指向的地址存储的数据类型。
3、指针的运算
1) Assignment operation
a. The pointer points to the ordinary variable
int num = 10;
1 - int *p = # //The pointer p points to the integer variable num.
2 - int *p = NULL;
p = #
b. The pointer points to a one-dimensional array
int num[5] = {1,2,3,4,5};
1 - int *p = num; //The array name is Represents the address of the first element of the array
2 - int *p = &num[0]; //The pointer p points to the first address of the array
p <=> num
Access the value of the element num[i]:
direct access through the array name: num[i ] *(num+i)
indirect access through the pointer name: p[i] *(p+i)
access to the address of the element num[i]:
direct access through the array name: &num[i] num+i
indirect access through the pointer name : &p[i] p+i
Derivation process: The pointer p points to the array num, and p stores the first address of the num array, that is, p points to the address of the first element of the array.
p => &num[0] 那p+i则为num[i]的地址 &num[i]
*(p+i)相当于对&num[i]进行取值运算,因此*(p+i) => num[i]
约定地址的等级高于元素值的等级
升级 : 加& 去掉[]
降级 :加* 添加[]
c.指针指向另一个指针指向的数据
int num;
int *p = #
int *q = p;
2)取值取址运算
& 取地址符 :取变量的地址
* 取值符 :取地址上的值
&和*互为逆运算,可以抵消。
*&num = num
3)算术运算
p+1 :向高地址方向移动一个数据的大小
p-1 :向低地址方向移动一个数据的大小
//以上两种运算,p的指向不变
p++、p--才会真正改变指针指向
4) Relational operations
> < >= <= == !=
The relational operation between pointers compares the high and low addresses,
and the pointer pointing to the high address is larger than the pointer pointing to the low address.
Pointers pointing to different areas and different types have no relational operation meaning.
4. Pointer size
In 32-bit operating systems, the pointer size is always 4 bytes.
The effective addressing space of the pointer is 4G.
Addressing range: 0 ~ 2^32-1
4,294,967,296 bytes = 4,194,304KB = 4096MB = 4GB
int num;
int *p1 = #
char ch;
char *p2 = &ch;
double f;
double *p3 = &f;
sizeof(p1) sizeof(p2) sizeof(p3)
Practice: 1. Enter a string of strings in the terminal, replace character a with character * output
(realize with pointers)
2. Realize string inversion through pointers Input and input
from the terminal
hello
output olleh
segmentation fault Segmentation fault (core dumped)
reasons: 1) memory access out of bounds
2) use of wild pointer
wild pointer: if there is no clear pointer to the object
definition pointer, if there is no clear pointer, it will be initialized to empty to prevent wild pointer problems.
5. Modification of pointers (const, void)
const constant
function: read-only modification
1) const modification of ordinary variables
#include<stdio.h>
int main(int argc, const char *argv[])
{ const int num = 10; //num = 20; // error : The read-only variable num cannot be assigned a value int *p = # *p = 20; printf("%d\n",num); return 0; } 2) const modified pointer int num1 = 10, num2 = 20; const int *p = &num1; //int const *p = &num1; *p = 20; //Error, const modifies *p as a whole, and the value of the address pointed to by the pointer cannot be changed by changing *p p = &num2; // It is feasible, and the pointer points to variable.
int num1 = 10, num2 = 20;
int * const p = &num1;
*p = 20; // feasible, *p can be changed.
p = &num2; //Error, because const modifies p, the pointer point cannot be changed.
void empty type
void *p = NULL; //The data type pointed to by the void type pointer is uncertain.
//The null type pointer can point to any type of variable.
int a = 10;
char b = '!';
float c = 3.14;
void *p = NULL;
//The void type pointer needs to be cast for the pointed data type when used.
p = &a;
printf("%d\n",*(int *)p);
p = &b;
printf("%c\n",*(char *)p);
p = &c;
printf("% f\n",*(float *)p);
6. Secondary pointer
Concept: A pointer to a first-level pointer is called a second-level pointer
Example:
int num = 10;
int *p = #
int **q = &p; //The second-level pointer q points to the first-level pointer p
to access the value of num:
num *p **q
accesses the address of num
&num p *q
7. Pointers and arrays
Direct access: access through the array name
Indirect access: access through a pointer to the array
1.指针与一维数组
int num[5] = {1,2,3,4,5};
int *p = num;
访问num[i]的值:
直接访问: num[i] *(num+i)
间接访问: p[i] *(p+i)
访问num[i]的地址:
直接访问: &num[i] num+i
间接访问: &p[i] p+i
printf("%p\n",num+1); //打印num[0]的地址
printf("%p\n",p+1); //打印num[0]的地址,指针指向不变。
printf("%p\n",num++); //报错,num是数组首地址是个地址常量,常量不能自加。
printf("%p\n",p++); //打印num[0]的地址,再让指针向后移动。
注意:
1)*和++都是单目运算符,优先级相同。
2)单目运算符结合性是从右向左。
*p++ :先取出p的值参与取值(*)运算,再让指针向高地址方向移动一个数据。
*(p++):先取出p的值参与取值(*)运算,再让指针向高地址方向移动一个数据。
*++p :先让指针向高地址方向移动一个数据,再对p的值进行取值运算。
*(++p):先让指针向高地址方向移动一个数据,再对p的值进行取值运算。
++*p :先对p进行取值运算,再对p指向的地址上的值进行自加运算。
++(*p):先对p进行取值运算,再对p指向的地址上的值进行自加运算。
(*p)++:先对p进行取值运算,参与完其他运算之后,再对指针指向的地址上值进行自加运算。
2.指针与二维数组
int num[2][3];
int *p = num; //错误,因为二维数组的数组名是个二级地址,因此不能用一级指针直接指向。
推导过程:
num => &num[0] => &&num[0][0]
访问num[i][j]的元素值:
num[i][j] *(num[i]+j) *(*(num+i)+j)
访问num[i][j]的元素地址:
&num[i][j] num[i]+j *(num+i)+j
8、数组内存移动问题
One-dimensional array:
&num entire array
num &num[0] element
int num[5];
&num +1 20 bytes
num +1 4 bytes
&num[0] +1 4 bytes
two-dimensional array:
&num entire array
num &num[ 0] row address
num[0] +1 column address
&num[i][j] element address
int num[2][3];
&num +1 24 bytes
num+1 &num[0]+1 12 bytes
num[ 0]+1 &num[0][0]+1 4 bytes
9. Array pointer
Concept: It is essentially a secondary pointer, and a pointer dedicated to pointing to an array (two-dimensional) is called an array pointer.
Definition format:
[storage type] [data type] (*array pointer name)[number of columns];
(auto) int (*p)[i];
//When the array pointer is defined, [] fills in the two-dimensional pointing The number of columns in the array.
Example:
int num[2][3];
int (*p)[3] = num;
p row address
*p column address element address
**p element value
array pointer p points to the two-dimensional array num, so num and p Equivalent, at this time p represents the row address of the num array.
Access the value of num[i][j]:
direct access: num[i][j] *(num[i]+j) *(*(num+i)+j)
indirect access: p[i][j ] *(p[i]+j) *(*(p+i)+j)
access the address of num[i][j]
direct access: &num[i][j] num[i]+j *(num +i)+j
indirect access: &p[i][j] p[i]+j *(p+i)+j
10. Array of pointers
Concept: Essentially an array, the array used to store pointers (addresses) is called a pointer array
Definition format:
[storage type] [data type] * pointer array name [size];
(auto) int *num[i];
size : Number of elements
Application example:
1. The pointer array stores the address of ordinary variables
int a = 10, b = 20, c = 30;
int *p[3] = {&a,&b,&c};
access b through the array name p The value of:
*p[1] *(*(p+1))
Access the address of b through the array name p:
p[1] *(p+1)
2. The pointer array stores the first element of each row of the two-dimensional array address (column address)
int num[2][3];
int *p[2] = {num[0],num[1]};
int *p[2] = {&num[0][0], &num[1][0]};
Derivation process:
p => &p[0] => &num[0] => num
The command line parameter argv is an array of pointers, which store the strings passed by the command line. argc indicates the number of data stored in the argv pointer array, that is, the number of strings passed on the command line.
int main(int argc, const char *argv[])
{ printf("ip:%s\n",argv[1]); return 0; } Array size: number of elements * 4 (pointer size) //Because The size of the pointer in the 32-bit operating system is always 4 bytes
(9) Function
1. Concept
Code modules with specific functionality
Advantages: 1) Reduce code duplication
2) Modular programming
2. Format
return value type function name (parameter)
int main (int argc, const char *argv[])
{
...
//code block
return 0; //return value
}
3. Classification
1) There are parameters and return values
2) There are parameters but no return value
3) No parameter and no return value
4. Function call
1) Call a function with parameters and a return value
a. Pass parameters according to the data type required by the function parameter
b. Define a variable of the same type as the return value of the function to receive the return value of the function
Example:
int x = 3,y = 5,res;
res = add(x,y);
printf("%d\n",res);
2) Call a function with parameters and no return value
Pass parameters according to the data type required by the function parameter
Example:
sub(x,y);
3) Call a function with no parameters and no return value
Just call the function name directly.
Example:
func();
5. Function declaration
Just put the function definition between the main function and the header file.
Example:
#include<stdio.h>
int add(int a,int b);
void sub(int a,int b);
void func();
int main()
{
...
}
Exercise: Write the mystrcat function following the strcat function.
//Write with parameters and return value
//Writing with parameters but without return value
练习:写一个函数swap实现两个数交换
//写法一:
传递实参的值,只是交换了形参的值,并未影响到实参本身,没有实现真正的交换。
//写法二:
传递实参的地址,通过形参访问实参地址,实现交换地址上的值,真正实现了数据交换。
函数传参:
1)值传递:相当于将实参的值进行拷贝传递给形参,对实参本身并无影响。
2)地址传递:相当于将实参的地址传递给形参,操作形参等同于操作实参。
3)数组传递:相当于传递数组首地址,操作形参相当于操作数组本身。本质就是地址传递。
6、递归函数
1.概念:自己调用自己的函数
注意:递归函数一定要设置结束条件。
2.递推阶段:从原问题出发,按照递推公式从未知到已知,最终达到终止条件。
回归阶段:按照递归终止条件求出结果,再将结果逆向代入递归公式,最终回到原问题求解。
示例:
练习:利用递归函数求斐波那契数列第20项的值
已知前两项为1.
分析:
第五项?
=第三项 + 第四项
=(第一项+第二项) + (第二项 + 第三项)
= 1 + 1 + 1 +(第一项+第二项)
= 1 + 1 + 1 + 1 + 1
那么第n项 = 第n-1项 + 第n-2项
不断拆解直到达到已知条件,再带入原问题求得最终解。
代码实现:
(十)结构体
1、概念
结构体是由用户自定义的一种构造类型,用于描述复杂事物,表示多种不同类型的数据的集合。
2、格式
struct 结构体名
{
数据类型1 成员1;
数据类型2 成员2;
....
数据类型n 成员n;
};
示例:
struct student
{
int id; //学号
char name[32]; //姓名
float score; //成绩
};
3、结构体大小
1)字节对齐规则:在结构体所有成员中,选择数据类型最大成员跟value(4字节),按照小的为单位开辟内存空间。
2)节省空间原则:在保证数据不被破坏的前提下,尽可能向上压缩以节省存储空间。
//Why byte alignment? The memory space in modern computers is divided by byte. In theory, it seems that access to any type of variable can start from any address, but the actual situation is that when accessing a specific type of variable, it is often accessed at a specific memory address. It requires various types of data to be arranged in space according to certain rules, rather than sequentially arranged one by one, which is alignment. When we wrote the program before, we may find that sometimes the variable you define is one byte, but it is still stored in four bytes in memory, because in a 32-bit system, 4-byte alignment executes efficiently is the fastest. This is a solution that sacrifices memory for performance.
Special case:
struct num
{
char a; //4
short b; char and short are 2-byte aligned within four bytes.
char c; //4
int d; //4
};
sizeof(struct num) = 12
4. Structure variables
1. Concept: A variable defined by a structure type is called a structure variable.
2. Define the format
1) Define the structure type first, and then define the structure variable through the structure type.
struct phone
{
int ID;
char Brand[10];
char Model[20];
char CPU[20];
float Price;
};
struct phone p1;
2) Define the structure variable while defining the structure type.
struct phone
{
int ID;
char Brand[10];
char Model[20];
char CPU[20];
float Price;
}p1,p2;
struct phone p3;
3) When the structure is nested, the structure variable can be defined with the default structure name.
struct student
{
int ID;
char Name[32];
struct {
float chinese;
float math;
char PE;int English;
} cj;
};
3. Structure variable initialization
1) Initialize while defining the structure variable
struct phone
{
int ID;
char Brand[10];
char Model[20];
char CPU[20];
float Price;
}p2 = {1002,"Xiaomi","13","Snapdragon 8Gen1",3999};
struct phone p1 = {1001,"Huawei","P60","Snapdragon 8Gne2",5999};
2) When defining the structure variable, it is not initialized, and then assign values to the members respectively.
Structural variable through. Access members: Structural variable name. Member
Example:
struct phone p3; //uninitialized
strcpy(p3.Brand,"APPLE");
strcpy(p3.Model,"14ProMax");
strcpy(p3.CPU,"A16");
p3.Price = 8999;
Supplement:
Use typedef to alias the structure type.
typedef struct
{ int ID; char Brand[10]; char Model[20]; char CPU[20]; float Price; }PH; //ph is the structure type PH p1; //p1 is the structure variable
5. Structure array
1. Concept: An array used to store structure variables, and the elements stored in the structure array are all structure types.
2. Definition format:
first define the structure type, and then define the structure array through the structure type.
typedef struct
{ int ID; char Brand[10]; char Model[20]; char CPU[20]; float Price; }PH; PH ph_arr[20]; 3. Structure array initialization PH ph_arr[10] ={ { 1001,"Huawei","P60","Snapdragon 8Gen2",5999}, {1002,"Xiaomi","13","Snapdragon 8Gen1",3999} } ;
4. The input and output of the structure array
struct phone ph_arr[5] = {0};
scanf("%d",&ph_arr[0].id);
optimize by loop:
for(int i=0;i<5; i++)
{ scanf("%d %s %s %s %f",&ph_arr[i].id,ph_arr[i].brand,ph_arr[i].mod,ph_arr[i].cpu,&ph_arr[i] .price); } for(int i=0;i<5;i++) { printf("%d %s %s %s %f",ph_arr[i].id,ph_arr[i].brand,ph_arr[ i].mod,ph_arr[i].cpu,ph_arr[i].price); }
6. Structure pointer
Concept: A pointer to a structure type is called a structure pointer
Definition format:
struct structure name*structure pointer name;
application example:
struct phone
{ int ID; char Brand[10]; char Model[20]; char CPU[20] ]; float Price; }arr[10]; struct phone *p = arr; Access form: assign a value to the ID member of the element whose subscript is 1 in the array: (*(p+1)).ID = 1001; (p +1)->ID = 1001;
7. Community
Concept: Data of different data types use a common storage area. This type of data construction is called a union, also known as a union.
Definition format:
union union name
{ member list; }; for example: union data { char cval; int ival; float fval; }; union type variable definition: (1) Define the union type first, then define the variable. union data { char cval; int ival; float fval; }; union data a,b,c; (2) Define the variable while defining the union type. union data {
char cval;
int ival;
float fval;
}a,b,c;
if no new variables are defined, the name of the union can also be omitted:
union
{ char cval; int ival; float fval; }a,b,c ; Calculation of the size of the union: The memory occupied by the structure is greater than or equal to the sum of the memory occupied by all members, because there may be gaps between members, and the memory space occupied by the union is equal to the memory occupied by the largest member variable. The union adopts the memory overlay technology, which can only save the value of one member at a time. If a value is assigned to a new member, the original member data will be overwritten. For example: int type data occupies the largest memory in the union data, occupying 4 bytes, then the memory size occupied by the union data is 4. union test { char s[20]; int b; double c; }a;
sizeof(a) = 20;
8. Enumeration
Definition: A data type that can only take predefined values is an enumeration type.
In actual programming, the value of some data is often limited and can only be a very small number of integers, and it is best to give each value a name for easy use in subsequent codes. For example, there are only seven days in a week. There are only twelve months in a year, and a class has six courses a week, etc.
Format:
enum enumeration type name
{ enumeration element list }; For example: List the days of a week: enum week { Mon, Tues, Wed, Thurs, Fri, Sat, Sun }; As you can see, we only give The name is given, but the value corresponding to the name is not given, because the enumeration value starts from 0 by default and increases by 1 one by one, that is to say, Mon, Tues in week... Sun
The corresponding values are 0, 1...6.
We can also assign a value to each name:
enum week
{
Mon = 1, Tues = 2, Wed = 3, Thurs = 4, Fri = 5, Sat = 6, Sun = 7 }
;
due to the enum type value one by one Increment by 1, we can also only assign a value to the first name:
enum week
{
Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun
};
Explanation: 1) The enumeration type is a type, through which You can define enumeration variables
enum week a,b,c;
2) You can assign values in the list to enumeration variables
enum week a = Mon, b = Web, c = Sat;
3) Mon, Tues in the enumeration list The scope of these identifiers, Wed is global (strictly speaking, inside the main() function), and
variables with the same name as them cannot be defined.
4) Mon, Tues, Wed, etc. are all constants, which cannot be assigned again, but can only be assigned to other variables.
Example: Determine the day of the week entered by the user.
#include <stdio.h>
int main(){ enum week{ Mon = 1, Tues, Wed, Thurs, Fri, Sat, Sun } day; scanf("%d", &day); switch(day){ case Mon : puts("Monday"); break; case Tues: puts("Tuesday"); break; case Wed: puts("Wednesday") ;
case Fri: puts("Friday"); break;
case Sat: puts("Saturday"); break;
case Sun: puts("Sunday"); break;
default: puts("Error!");
}
return 0;
}