Loop_for

这篇博客探讨了编程中的循环结构,包括for循环的使用方式,并通过实例展示了如何计算阶乘、斐波那契数列以及判断素数。此外,还提及了两种不同的循环实现,即while循环和for循环的简单示例。
 for(计数器的初始化; 判定条件; 变化规律){
循环体
}

* */
//练习: 求x!
// int x= 10;
// int fac = 1;
// for(int i=1;i<=x;i++){
// fac *=i;
// }
// System.out.println("fac="+fac);

//练习:  求斐波那契数列的第n项值
//                         
//      1   1   2   3   5   8  13  21 
//     a1  a2  a3
//         a1  a2  a3
//             a1  a2  a3
//                 a1  a2  a3 

/*
a1 = 1
a2 = 1
a3 = 2
 
  n-3 次    { 
向后平移
a1=a2
a2=a3
a3 = a1+a2

}*/
// int n = 1;
//用户输入n (-100  0  1  2  4 5  6 )

// if(n>=3){
// int a1 = 1;
// int a2 = 1;
// int a3 = 2;
// for(int i=1; i<=n-3;i++){
// a1=a2; //a1为上次的a2
// a2=a3; //a2 为上次的a3    相当于整体向后平移
// a3 = a1+a2;
// }
// System.out.println("第"+n+"项的值为:"+a3);
//
// }else if(n==1||n==2){
// System.out.println("第"+n+"项的值为:"+1);
//
// }else{
// System.out.println("n>=1");
// }


//练习:1.判定一个整数 n 判定其是否是素数
//   2.输出1~30 间所有的素数  
//     循环 i:1~30
//        每次判定i是否是素数  
//          若是则打印

for(int i=1; i<=30;i++){
//----运算 i是否是素数-------
//能整除的总次数
int count = 0;//循环  i从2到n-1
for(int j=2; j<=i-1; j++){
//判定 若 n%i == 0
if(i%j==0){
//则count++
count++;
}
}

if(count == 0){
System.out.println(i);
}
}


/*------判定给定数是否是素数-------*/
// int n = 97;
// int count = 0;//能整除的总次数
// //循环  i从2到n-1
// for(int i=2; i<=n-1; i++){
// //判定 若 n%i == 0
// if(n%i==0){
// //则count++
// count++;
// }
// }
//
// //循环完了  判定  count==0
// if(count == 0){
// System.out.println("是素数");
// }else{
// System.out.println("不是素数");
// }




