Linux operating system and C language (detailed explanation)

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

099a849692b226d283a33256ec385f5a.png

33475f8ce184c5f8003120b94eb298cd.png

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

feff6757b85840499170434651ecde11.png

3. Compilation

Generate binary object files from assembly files

gcc -c hello.s -o hello.o

863faab616ead2d0557251ca38d18dec.png

9a082d6c1506e15069cb22f2005d124a.png

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

18f62bf315cfa21541380e0b6d86af94.png

6692ea24e27e1fc7be3c4abf1c06fa10.png

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’

'\\' '\"'

9512168ccee641286b0a8a72690e3c8f.png

字符0 48

字符9 57

'A' 65

'Z' 90

'a' 97

'z' 122

(二)变量

概念: 在程序运行过程中其值会发生变化的量

定义变量:

[存储类型] [数据类型] 变量名;

(auto) int num;

存储类型:变量存储位置

1、auto(自动型)

在缺省存储类型定义变量时,一般将存储类型默认为auto类型。

2、static(静态型)

延长生命周期,限制作用域。

static修饰局部变量:

未初始化初值为0

存储位置:全局区(静态区)

生命周期:同程序共存亡

9745f378919aa7809820e331c15b9b32.png

static修饰全局变量:

将全局变量的作用域限制在了本文件中

2b8ac9bba63fed3a11f869c75606275d.png

3、extern(外部引用类型)

在使用同一程序不同文件的全局变量,通常加extern进行外部引用。

95cbadd2a7c246a54160532a08abe780.png

extern引用语句放在全局,引用到该文件的所有的函数均可访问这个全局变量。

extern引用语句放在局部,仅能在所在函数体内部使用。

b0251ae1bf01238aecc5fee7b8bc2e09.png

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

2858736c3660b1f721a8d7a60c4b7b8f.png

Difference 2: The storage locations of global variables and local variables are different

757f565b490d2f1c770a311ec04b46b0.png

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.

530c34ede5a47592f89dc626d73e40e0.png


(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

654ae8a1fc3e02ded75dced4c695cda7.png

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 = &num;
              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 = &num;
           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;
            }               
           

Guess you like

Origin blog.csdn.net/qq_52049228/article/details/129935370