LinuxC

Linux操作

    磁盘相关命令是在Linux系统中用于管理和查看磁盘空间的命令。以下是一些常用的磁盘相关命令:
1. free命令:用于查看当前系统内存使用情况。
2. df命令:用于查看文件系统的磁盘空间占用情况。
3. du命令:du -sh命令用于统计目录所占磁盘空间的大小。
4. fdisk命令:用于查看磁盘分区情况及对磁盘进行分区管理。使用fdisk命令需要拥有root权限。IDE磁盘命名为hda、hdb,而SCSI硬盘命名为sda、sdb,其中hda1表示第一个IDE硬盘的第一个分区。
文件和目录相关的命令用于管理和操作文件和目录。以下是一些常用的文件和目录命令:
1. ls命令:用于列出文件和目录。通过ls -l命令可以查看文件的详细信息,文件类型可以通过显示的第一个字符来判断。
2. chmod命令:用于改变文件的访问权限。可以使用方法一或方法二来改变权限。
3. chown命令:用于修改文件的所有者和组别。
4. chgrp命令:用于改变文件的组所有权。
5. cat命令:用于查看较短的文档。
6. more命令:适合查看较长的文档,可以通过空格、回车和b来向上或向下查看文档内容,按q退出。
7. less命令:是more命令的增强版,除了支持more命令的操作外,还支持上下箭头进行浏览。
8. grep命令:在指定文件中搜索特定的内容,并将含有这些内容的行输出。通常与管道符号(|)配合使用。
常用的特殊符号包括重定向符号、追加重定向符号和反引号。重定向符号(>)可以将输出内容保存到文件中,如果文件不存在则新建,如果存在则覆盖原文件中的内容。追加重定向符号(>>)将输出内容追加到文件末尾。反引号(``)可以将字符串当成命令来执行。
ln命令用于创建硬链接和软链接。在创建硬链接时,任何一个链接文件的变化都会反映在其他链接文件中。而软链接只会在选定位置上生成文件的镜像,不会重复占用磁盘空间。
find命令用于查找文件和目录。可以根据文件名、文件类型、文件大小等条件来查找符合要求的文件。
常用的find命令选项包括:
- -name:按照文件名进行查找。
- -type:按照文件类型进行查找。
- -size:按照文件大小进行查找。
- -mtime:按照文件修改时间进行查找。
- -exec:对查找到的文件执行特定的操作。
例如,使用find命令查找当前目录下所有以.txt结尾的文件:
find . -name "*.txt"
其中`.`表示当前目录,`-name "*.txt"`表示按照文件名进行查找,`*.txt`表示以.txt结尾的文件。
其他常用的命令还包括:
1. ps命令:用于查看当前系统中正在运行的进程。
2. top命令:用于实时监控系统的运行状态,包括CPU使用率、内存使用率、进程信息等。
3. kill命令:用于终止指定进程。
4. scp命令:用于在本地和远程服务器之间进行文件传输。
5. wget命令:用于从指定的URL下载文件。
6. ssh命令:用于远程登录到其他计算机。
7. tail命令:用于查看文件的末尾内容。
8. head命令:用于查看文件的开头内容。

网络基础知识介绍

在网络中,IP地址是用来唯一标识主机的。它由网络地址和主机地址组成,共32位二进制数字,通常以点分十进制的形式表示(例如:"192.168.12.78")。IP地址分类主要根据网络地址的位数进行划分。
- A类IP地址范围从1.0.0.0到126.255.255.255,其中第一个字节(最高位)始终为0。因此,A类IP地址的网络部分只有一个字节,而主机部分由剩余的三个字节组成。
- B类IP地址范围从128.0.0.0到191.255.255.255,其中前两个字节的最高位都为1。B类IP地址的网络部分由前两个字节组成,主机部分则由后两个字节组成。
- C类IP地址范围从192.0.0.0到223.255.255.255,其中前三个字节的最高位都为1。C类IP地址的网络部分由前三个字节组成,主机部分则由最后一个字节组成。
除了A、B、C三类IP地址之外,还有D类和E类。
- D类IP地址范围从224.0.0.0到239.255.255.255,其中前四个字节的最高位为1110。D类IP地址用于多播,即将数据包发送给一组特定的设备。
- E类IP地址范围从240.0.0.0到247.255.255.255,其中前五个字节的最高位为11110。E类IP地址实际上是保留给未来使用的。
子网掩码是用来划分网络地址和主机地址的一个掩码。对于A、B、C类IP地址,子网掩码的网络地址部分全为1,主机地址部分全为0。例如,对于C类IP地址,子网掩码通常为255.255.255.0。
子网掩码的主要作用是判断主机发送的数据包是要发送到外网还是内网。
网关是一个连接两个或多个网络的节点,实质上是一个路由器,用来转发数据包。当主机要发送数据包到其他网络时,会先将数据包发送到网关,然后由网关负责转发到目标网络。
DNS服务器(域名解析服务器)是用来解析域名和IP地址之间的映射关系的服务器。当我们在浏览器中输入一个域名时,DNS服务器会将域名解析为对应的IP地址,然后根据IP地址来进行网络通信。DNS服务器的作用是帮助我们更方便地访问互联网上的资源。
以上是网络基础知识的介绍,了解这些概念和原理可以帮助我们有效地管理网络和解决网络相关的问题。

