知识点归纳4

1、串口类型:TTL \rs232 \rs422 \rs48

串口有不同的分类: 
        TTL: TTL电平串口 
            Tx  数据发送端口
            Rx  数据接收端口
            Vcc 电源端口 
            Gnd 接地端口,通信的双方必须共地
       常见的分类: 
            RS-232、RS-422、RS-485
            不同的串口分类,引脚的个数也不一样
            不同的电气标准的串口的区别如下:
                         TTL            RS-232          RS-422        RS-485      
高电平           3.3V/5V        -3v~-15V          +2V             +1.5v
低电平               0v            +3v~+15V          -2v              -1.5v 
信号              单端信号       单端信号       差分信号       差分信号
传输长度          <2m             <15m           <1200m         <1200m

ps:差分信号:是指两根线传输的信号,传输的是两根线之前的电压差。受干扰能力强,传输距离远。

RS232和RS485是串行通信协议。RS232是一种点对点的单向通信协议,通常用于连接计算机和串口设备之间的数据传输。它使用单个信号线进行传输,可达到最大传输距离约15米。

而RS485则是一种多点半双工通信协议,适用于连接多个设备进行数据通信。它使用两个信号线进行传输,可以在一个总线上同时连接多个设备,每个设备都有唯一的地址。最大传输距离可达1200米,且具有传输速度快、抗干扰能力高等特点,因此被广泛应用于工业自动化控制领域。

2、栈和队列的区别

栈和队列都是常用的数据结构,它们的主要区别在于数据的插入和删除顺序。

栈 (Stack) 是一种后进先出 (Last-In-First-Out, LIFO) 的数据结构,只允许在一端进行插入和删除操作,这一端称为栈顶。新元素插入后成为新的栈顶,而删除时也只能删除栈顶元素。

队列 (Queue) 是一种先进先出 (First-In-First-Out, FIFO) 的数据结构,允许在两端进行插入和删除操作,插入在队尾,删除在队头。新元素插入时成为新的队尾,而删除时也只能删除队头元素。

除了操作顺序不同,栈和队列还有其他一些不同:

  1. 空间分配不同:在栈中,所有元素都在同一个连续的内存块中,因此栈的空间分配比较简单。而在队列中,元素通常分布在不同的内存块中,因此队列的空间分配比较复杂。

  2. 插入和删除性能不同:由于栈的操作顺序是后进先出,因此在栈中插入或删除操作只涉及到栈顶元素,而在队列中因为是先进先出,每一次插入或删除操作都可能影响到队头或队尾的元素。因此队列的插入和删除操作通常比栈慢。

  3. 应用场景不同:栈通常用于递归算法,表达式求值、内存分配等场合。而队列则通常用于任务调度、缓存队列、消息队列等需要按顺序处理多个任务的场合。

3、静态变量和静态函数都有什么特点

静态变量和静态函数都是C语言中的关键字,它们具有以下特点:

1. 静态变量

静态变量是一种在程序运行期间分配存储空间的变量,它的生存期与程序的生存期相同。与自动变量(函数内声明的局部变量)不同的是,静态变量在同一程序执行期间一直存在,不会在每次函数调用时重新分配内存。

静态变量有以下特点:

- 只会被初始化一次,在第一次执行到定义它的语句时进行初始化;
- 在函数结束后,它的值不会销毁,可以在下一次函数调用时使用;
- 静态变量的作用域只限于定义它的文件,其他文件无法访问。

2. 静态函数

静态函数是一种只在定义它的源文件中可见,不可被其他源文件调用的函数。与全局函数和外部函数相比,静态函数具有以下特点:

- 作用域只是限于定义它的源文件中,其他源文件无法访问;
- 编译器可以对静态函数作出更多优化,因为它不需要考虑其他文件中的调用关系;
- 静态函数对外部变量的影响范围更小,增强了程序模块的独立性和封装性。

静态函数一般用于只在一个文件中使用的辅助函数。

4、c语言的内存分为几种类型

C语言的内存可以分为以下几种类型:

1. 栈(Stack)内存

栈内存是由编译器自动分配和释放的内存区域,用来存储函数中的所有局部变量和函数返回地址。栈内存分配速度较快,但是大小有限制,同时在函数返回后,分配的栈内存会自动释放。因此,栈内存适合用来存储临时变量和函数的返回值。

2. 堆(Heap)内存