// int i=1;
// for (;i<=5; ) {
// System.out.println("*"+i);
// i++;
// }
//
// int count = 1;
// while (count<=5) {
// System.out.println("*"+count);
// count++;
// }
}


}
/* * Copyright 2019 TP-Link Technologies Co., Ltd. All rights reserved. * * */ #include "nano_loop.h" struct nano_loop_context* nano_loop_new(void) { struct nano_loop_context *ctx = osal_malloc(sizeof(struct nano_loop_context)); if (ctx) { memset(ctx, 0, sizeof(struct nano_loop_context)); INIT_LIST_HEAD(&(ctx->timeouts)); } return ctx; } static void nano_loop_run_events(struct nano_loop_context *ctx, int timeout) { struct nano_loop_fd *sock; nano_switch_fd_t fds[NANO_LOOP_MAX_REGISTERED_FDS], fd; SH_INT32 i, ret, len; if (ctx->pending_fds_num <= 0) { for (i = 0; i < ctx->registered_num; i++) fds[i] = ctx->registered_fds[i]->fd; len = ctx->registered_num; ret = nano_switch_select(fds, &len, timeout); if (ret == 0 && len > 0) { ctx->pending_fds_num = len; for (i = 0; i < len; i++) ctx->pending_fds[i] = fds[i]; } } if (ctx->pending_fds_num > 0) { fd = ctx->pending_fds[ctx->pending_fds_num - 1]; ctx->pending_fds_num--; for (i = 0; i < ctx->registered_num; i++) { sock = ctx->registered_fds[i]; if (sock->fd == fd) { sock->cb(sock, NANO_LOOP_READ); /* registered_fds array may be changed in cb, since we need process cb only once, so we must break here */ break; } } } } int nano_loop_fd_add(struct nano_loop_context *ctx, struct nano_loop_fd *sock) { if (sock->registered) nano_loop_fd_delete(sock); if (!ctx) ctx = sock->ctx; else sock->ctx = ctx; if (!ctx || ctx->registered_num >= NANO_LOOP_MAX_REGISTERED_FDS || sock->fd == NULL) return -1; ctx->registered_fds[ctx->registered_num++] = sock; sock->registered = TRUE; return 0; } int nano_loop_fd_delete(struct nano_loop_fd *fd) { int i; if (!fd->registered || !fd->ctx) return 0; fd->registered = FALSE; for (i = 0; i < fd->ctx->registered_num; i++) { if (fd->ctx->registered_fds[i] == fd) { fd->ctx->registered_fds[i] = fd->ctx->registered_fds[fd->ctx->registered_num - 1]; fd->ctx->registered_num--; break; } } return 0; } int nano_loop_timeout_add(struct nano_loop_context *ctx, struct nano_loop_timeout *timeout) { struct nano_loop_timeout *tmp; struct list_head *h; if (timeout->pending) return -1; if (!ctx) ctx = timeout->ctx; else timeout->ctx = ctx; if (!ctx) return -1; h = &(ctx->timeouts); list_for_each_entry(tmp, &(ctx->timeouts), list) { if (tmp->time > timeout->time) { h = &tmp->list; break; } } list_add_tail(&timeout->list, h); timeout->pending = TRUE; return 0; } int nano_loop_timeout_set(struct nano_loop_context *ctx, struct nano_loop_timeout *timeout, int msecs) { if (msecs < 0) return -1; if (timeout->pending) nano_loop_timeout_cancel(timeout); timeout->time = osal_time_ms() + msecs; return nano_loop_timeout_add(ctx, timeout); } int nano_loop_timeout_cancel(struct nano_loop_timeout *timeout) { if (!timeout->pending) return -1; list_del(&timeout->list); timeout->pending = FALSE; return 0; } int nano_loop_timeout_remaining(struct nano_loop_timeout *timeout) { SH_UINT64 tv; if (!timeout->pending) return -1; tv = osal_time_ms(); return timeout->time - tv; } static int nano_loop_get_next_timeout(struct nano_loop_context *ctx, SH_UINT64 tv) { struct nano_loop_timeout *timeout; if (list_empty(&(ctx->timeouts))) return -1; timeout = list_first_entry(&(ctx->timeouts), struct nano_loop_timeout, list); if (timeout->time <= tv) return 0; else return timeout->time - tv; } static void nano_loop_process_timeouts(struct nano_loop_context *ctx, SH_UINT64 tv) { struct nano_loop_timeout *t; while (!list_empty(&(ctx->timeouts))) { t = list_first_entry(&(ctx->timeouts), struct nano_loop_timeout, list); if (t->time > tv) break; nano_loop_timeout_cancel(t); if (t->cb) t->cb(t); } } static void nano_loop_clear_timeouts(struct nano_loop_context *ctx) { struct nano_loop_timeout *t, *tmp; list_for_each_entry_safe(t, tmp, &(ctx->timeouts), list) nano_loop_timeout_cancel(t); } int nano_loop_run(struct nano_loop_context *ctx) { SH_UINT64 tv; ctx->nano_loop_cancelled = FALSE; while (!ctx->nano_loop_cancelled) { tv = osal_time_ms(); nano_loop_process_timeouts(ctx, tv); if (ctx->nano_loop_cancelled) break; tv = osal_time_ms(); nano_loop_run_events(ctx, nano_loop_get_next_timeout(ctx, tv)); } return 0; } void nano_loop_done(struct nano_loop_context *ctx) { if (ctx) { nano_loop_clear_timeouts(ctx); osal_free(ctx); } } 分析一下这些代码的用途和原理
最新发布
12-09
<think>这段代码实现了一个轻量级的事件循环(event loop),类似于libevent或libuv的核心功能,但更为简化。它主要用于处理I/O事件(通过文件描述符)和定时器事件。下面我将分析其主要组件和工作原理。 ### 1. 核心结构体 - `struct nano_loop_context`:事件循环的上下文,包含: - 已注册的文件描述符数组(`registered_fds`)及其数量(`registered_num`)。 - 待处理的文件描述符数组(`pending_fds`)及其数量(`pending_fds_num`)。 - 定时器链表(`timeouts`),按到期时间排序。 - 一个标志`nano_loop_cancelled`用于退出事件循环。 - `struct nano_loop_fd`:代表一个注册的I/O事件,包含文件描述符(`fd`)、回调函数(`cb`)等。 - `struct nano_loop_timeout`:代表一个定时器事件,包含到期时间(`time`)、回调函数(`cb`)等。 ### 2. 主要功能 #### (1) 事件循环的创建和销毁 - `nano_loop_new()`:创建并初始化上下文。 - `nano_loop_done()`:销毁上下文,清理所有定时器并释放内存。 #### (2) 文件描述符事件管理 - `nano_loop_fd_add()`:将一个文件描述符及其回调函数注册到事件循环中。 - `nano_loop_fd_delete()`:从事件循环中删除一个文件描述符。 #### (3) 定时器管理 - `nano_loop_timeout_add()`:将一个定时器添加到事件循环的定时器链表中(按到期时间排序)。 - `nano_loop_timeout_set()`:设置定时器的到期时间(相对当前时间的毫秒数)并添加到事件循环。 - `nano_loop_timeout_cancel()`:取消一个定时器。 - `nano_loop_timeout_remaining()`:获取定时器剩余时间。 #### (4) 事件循环运行 - `nano_loop_run()`:启动事件循环,不断处理定时器事件和I/O事件。 1. 首先处理所有到期的定时器(调用其回调函数)。 2. 然后计算下一个定时器的等待时间,并用于I/O事件等待(通过`nano_switch_select`函数,这是一个类似select的系统调用)。 3. 当有I/O事件就绪时,将其加入待处理数组,然后逐个处理(调用对应的回调函数)。 ### 3. 工作原理 - **定时器处理**:事件循环每次迭代先处理所有已到期的定时器(按时间顺序),然后计算下一个最近定时器的剩余时间,作为I/O事件等待的超时时间。 - **I/O事件处理**:使用`nano_switch_select`等待I/O事件(超时时间取自下一个定时器的剩余时间)。当有事件就绪时,将其放入待处理数组,然后从数组末尾开始逐个处理(注意:处理一个回调后,注册的文件描述符数组可能发生变化,所以每处理一个就退出循环,等待下一次事件循环迭代继续处理)。 - **退出循环**:设置`ctx->nano_loop_cancelled`为真即可退出事件循环。 ### 4. 注意事项 - 该事件循环是单线程的。 - 在处理I/O事件回调时,由于回调函数可能会修改注册的文件描述符数组(比如删除或添加新的描述符),所以每次处理一个就绪事件后就会中断循环(因为数组可能已经改变),留待下一次循环继续处理。 - 定时器链表按到期时间升序排列,所以每次取第一个就是最近要触发的定时器。 ### 潜在问题 - 待处理的I/O事件数组(`pending_fds`)处理方式可能导致事件处理延迟,尤其是当多个事件同时就绪时,每次循环只处理一个事件(从数组末尾取一个),这可能导致其他就绪事件被延迟处理。 - `NANO_LOOP_MAX_REGISTERED_FDS`限制了最大文件描述符数量,可能不够用。 ### 总结 这是一个轻量级的事件循环实现,适用于嵌入式系统或资源受限环境,提供了基本的I/O事件和定时器事件管理。它通过一个简单的select系统调用来处理I/O多路复用,定时器使用链表管理并按时间排序。 §§相关问题§§ 1. 代码中`nano_switch_select`函数的作用是什么?它是如何实现的? 2. 如何优化事件循环以同时处理多个就绪的I/O事件,而不是每次只处理一个? 3. 如果需要在事件循环中处理信号事件,应该如何扩展这个框架? 4. 定时器链表的排序方式(按到期时间升序)在处理大量定时器时可能效率较低,有什么更好的数据结构可以替代链表? 5. 代码中`nano_loop_run_events`函数在处理I/O事件回调后立即跳出循环(break),这样设计的原因是什么?可能会带来什么问题? </think> 这段代码实现了一个轻量级的事件循环框架(Event Loop),类似于libevent或libuv的核心功能,主要用于嵌入式或资源受限环境。以下是核心分析: ### **核心功能** 1. **事件循环管理** - `nano_loop_run()`:主循环函数,持续处理定时器和I/O事件 - 使用`nano_switch_select()`实现I/O多路复用(类似select系统调用) - 通过`nano_loop_cancelled`标志控制循环退出 2. **定时器管理** - **定时器链表**:按到期时间升序排列(`ctx->timeouts`) - `nano_loop_timeout_set()`:设置定时器(计算绝对到期时间) - `nano_loop_process_timeouts()`:触发到期定时器的回调函数 - 支持取消定时器(`nano_loop_timeout_cancel()`) 3. **I/O事件管理** - **文件描述符数组**:管理注册的I/O事件(`ctx->registered_fds`) - `nano_loop_fd_add()`:注册I/O事件及回调函数 - 事件就绪时调用`sock->cb(sock, NANO_LOOP_READ)`通知应用层 ### **工作原理** 1. **事件处理流程**: - 计算最近定时器的剩余时间作为I/O等待超时 - 调用`nano_switch_select()`等待I/O事件 - 优先处理到期定时器 → 再处理就绪的I/O事件 2. **关键设计**: - **定时器优化**:链表按时间排序,快速获取最近到期定时器 - **I/O批处理**:通过`pending_fds`缓存就绪事件,避免每次循环全量扫描 - **回调安全**:处理I/O事件时单次回调后立即退出(防止数组被修改) ### **关键数据结构** ```c struct nano_loop_context { struct nano_loop_fd *registered_fds[NANO_LOOP_MAX_REGISTERED_FDS]; // 注册的I/O事件 nano_switch_fd_t pending_fds[NANO_LOOP_MAX_REGISTERED_FDS]; // 就绪的I/O事件 struct list_head timeouts; // 定时器链表(按到期时间排序) int registered_num; // 当前注册的I/O事件数量 int pending_fds_num; // 当前就绪的I/O事件数量 bool nano_loop_cancelled; // 循环退出标志 }; ``` ### **典型应用场景** 1. 嵌入式网络服务(TCP/UDP事件处理) 2. 设备定时任务调度(如传感器轮询) 3. 资源受限环境的异步操作管理
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值