shell编程

Shell编程是一种用于编写脚本的编程语言,它主要用于自动化任务和系统管理。以下是对Shell编程的详细论述并给出必要的代码示例:
创建一个.sh文件:
可以使用任何文本编辑器创建一个以".sh"为扩展名的Shell脚本文件,例如"script.sh"。
修改文件的权限:
在Shell脚本文件中,使用`chmod +x *.sh`命令可以修改文件的权限,使其可以执行。
执行:
在终端中,使用`./script.sh`命令来执行Shell脚本文件。
注释:
在Shell脚本中,以"#"开头的行是注释,用于解释代码的目的和功能。以下是一个Shell脚本示例,包含注释:

```bash
#!/bin/bash
# This is a sample script

# Variable:
name="John" # Define a variable named "name"

# Print a greeting:
echo "Hello, $name!" # Print "Hello, John!"
```

变量:
在Shell脚本中,可以使用变量来存储和访问数据。使用`$`符号加上变量名来访问变量的值。以下是一个示例:
```bash
# Variable:
name="John" # Define a variable named "name"
# Accessing variable value:
echo "Hello, $name!" # Print "Hello, John!"
```

位置参数即命令行参数:
使用`$0`、`$1`、`$#`、`$@`、`$*`等特殊变量来引用命令行参数和程序的相关信息。以下是一个示例:
```bash
# Command-line arguments:
echo "Script name: $0"
echo "First argument: $1"
echo "Number of arguments: $#"
echo "All arguments: $@"
echo "All arguments: $*"
echo "Process ID: $$"
echo "Exit status of last command: $?"
```

Shell程序和语句:
Shell编程支持各种语句和命令,用于从键盘读取变量值、进行算术运算、测试条件等。

```bash
# Read variable value from keyboard:
read -p "Enter your name: " name

# Arithmetic operations using "expr" command:
num1=10
num2=5
result=$(expr $num1 + $num2)
echo "Result: $result"

# Test command for string and integer testing:
# String testing:
if [ $name = "John" ]; then
    echo "Welcome, John!"
elif [ $name = "Jane" ]; then
    echo "Welcome, Jane!"
else
    echo "Unknown user!"
fi

# Integer testing:
num=10
if [ $num -gt 0 ]; then
    echo "Number is positive"
fi

# File attribute testing:
file="filename"
if [ -d $file ]; then
    echo "$file is a directory"
fi
```

结构性语句:
Shell编程提供了各种结构性语句来控制程序的执行流程,包括顺序执行语句、选择语句和循环语句。

顺序执行语句:
```bash
# Read input from user:
read -p "Enter your name: " name

# Print output:
echo "Hello, $name!"
```

选择语句:
- 单分支:

```bash
if [ $num -gt 10 ]; then
    echo "Number is greater than 10"
fi
```

- 双分支:

```bash
if [ $num -gt 10 ]; then
    echo "Number is greater than 10"
else
    echo "Number is less than or equal to 10"
fi
```

- 多分支:

```bash
if [ $num -gt 10 ]; then
    echo "Number is greater than 10"
elif [ $num -eq 10 ]; then
    echo "Number is equal to 10"
else
    echo "Number is less than 10"
fi
```

循环语句:
- continue:

```bash
for num in 1 2 3 4 5; do
    if [ $num -eq 3 ]; then
        continue
    fi
    echo $num
done
```
- break:

```bash
for num in 1 2 3 4 5; do
    if [ $num -eq 3 ]; then
        break
    fi
    echo $num
done
```

- for循环:

```bash
# With a list:
for i in 1 2 3 4 5; do
    echo $i
done

# Without a list:
for ((i=1; i<=5; i++)); do
    echo $i
done

# C-style for loop:
for ((i=1; i<=5; i++)); do
    if [ $i -eq 3 ]; then
        continue
    fi
    echo $i
    if [ $i -eq 4 ]; then
        break
    fi
done
```