堆内存是由程序员手动申请和释放的内存区域,用来存储大的数据结构和动态分配的内存。堆内存分配速度较慢,但是大小具有灵活性,并且在程序运行期间可随时增加或减少。因此,堆内存适合用来存储动态分配的内存块,例如链表、数组等。

3. 全局(Global)内存

全局内存是在程序运行期间一直存在的内存区域,用来存储程序中的全局变量和静态变量。全局内存在程序启动时由操作系统分配,在程序结束后才会被释放。因此,全局内存适合用来存储长期存在的变量和数据。

4. 常量(Constant)内存

常量内存是用来存储程序中的常量数据,例如字符串常量、数字常量等。常量内存通常存储在只读内存区域中,程序无法修改其中的值。常量内存也可以存储在代码段中,这样可以节约内存空间。

总的来说,C语言的内存可以分为栈内存、堆内存、全局内存和常量内存,每种内存都有其特定的用途和限制。程序员需要根据实际情况选择合适的内存分配方式。

5、c语言全局变量分配在哪里?

C语言中的全局变量存储在静态存储区,静态存储区又称为全局数据区或全局区。静态存储区是由编译器在程序启动时分配的内存区域,其大小是程序编译时确定的。在静态存储区中声明的变量在程序的整个运行期间都存在,并且在程序启动时就已经初始化。

静态存储区由两部分组成:

1. 数据段(Data Segment)

数据段用于存储程序中已经初始化的全局变量和静态变量。数据段中的变量在程序启动时就已经分配了内存空间,变量的初值都已经确定。数据段的大小由程序中已经初始化的全局变量和静态变量的总大小决定。

2. BSS段

BSS段用于存储程序中未初始化的全局变量和静态变量。BSS段中的变量在程序启动时没有实际的值,操作系统会为其分配一段空间,并在内部设置为0。因此,BSS段中的变量会占用一定的内存空间,但不会占用程序的可执行文件的磁盘空间。BSS段的大小由程序中未初始化的全局变量和静态变量的总大小决定。

总的来说,C语言中的全局变量存储在静态存储区中,静态存储区由数据段和BSS段组成,全局变量的存储位置取决于变量是否被初始化。已经初始化的全局变量存储在数据段中,未初始化的全局变量存储在BSS段中。

6、异步io和同步io有什么区别? 

同步 IO 和异步 IO 是关于数据读写方式的两种不同模式。

同步 IO 是指在程序读写数据时,需要等待操作完成后才能继续执行后面的程序。这种模式下,当程序使用阻塞式 IO 时,会一直等待IO操作完成,程序会暂停执行,直至IO操作完成,这样会导致程序的执行效率降低。同步 IO 主要用于小型程序,如批处理作业,简单计算和查询程序等。

异步 IO 是指在进行数据读写操作时,程序无需等待 IO 操作完成。异步 IO 使得程序可以在 IO 操作的同时执行其他操作,提高了程序的执行效率。异步 IO 主要用于高并发场景,如 Web 服务器、数据库访问等。

总结起来,异步 IO 与同步 IO 主要的区别在于对 IO 操作的处理方式,同步 IO 要求在读写数据时对操作完成做出响应后再继续程序执行,异步 IO 则不需要这样做,使得程序能够更为高效的利用 CPU 资源。

7、Linux下的多播

在Linux下使用C语言进行多播,需要以下几个步骤:

1. 创建套接字

使用`socket()`系统调用创建一个UDP套接字,并设置它的选项以启用多播。例如:


int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
    perror("socket");
    exit(1);
}

int yes = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
    perror("setsockopt");
    exit(1);
}

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT);

if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    perror("bind");
    exit(1);
}
 

这里假设要发送到的目标地址为`224.0.0.1`,端口号为`PORT`。

2. 设置多播组

使用`setsockopt()`函数将套接字加入到多播组中。例如:

```c
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.1");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
    perror("setsockopt");
    exit(1);
}
```

3. 发送数据

使用`sendto()`函数向指定的多播地址发送数据。例如:

```c
char *msg = "hello world";
int len = strlen(msg);

struct sockaddr_in mulAddr;
memset(&mulAddr, 0, sizeof(mulAddr));
mulAddr.sin_family = AF_INET;
mulAddr.sin_addr.s_addr = inet_addr("224.0.0.1");
mulAddr.sin_port = htons(PORT);

if (sendto(sock, msg, len, 0, (struct sockaddr *)&mulAddr, sizeof(mulAddr)) < 0) {
    perror("sendto");
    exit(1);
}
```

这里的`msg`是要发送的数据,`

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值