- while循环:

```bash
counter=1
while [ $counter -le 5 ]; do
    echo $counter
    counter=$((counter + 1))
done
```

函数:
在Shell编程中,可以使用`function_name() { code }`的语法来定义函数,并使用函数名来调用函数。

```bash
# Function definition:
print_hello() {
    echo "Hello"
}

# Function call:
print_hello
```

这些是Shell编程的一些主要概念和语法。还有其他一些重要的概念和语法可以在Shell编程中使用,包括:

- 数组:Shell编程支持数组,可以使用`array_name[index]=value`的语法来定义和访问数组元素。

```bash
# Array definition:
fruits=("apple" "banana" "orange")

# Accessing array elements:
echo ${fruits[0]} # Print "apple"
echo ${fruits[1]} # Print "banana"
echo ${fruits[2]} # Print "orange"

# Looping through array elements:
for fruit in ${fruits[@]}; do
    echo $fruit
done
```

- 输入输出重定向:可以使用`>`和`>>`来将输出重定向到文件,使用`<`来将文件内容作为输入。

```bash
# Redirect output to a file:
echo "Hello, World!" > output.txt

# Append output to a file:
echo "Hello again!" >> output.txt

# Redirect input from a file:
while read line; do
    echo $line
done < input.txt
```

- 管道:可以使用`|`将一个命令的输出作为另一个命令的输入。

```bash
# Pipe output of a command to another command:
ls -l | grep "file"
```

- 条件测试:可以使用`test`命令或方括号`[]`来进行条件测试。

```bash
# Using "test" command:
if test $num -gt 10; then
    echo "Number is greater than 10"
fi

# Using square brackets:
if [ $num -gt 10 ]; then
    echo "Number is greater than 10"
fi
```

- Shell脚本文件:可以将Shell命令和语句保存在一个脚本文件中,并使用`chmod +x script.sh`来使脚本文件可执行。

```bash
# Script file "script.sh":
#!/bin/bash

name="John"
echo "Hello, $name!"

# Run the script:
./script.sh
```


Makefile

1. 定义变量:在Makefile中,可以使用 = 或 := 操作符来定义变量。例如:
   CC = gcc
   CFLAGS := -Wall -O2
   SOURCES = main.c foo.c bar.c
   上述代码定义了三个变量: CC 表示编译器, CFLAGS 表示编译器选项, SOURCES 表示源文件列表。
2. 引用变量:在Makefile中,可以使用 $() 或 ${} 来引用变量的值。例如:
   $(CC) $(CFLAGS) -o myprog $(SOURCES)
   上述代码中, $(CC) 引用了编译器的值, $(CFLAGS) 引用了编译器选项的值, $(SOURCES) 引用了源文件列表的值。
3. 预定义变量:Makefile中还有一些预定义的特殊变量,可以在Makefile中直接使用。常用的预定义变量包括:
   -  $(CC) :C编译器的名称,默认为 cc 。
   -  $(CFLAGS) :C编译器的选项,默认为空。
   -  $(CPPFLAGS) :C预处理器的选项,默认为空。
   -  $(LDFLAGS) :链接器的选项,默认为空。
   -  $(LDLIBS) :链接器的库文件选项,默认为空。
   -  $(RM) :删除文件的命令,默认为 rm -f 。
   例如,可以使用 $(CC) 和 $(CFLAGS) 来指定编译器和编译选项:
   CC = gcc
   CFLAGS = -Wall -O2
4. 变量的扩展:在Makefile中,变量的值可以通过扩展来进行进一步的处理。常用的扩展方式包括:
   -  $(var) :引用变量 var 的值。
   -  $(var:suffix=replacement) :将变量 var 的值中的后缀 suffix 替换为 replacement 。
   -  $(wildcard pattern) :匹配文件名模式 pattern ,返回匹配到的文件列表。
   -  $(shell command) :执行命令 command ,返回命令的输出结果。
   例如,可以使用 $(wildcard) 来获取所有的C源文件:
   SOURCES = $(wildcard *.c)
5. 变量的覆盖:在Makefile中,可以通过重新定义变量的方式来覆盖变量的值。后面定义的变量会覆盖前面定义的变量。例如:
   CC = gcc
   CC = clang
   上述代码中,CC变量的值被覆盖为clang。
    = 与 := 的区别:
    1.  =  赋值操作符:使用 = 进行变量赋值时,变量的值是在变量被引用时才会被扩展。这意味着,如果变量的值在引用之前发生了变化,那么引用该变量的地方也会受到影响。例如:
           VAR = value1
          TARGET = $(VAR)
           VAR = value2
           在上述代码中, TARGET 的值将是 value2 ,因为在引用 $(VAR) 时, VAR 的值已经被更新为 value2 。
    2.  :=  赋值操作符:使用 := 进行变量赋值时,变量的值会立即被扩展并赋给变量。这意味着,变量的值不会受到后续修改的影响。例如:
           VAR := value1
           TARGET := $(VAR)
           VAR := value2
           在上述代码中, TARGET 的值将是 value1 ,因为在赋值 $(VAR) 给 TARGET 时, VAR 的值是 value1 。

C高级


函数指针是C语言中的一种强大特性,它允许将函数作为参数传递给其他函数,或将函数的指针作为返回值。函数指针的声明形式为`return_type (*function_name)(parameter_list)`。以下是几个关于函数指针的代码示例:

```c
// 声明一个返回类型为整型、参数为整型的函数指针
int (*p)(int);

// 使用函数指针进行函数调用
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

int main() {
    int result;
    p = add;
    result = p(5, 3); // 调用add函数,result为8
    p = subtract;
    result = p(5, 3); // 调用subtract函数,result为2
    return 0;
}
```

存储类型用于指定变量的存储位置和生命周期。在C语言中,有4种存储类型:`register`、`auto`、`extern`和`static`。

- `register`用于定义寄存器变量,它将变量存储在CPU的寄存器中,以提高访问速度。
- `auto`是默认的存储类型,用于定义自动变量,它的作用域仅限于定义它的块内。
- `extern`用于修饰全局变量和函数,它表示该变量或函数是在其他地方定义的,需要在当前文件中使用。
- `static`用于修饰全局变量和函数,它表示该变量或函数的作用域仅限于当前文件,其他文件无法访问。

大端存储和小端存储是指不同的数据存储方式。在大端存储中,最高有效字节(MSB)位于最低的内存地址,而最低有效字节(LSB)位于最高的内存地址。在小端存储中,最低有效字节(LSB)位于最低的内存地址,而最高有效字节(MSB)位于最高的内存地址。下面是一个示例:

```c
unsigned int num = 0x12345678;
unsigned char *ptr = (unsigned char *)&num;

if (*ptr == 0x12) {
    printf("Big Endian\n");  // 输出结果:Big Endian
} else {
    printf("Little Endian\n");
}
```

在堆和结构体方面,结构体是一种复合数据类型,用于将多个不同类型的数据组合在一起。可以使用`struct`关键字定义结构体,并使用`.`访问结构体成员。结构体可以包含不同类型的成员变量,也可以包含其他结构体作为成员变量,从而实现结构体的嵌套。

堆是一种动态分配内存的方式,通过调用`malloc`函数可以在堆上分配一块指定大小的内存空间。可以使用指针来管理堆上的内存,通过指针可以访问和操作堆上的数据。在使用完堆上的内存后,需要调用`free`函数释放该内存空间,以防止内存泄漏。

以下是一个结构体嵌套和堆内存分配的示例代码:

```c
#include <stdio.h>
#include <stdlib.h>

struct Date {
    int day;
    int month;
    int year;
};

struct Student {
    char name[20];
    struct Date birthdate;
    int grade;
};

int main() {
    struct Student *ptr;
    ptr = (struct Student *)malloc(sizeof(struct Student));
    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }
    
    strcpy(ptr->name, "John");
    ptr->birthdate.day = 12;
    ptr->birthdate.month = 3;
    ptr->birthdate.year = 2000;
    ptr->grade = 85;
    
    printf("Name: %s\n", ptr->name);
    printf("Birthdate: %d/%d/%d\n", ptr->birthdate.day, ptr->birthdate.month, ptr->birthdate.year);
    printf("Grade: %d\n", ptr->grade);
    
    free(ptr);
    
    return 0;
}
```

以上代码定义了一个`Student`结构体,其中包含一个`Date`结构体作为成员变量。通过动态分配内存,在堆上创建了一个`Student`结构体的实例,并使用指针访问和操作该实例的成员变量。最后,使用`free`函数释放了分配的内存空间。

共用体(Union)是一种特殊的数据类型,它允许在相同的内存位置存储不同的数据类型。共用体的关键字是`union`。

共用体的特点如下:
- 共用体的大小取决于其成员中最大的数据类型。共用体的大小足够容纳其最大的成员。
- 共用体的成员共享同一块内存,即它们在内存中的起始地址是相同的。
- 当给一个成员赋值后,其他成员的值会被覆盖。这是因为共用体的成员共享同一块内存,修改一个成员的值会影响到其他成员。

下面是一个共用体的示例代码:

```c
#include <stdio.h>

union Data {
    int num;
    float avg;
    char name[20];
};

int main() {
    union Data data;
    
    data.num = 10;
    printf("Number: %d\n", data.num);
    
    data.avg = 75.5;
    printf("Number: %d\n", data.num);  // 这里的值被覆盖了
    
    strcpy(data.name, "John");
    printf("Number: %d\n", data.num);  // 这里的值又被覆盖了
    printf("Average: %.2f\n", data.avg);  // 由于共用体的成员共享同一块内存,修改一个成员的值会影响到其他成员
    
    return 0;
}
```

以上代码定义了一个名为`Data`的共用体,它有三个成员变量:`num`、`avg`和`name`。在`main`函数中,我们先给`num`赋值为10,然后打印出来。接着,我们给`avg`赋值为75.5,再次打印`num`的值,发现它被覆盖了。最后,我们使用`strcpy`函数给`name`赋值为"John",再次打印`num`的值,发现它又被覆盖了。这是因为共用体的成员共享同一块内存,修改一个成员的值会影响到其他成员。

需要注意的是,共用体在使用时需要谨慎,确保对共用体的成员赋值和访问的正确性。由于共用体的成员共享同一块内存,对一个成员的修改可能会导致其他成员的值不再有效。因此,在使用共用体时需要保证对共用体的成员的操作是有意义和合法的。

枚举(Enumeration)是C语言中的一种数据类型,用于定义一组具有特定取值的常量。枚举类型的关键字是`enum`。

枚举的特点如下:
- 枚举类型的取值是整数类型,可以进行比较和运算。
- 我们可以显式地为枚举类型的取值指定整数值,也可以让编译器自动分配默认的整数值。

下面是一个枚举的示例代码:

```c
#include <stdio.h>

enum Day {
    MON,
    TUE,
    WED,
    THU,
    FRI,
    SAT,
    SUN
};

int main() {
    enum Day today = WED;
    
    if (today == WED) {
        printf("Today is Wednesday.\n");
    }
    
    return 0;
}
```

以上代码定义了一个名为`Day`的枚举类型,它有七个取值:`MON`、`TUE`、`WED`、`THU`、`FRI`、`SAT`和`SUN`。在`main`函数中,我们定义了一个变量`today`,并将其赋值为`WED`。然后,我们使用条件语句判断`today`的值是否为`WED`,如果是,则打印"Today is Wednesday."。

字节对齐(Byte Alignment)是指在内存中分配变量时,变量的起始地址必须是某个特定值的整数倍。这个特定值通常是变量的数据类型的大小(以字节为单位)。字节对齐的目的是为了提高内存访问的效率,因为大多数计算机体系结构要求数据在特定地址上对齐才能以最快的速度进行读取和写入。

位域(Bit Field)是一种特殊的数据结构,用于在一个字节中存储多个字段。位域可以节省内存空间,特别适用于存储多个开关状态或标志位。位域使用冒号(:)来定义每个字段的位数。

下面是一个位域的示例代码:

```c
#include <stdio.h>

struct Flags {
    unsigned int flag1 : 1;
    unsigned int flag2 : 2;
    unsigned int flag3 : 3;
};

int main() {
    struct Flags flags;
    
    flags.flag1 = 1;
    flags.flag2 = 2;
    flags.flag3 = 3;
    
    printf("flag1: %d\n", flags.flag1);
    printf("flag2: %d\n", flags.flag2);
    printf("flag3: %d\n", flags.flag3);
    
    return 0;
}
```

以上代码定义了一个名为`Flags`的结构体,它有三个位域成员变量:`flag1`、`flag2`和`flag3`。在`main`函数中,我们创建了一个`Flags`结构体的实例,并给每个位域成员赋值。然后,我们打印出每个位域成员的值。

递归(Recursion)是指一个函数调用自身的过程。递归可以用于解决一些问题,特别是那些可以通过重复调用自身来缩小问题规模的问题。递归函数必须具有终止条件,否则会导致无限递归。

下面是一个递归的示例代码:

```c
#include <stdio.h>

int factorial(int n) {
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}

int main() {
    int n = 5;
    int result = factorial(n);
    
    printf("Factorial of %d is %d\n", n, result);
    
    return 0;
}
```

以上代码定义了一个名为`factorial`的递归函数,用于计算一个数的阶乘。在`main`函数中,我们调用`factorial`函数来计算5的阶乘,并将结果打印出来。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值