简单实现注释转换(/* */)→(//)

本文档介绍如何在C语言中实现将/* */注释转换为//注释。通过分析文件内容,处理不同状态,利用枚举类型表示状态转换,并提供相关代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这只是简单实现,将一个正确代码中的注释进行转换,如果代码里面有错误的话,可能会出现问题,比如出现了 /* 但是不出现 */ 如果这时候文件结束了,这样注释转换就会出错,所以转换前,应先保证注释的正确性。(以下情况均是在注释正确的情况下进行)
话不多说,进入正题。
先分析一波:

我们读取一个.c文件时,第一个可能读取到的字符可能有 / 、正常代码、和EOF(文件为空,直接为文件尾)

  • 当读到正常代码时,直接将正常代码写入到新的文档中即可。
  • 当读到EOF时,代表文件读完,返回即可。
  • 当读到/时,分为两种情况:

    • / 的下一位为/ 这时,就是//注释,它不需要转换,直接写入文档即可。
    • /的下一位为* 这时,就是/*注释,它需要转换。
      而上面这两种情况对于读取到的字符的处理方式又不同,所以到时候需要再写两个函数来处理它们。

首先,我们将这几种情况用枚举类型罗列出来:

    typedef enum State
{
    NUL_State,           //无状态,即正常代码状态
    C_State,               //C注释状态,即 /*  */ 注释状态
    CPP_State,         //C++注释状态,即 // 注释状态
    END_State            //结束状态,即读取到文件结尾
}State;

我们可以将它们几种状态的转换关系再画出来:
这里写图片描述
黑色的字体为状态之间转换的条件。

接下来,我们用代码来实现:
采用多文件编译的方式:

CommentConvert.h
#ifndef __CommentConvert_H__
#define __CommentConvert_H__

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

typedef enum State
{
    NUL_State,
    C_State,
    CPP_State,
    END_State
}State;

void CommentConvert(FILE *PRead, FILE *PWrite);         //注释转换

void DO_NUL_State(FILE *PRead, FILE *PWrite, State *PState);    //无状态执行操作

void DO_C_State(FILE *PRead, FILE *PWrite, State *PState);     //c注释状态执行操作 /*

void DO_CPP_State(FILE *PRead, FILE *PWrite, State *PState);   //c++状态执行操作  //

#endif // !__CommentConvert_H__

CommentConvert.c
#include"CommentConvert.h"



void CommentConvert(FILE *PRead, FILE *PWrite)
{
    //状态机  多个状态
    //   无状态  c注释状态   c++状态   eof状态
    State state = NUL_State;
    while (state != END_State)         //当文件未读完时
    {
        switch (state)
        {
            case NUL_State:
                DO_NUL_State(PRead, PWrite, &state);
                break;
            case C_State:
                DO_C_State(PRead, PWrite, &state);
                break;
            case CPP_State:
                DO_CPP_State(PRead, PWrite, &state);
                break;  
        }
    }   
}


void DO_NUL_State(FILE *PRead, FILE *PWrite, State *PState)
{
    int first = fgetc(PRead);
    switch (first)
    {
        case '/':                  //注释的开始
        {
            int second = fgetc(PRead);
            switch (second)
            {
                //      // /* 
                case'*':                          //c注释开始
                {
                    fputc('/', PWrite);
                    fputc('/', PWrite);
                    *PState = C_State;
                }
                    break;
                case'/':                        //c++注释开始
                {
                    fputc(first, PWrite);
                    fputc(second, PWrite);
                    *PState = CPP_State;
                }
                    break;
                default:                      //正常读到代码即 2/3 等情况 
                {
                    fputc(first, PWrite);
                    ungetc(second, PRead);
                }
                    break;  
            }
        }
            break;
        case EOF:                  //文件的结束
            *PState = END_State;
            break;
        default:                    //正常代码
        {
            fputc(first, PWrite);
        }
            break;
    }
}


void DO_C_State(FILE *PRead, FILE *PWrite, State *Pstate)       //c注释的处理
{
    int first = fgetc(PRead);
    //        a   */   **/    */i
    switch (first)
    {
        case '*':
        {
            int second = fgetc(PRead);
            switch (second)
            {
                case '/':                          //c注释结束
                {
                    int third = fgetc(PRead);
                    if (third == '\n')
                    {
                        fputc(third, PWrite);
                    }
                    else                        //考虑到连续两个c注释的问题 比如  /* int a = 1; */  /* int b = 1;*/   将它们放在两行
                    {
                        fputc('\n', PWrite);
                        ungetc(third, PRead);
                    }
                    *Pstate = NUL_State;
                }
                    break;
                case '*':                      //   **/  ******/   等问题
                {
                    fputc(first, PWrite);
                    ungetc(second, PRead);
                }
                    break;
                default:                      //正常读到代码
                {
                    fputc(first, PWrite);
                    ungetc(second, PRead);
                }
                    break;
            }
        }
            break;
        case '\n':             //多行注释
        {
            fputc(first, PWrite);
            fputc('/', PWrite);
            fputc('/', PWrite);
        }
            break;
        default:
        {
            fputc(first, PWrite);
        }
            break;
    }
}


void DO_CPP_State(FILE *PRead, FILE *PWrite, State *PState)
{
    int first = fgetc(PRead);
    switch (first)
    {
        case '\n':                       //c++注释结束
        {
            fputc(first, PWrite);
            *PState = NUL_State;
        }
            break; 
        case EOF:                 //文件尾
            *PState = END_State;
            break;
        default:                         //正常读到代码
            fputc(first, PWrite);
            break;

    }
}
test.c
#include"CommentConvert.h"


void test()
{
    FILE *PRead = fopen("input.c", "r");
    if (PRead == NULL)
    {
        perror("error for PRead ");
        exit(EXIT_FAILURE);
    }
    FILE *PWrite = fopen("output.c", "w");  
    if (PRead == NULL)
    {
        perror("error for PWrite ");
        exit(EXIT_FAILURE);
    }
    CommentConvert(PRead, PWrite);
    fclose(PRead);
    PRead = NULL;
    fclose(PWrite);
    PWrite = NULL;
}

int main()
{
    test();
    return 0;
}

测试代码 input.c


2/3           //代码中只出现一个/的情况
/*这是一段代码
  这段代码只用作测试
  注释为添加的各种情况
*/int Fib(int n)         
{
    int ret = 0;   /*//ret为返回值//*/int i = 0;
    int count0 = 1;  /***count0为第n-2个fib的值***/
    int count1 = 0;  /***count0为:***/ /*第n-2个fib的值***/
    for (i = 0; i < n; i++)   //  /*从第一个开始计算*/
    {
        //从第一个
        //开始
        /*计算ret的值。*/ret = count0 + count1;
        count0 = count1;    /*让count0跟着i变化/**/
        count1 = ret;
    }
    return ret;       //返回求得的第n个fib的值   /**/
}

测试结果:

这里写图片描述

我们也可以将前面的流更改为标准的输入输出流,这样我们就可以在cmd窗口里输入并显示输出了,不过它的显示是输入一行输出一行,所以看起来可能不是很容易,不过原理与前面代码相同。

以上即为实现注释转换的全部内容,不足之处还望指正。
{ /* 0 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_TX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_TX_Disable] */ { /* 1 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_TX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_TX_EnableNoinit] */ { /* 2 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_RX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_RX_Disable] */ { /* 3 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_RX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_RX_EnableNoinit] */ { /* 4 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_RX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_RX_Disable] */ { /* 5 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_RX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_RX_EnableNoinit] */ { /* 6 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_Disable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_Disable_DM] */ { /* 7 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_Enable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_Enable_DM] */ { /* 8 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_RX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_RX_Disable] */ { /* 9 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_RX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_RX_EnableNoinit] */ { /* 10 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_Disable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_Disable_DM] */ { /* 11 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_Enable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_Enable_DM] */ { /* 12 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_TX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_TX_Disable] */ { /* 13 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_TX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_TX_EnableNoinit] */ { /* 14 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_TX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_TX_Disable] */ { /* 15 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_TX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_04_MAPPING_d1cfcc6c_TX_EnableNoinit] */ { /* 16 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_Disable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_Disable_DM] */ { /* 17 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_Enable_DM }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_00_MAPPING_b2c42696_Enable_DM] */ { /* 18 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_TX_Disable }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_TX_Disable] */ { /* 19 */ BswM_ActionList_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_TX_EnableNoinit }, /* [Priority: 0] */ /* [AL_CC_AL_WMI_D_HEADUNIT1_2p4my5eqkne6nszvtvuda3zjh_72af7b72_PNC_08_MAPPING_d3a845f4_TX_EnableNoinit] */ { /* 20 */ BswM_ActionList_ESH_AL_ExitRun }, /* [Priority: 0] */ /* [AL_ESH_AL_ExitRun] */ { /* 21 */ BswM_ActionList_ESH_AL_RunToPostRun }, /* [Priority: 0] */ /* [AL_ESH_AL_RunToPostRun] */ { /* 22 */ BswM_ActionList_ESH_AL_WaitForNvMToShutdown }, /* [Priority: 0] */ /* [AL_ESH_AL_WaitForNvMToShutdown] */ { /* 23 */ BswM_ActionList_ESH_AL_WakeupToPrep }, /* [Priority: 0] */ /* [AL_ESH_AL_WakeupToPrep] */ { /* 24 */ BswM_ActionList_ESH_AL_WaitForNvMWakeup }, /* [Priority: 0] */ /* [AL_ESH_AL_WaitForNvMWakeup] */ { /* 25 */ BswM_ActionList_ESH_AL_WakeupToRun }, /* [Priority: 0] */ /* [AL_ESH_AL_WakeupToRun] */ { /* 26 */ BswM_ActionList_ESH_AL_DemInit }, /* [Priority: 0] */ /* [AL_ESH_AL_DemInit] */ { /* 27 */ BswM_ActionList_ESH_AL_InitToWakeup }, /* [Priority: 0] */ /* [AL_ESH_AL_InitToWakeup] */ { /* 28 */ BswM_ActionList_ESH_AL_PostRunToPrepShutdown }, /* [Priority: 0] */ /* [AL_ESH_AL_PostRunToPrepShutdown] */ { /* 29 */ BswM_ActionList_ESH_AL_ESH_PostRunToPrepCheck }, /* [Priority: 0] */ /* [AL_ESH_AL_ESH_PostRunToPrepCheck] */ { /* 30 */ BswM_ActionList_ESH_AL_PostRunToRun }, /* [Priority: 0] */ /* [AL_ESH_AL_PostRunToRun] */ { /* 31 */ BswM_ActionList_ESH_AL_ExitPostRun }, /* [Priority: 0] */ /* [AL_ESH_AL_ExitPostRun] */ { /* 32 */ BswM_ActionList_ESH_AL_PrepShutdownToWaitForNvM }, /* [Priority: 0] */ /* [AL_ESH_AL_PrepShutdownToWaitForNvM] */ { /* 33 */ BswM_ActionList_INIT_AL_Initialize } /* [Priority: 0] */ /* [AL_INIT_AL_Initialize] */
最新发布
08-16
/** * @file ProximitySwitchControl.cpp * @brief 此程序用于通过接近开关控制四个电磁阀的开启和关闭顺序,并设置每个电磁阀的单独开启时间 */ #include <Servo.h> // // 接近信号输入引脚// 运行状态枚举 enum SystemState { IDLE, OPENING_VALVES, HOLDING_OPEN, CLOSING_VALVES, EMERGENCY_STOP }; const int proximityPin = 6; // 电磁阀控制引脚 const int valvePins[] = {9,10,11,12}; /** * @brief 定义存储电磁阀控制引脚的数组 */ // 开启顺序(对应valvePins索引) int openOrder[] = {0,1,2,3}; /** * @brief 定义电磁阀的开启顺序数组 */ // 关闭顺序(对应valvePins索引) int closeOrder[] = {3,1,2,0}; /** * @brief 定义电磁阀的关闭顺序数组 */ // 运行状态标志 bool isRunning = false; /** * @brief 表示当前控制序列是否正在运行的标志,初始为false */ // 上一次接近开关状态 bool lastProxState = HIGH; /** * @brief 用于存储上一次读取的接近开关状态 */ // 消抖时间戳 unsigned long debounceTime = 0; /** * @brief 记录上次检测到接近开关状态变化的时间,用于消抖处理 */ // 每个电磁阀的单独开启时间(毫秒) int openTimes[] = {500, 500, 500, 900}; /** * @brief 定义每个电磁阀的单独开启时间数组 */ /** * @brief 初始化设置函数 */ void setup() { // 循环设置电磁阀引脚为输出,并初始化为低电平 for(int i=0; i<4; i++) { pinMode(valvePins[i], OUTPUT); digitalWrite(valvePins[i], LOW); } /** * @brief 为每个电磁阀引脚设置模式为输出,并将初始状态设置为低电平 */ // 设置接近开关引脚为上拉输入 pinMode(proximityPin, INPUT_PULLUP); /** * @brief 将接近开关引脚设置为上拉输入模式 */ } /** * @brief 主循环函数 / void loop() { int currentProxState = digitalRead(proximityPin); /* * @brief 读取当前接近开关的状态 */ // 带消抖的下降沿检测 if(!isRunning && (millis() - debounceTime) > 50){ /** * @brief 检查是否处于未运行状态且经过了足够的消抖时间 / if(lastProxState == HIGH && currentProxState == LOW){ /* * @brief 检测到接近开关从高电平变为低电平(下降沿) / isRunning = true; debounceTime = millis(); /* * @brief 设置运行标志为true,并更新消抖时间 / // 运行控制序列 if(runSequence()) { /* * @brief 调用控制序列函数,如果成功则进行后续处理 / isRunning = false; /* * @brief 控制序列完成,将运行标志设置为false / } else { /* * @brief 控制序列运行失败,进行错误处理 */ // 可以在这里添加错误处理代码,如输出错误信息或采取其他措施 Serial.println(“Control sequence failed.”); 完善这代码,不要看门狗
03-25
C语言的注释分为两种,第一种:在一行源代码中“//”后的内容为注释内容。第二种:“/*”与“*/”之间的内容为注释内容。第三种:程序中只出现了“/*”,没有“*/”与之对应,那么将“/*”后的全部内容都要过滤掉。注意,只要是注释内容,那么注释内容中的字符应该全部忽略,即不起任何的作用。例如“/*”与“*/”之间如果再有“//”,那么“//”不应起作用;如果“//”再有“/*”,那么“/*”也不应起作用。 你的任务是先打开一个名字为dict.dic的文本文件,该文件中前5行每行为1个整数,从第6行开始为5段C语言的源代码。那5个数字代表这5段源代码结束的行数,比如如果第一行的整数为20,第二行的整数为60,则表示从第6行到第20为第一段代码,从第21行到第60为第二段代码。然后根据输入要求将源代码中所有注释过滤掉。 在本过滤注释系统中,你可以忽略源文件中双引号导致“//”、“/*”、“*/”失去作用的情况,即只要“//”、“/*”、“*/”不是注释内容,在任何情况下都起作用。 输入 只可能是1,2,3,4,5之一 输出 输入为1则输出第一段代码过滤后的结果,输入为2则输出第二段代码过滤后的结果,依此类推。 样例输入 Copy 1 样例输出 Copy 如果第一段代码是这样: /* @Author: BUPT @Date: 2010 8 26 */ #include<stdio.h> int main() { int a = 10 , b = 2 , c ; c = a / b ; //I just want to test '/' printf("I love programming C.\n") ; //"printf" is a useful function /* printf("I hope you love it too!\n") ; /* //C is not always hard , if you love it , it will not treat you rough. */ return 0 ; } 则输出是这样: #include<stdio.h> int main() { int a = 10 , b = 2 , c ; c = a / b ; printf("I love programming C.\n") ; printf("I hope you love it too!\n") ; return 0 ; }
05-12
那如果要用来配置ADC读取电压,该怎么配置ADC_GetFlagStatus(ADCx, ADC_FLAG_RSTCAL)和ADC_GetFlagStatus(ADCx, ADC_FLAG_CAL)的 参数 /** * @brief Checks whether the specified ADC flag is set or not. * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. * @param ADC_FLAG: specifies the flag to check. * This parameter can be one of the following values: * @arg ADC_FLAG_AWD: Analog watchdog flag * @arg ADC_FLAG_EOC: End of conversion flag * @arg ADC_FLAG_JEOC: End of injected group conversion flag * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag * @arg ADC_FLAG_STRT: Start of regular group conversion flag * @arg ADC_FLAG_OVR: Overrun flag * @retval The new state of ADC_FLAG (SET or RESET). */ FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) { FlagStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); /* Check the status of the specified ADC flag */ if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) { /* ADC_FLAG is set */ bitstatus = SET; } else { /* ADC_FLAG is reset */ bitstatus = RESET; } /* Return the ADC_FLAG status */ return bitstatus; } /** * @brief Checks whether the specified ADC flag is set or not. * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral. * @param ADC_FLAG: specifies the flag to check. * This parameter can be one of the following values: * @arg ADC_FLAG_AWD: Analog watchdog flag * @arg ADC_FLAG_EOC: End of conversion flag * @arg ADC_FLAG_JEOC: End of injected group conversion flag * @arg ADC_FLAG_JSTRT: Start of injected group conversion flag * @arg ADC_FLAG_STRT: Start of regular group conversion flag * @arg ADC_FLAG_OVR: Overrun flag * @retval The new state of ADC_FLAG (SET or RESET). */ FlagStatus ADC_GetFlagStatus(ADC_TypeDef* ADCx, uint8_t ADC_FLAG) { FlagStatus bitstatus = RESET; /* Check the parameters */ assert_param(IS_ADC_ALL_PERIPH(ADCx)); assert_param(IS_ADC_GET_FLAG(ADC_FLAG)); /* Check the status of the specified ADC flag */ if ((ADCx->SR & ADC_FLAG) != (uint8_t)RESET) { /* ADC_FLAG is set */ bitstatus = SET; } else { /* ADC_FLAG is reset */ bitstatus = RESET; } /* Return the ADC_FLAG status */ return bitstatus; }
07-04
#include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define MM 8 /* RS code over GF(2**8) */ #define KK 239 /* Number of information symbols */ #define NN 255 /* Total codeword length */ #define TT 8 /* Error correction capability */ int alpha_to[NN + 1]; /* Exponent to element mapping */ int index_of[NN + 1]; /* Element to exponent mapping */ int gg[NN - KK + 1]; /* Generator polynomial */ int recd[NN]; /* Received codeword */ int err_flag; /* Error flag */ int data[KK], bb[NN - KK]; /* Data and parity symbols */ /* GF multiplication */ int gf_mult(int a, int b) { if (a == 0 || b == 0) return 0; return alpha_to[(index_of[a] + index_of[b]) % NN]; } /* GF inverse */ int gf_inv(int a) { if (a == 0) return 0; return alpha_to[(NN - index_of[a]) % NN]; } /* Generate GF(2^8) */ void generate_gf() { int pp[9] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 }; /* Primitive polynomial */ register int i, mask = 1; alpha_to[MM] = 0; for (i = 0; i < MM; i++) { alpha_to[i] = mask; index_of[alpha_to[i]] = i; if (pp[i] != 0) alpha_to[MM] ^= mask; mask <<= 1; } index_of[alpha_to[MM]] = MM; mask >>= 1; for (i = MM + 1; i < NN; i++) { if (alpha_to[i - 1] >= mask) alpha_to[i] = alpha_to[MM] ^ ((alpha_to[i - 1] ^ mask) << 1); else alpha_to[i] = alpha_to[i - 1] << 1; index_of[alpha_to[i]] = i; } index_of[0] = -1; } /* Generate generator polynomial */ void gen_poly() { register int i, j; gg[0] = 2; /* α^1 */ gg[1] = 1; /* g(x) = x + α^1 */ for (i = 2; i <= NN - KK; i++) { gg[i] = 1; for (j = i - 1; j > 0; j--) { if (gg[j] != 0) gg[j] = gg[j - 1] ^ alpha_to[(index_of[gg[j]] + i) % NN]; else gg[j] = gg[j - 1]; } gg[0] = alpha_to[(index_of[gg[0]] + i) % NN]; } /* Convert to index form */ for (i = 0; i <= NN - KK; i++) gg[i] = index_of[gg[i]]; } /* RS encoding */ void encode_rs() { register int i, j; int feedback; for (i = 0; i < NN - KK; i++) bb[i] = 0; for (i = KK - 1; i >= 0; i--) { feedback = index_of[data[i] ^ bb[NN - KK - 1]]; if (feedback != -1) { for (j = NN - KK - 1; j > 0; j--) { if (gg[j] != -1) bb[j] = bb[j - 1] ^ alpha_to[(gg[j] + feedback) % NN]; else bb[j] = bb[j - 1]; } bb[0] = alpha_to[(gg[0] + feedback) % NN]; } else { for (j = NN - KK - 1; j > 0; j--) bb[j] = bb[j - 1]; bb[0] = 0; } } } /* Compute polynomial degree */ int poly_degree(int poly[], int len) { int deg = -1; for (int i = len - 1; i >= 0; i--) { if (poly[i] != 0) { deg = i; break; } } return deg; } /* Polynomial multiplication with mod x^limit */ void poly_mult(int a[], int a_deg, int b[], int b_deg, int result[], int limit) { for (int i = 0; i < limit; i++) result[i] = 0; for (int i = 0; i <= a_deg; i++) { if (a[i] != 0) { for (int j = 0; j <= b_deg && i + j < limit; j++) { if (b[j] != 0) { result[i + j] ^= gf_mult(a[i], b[j]); } } } } } /* Copy polynomial */ void copy_poly(int src[], int dest[], int len) { for (int i = 0; i < len; i++) { dest[i] = src[i]; } } /* RS decoding with Euclidean algorithm */ void decode_rs() { int s[NN - KK + 1]; /* Syndrome values */ int root[TT], loc[TT], err[NN]; int erasures[2 * TT]; /* Erasure positions */ int erasure_count = 0; /* Number of erasures */ int syn_error = 0; /* Syndrome error flag */ register int i, j; /* Erasure detection */ for (i = 0; i < NN; i++) { if (recd[i] == -1 && erasure_count < 2 * TT) { erasures[erasure_count++] = i; } } /* Syndrome calculation */ for (i = 1; i <= NN - KK; i++) { s[i] = 0; for (j = 0; j < NN; j++) { if (recd[j] == -1) continue; if (recd[j] != 0) { int exp = (index_of[recd[j]] + i * j) % NN; if (exp < 0) exp += NN; s[i] ^= alpha_to[exp]; } } if (s[i] != 0) syn_error = 1; s[i] = (s[i] == 0) ? -1 : index_of[s[i]]; } if (syn_error || erasure_count > 0) { err_flag = 1; /* Allocate memory for polynomials */ int gamma[NN - KK + 1] = { 0 }; /* Erasure locator polynomial */ int T[NN - KK] = { 0 }; /* Modified syndrome polynomial */ int max_deg = 2 * (NN - KK) + 1; /* 33 */ int R0[65] = { 0 }; int R1[65] = { 0 }; int V0[65] = { 0 }; int V1[65] = { 0 }; int lambda[NN - KK + 1] = { 0 };/* Error locator polynomial */ int omega[NN - KK] = { 0 }; /* Error evaluator polynomial */ /* Initialize gamma = 1 (erasure locator polynomial) */ gamma[0] = 1; if (erasure_count > 0) { for (i = 0; i < erasure_count; i++) { int Xi = alpha_to[erasures[i] % NN]; int tmp[NN - KK + 1] = { 0 }; tmp[0] = gamma[0]; for (j = 1; j <= NN - KK; j++) { tmp[j] = gamma[j] ^ gf_mult(Xi, gamma[j - 1]); } for (j = 0; j <= NN - KK; j++) { gamma[j] = tmp[j]; } } } /* Convert syndrome to polynomial form */ int S_poly[NN - KK]; for (i = 0; i < NN - KK; i++) { if (s[i + 1] == -1) { S_poly[i] = 0; } else { S_poly[i] = alpha_to[s[i + 1]]; } } /* Compute modified syndrome T(x) = S(x) * gamma(x) mod x^(2t) */ int gamma_deg = poly_degree(gamma, NN - KK + 1); poly_mult(S_poly, NN - KK - 1, gamma, gamma_deg, T, NN - KK); /* Initialize Euclidean algorithm */ R0[NN - KK] = 1; /* R0 = x^(2t) */ int deg_R0 = NN - KK; /* Degree of x^(2t) */ for (i = 0; i < NN - KK; i++) { R1[i] = T[i]; } int deg_R1 = poly_degree(R1, max_deg); V1[0] = 1; /* V1 = 1 */ int deg_V0 = -1; /* V0 = 0 */ int deg_V1 = 0; /* Degree of V1 is 0 */ int v_max = (NN - KK - erasure_count) / 2; /* Max errors correctable */ /* Euclidean algorithm iteration */ while (deg_R1 != -1 && deg_R1 >= v_max) { if (deg_R0 < deg_R1) { /* Swap R0 and R1 */ int temp_deg = deg_R0; deg_R0 = deg_R1; deg_R1 = temp_deg; int temp_R[65]; copy_poly(R0, temp_R, max_deg); copy_poly(R1, R0, max_deg); copy_poly(temp_R, R1, max_deg); /* Swap V0 and V1 */ temp_deg = deg_V0; deg_V0 = deg_V1; deg_V1 = temp_deg; int temp_V[65]; copy_poly(V0, temp_V, max_deg); copy_poly(V1, V0, max_deg); copy_poly(temp_V, V1, max_deg); } int shift = deg_R0 - deg_R1; int factor = gf_mult(R0[deg_R0], gf_inv(R1[deg_R1])); /* Update R0: R0 = R0 + factor * x^shift * R1 */ for (i = 0; i <= deg_R1; i++) { if (R1[i] != 0 && i + shift < max_deg) { R0[i + shift] ^= gf_mult(factor, R1[i]); } } deg_R0 = poly_degree(R0, max_deg); /* Update V0: V0 = V0 + factor * x^shift * V1 */ for (i = 0; i <= deg_V1; i++) { if (V1[i] != 0 && i + shift < max_deg) { if (i + shift < max_deg) { V0[i + shift] ^= gf_mult(factor, V1[i]); } } } deg_V0 = poly_degree(V0, max_deg); } /* Error locator polynomial = V1 (lambda) */ for (i = 0; i <= deg_V1; i++) { lambda[i] = V1[i]; } int deg_lambda = deg_V1; /* Error evaluator polynomial = R1 (omega) */ for (i = 0; i <= deg_R1; i++) { omega[i] = R1[i]; } int deg_omega = deg_R1; /* Compute total error locator (gamma * lambda) */ int total_loc[2 * TT + 1] = { 0 }; poly_mult(gamma, gamma_deg, lambda, deg_lambda, total_loc, 2 * TT + 1); int deg_total = poly_degree(total_loc, 2 * TT + 1); /* Find roots of total_loc (Chien search) */ int count = 0; for (int pos = 0; pos < NN; pos++) { int Xi_inv = alpha_to[(NN - pos) % NN]; int sum = total_loc[0]; /* Evaluate polynomial at alpha^(-pos) */ int Xi_power = Xi_inv; for (i = 1; i <= deg_total; i++) { if (total_loc[i] != 0) { sum ^= gf_mult(total_loc[i], Xi_power); } Xi_power = gf_mult(Xi_power, Xi_inv); } if (sum == 0) { loc[count] = pos; root[count] = Xi_inv; /* alpha^(-pos) */ count++; if (count > deg_total) break; /* Stop if found more roots than degree */ } } if (count != deg_total || deg_total == -1) { err_flag = 2; /* Too many errors or no roots found */ } else { /* Initialize error array */ for (i = 0; i < NN; i++) { err[i] = 0; if (recd[i] == -1) recd[i] = 0; } /* Forney algorithm for error values */ for (i = 0; i < count; i++) { int pos = loc[i]; int Xi = root[i]; /* alpha^(-pos) */ /* Compute numerator (omega(Xi)) */ int num = 0; int Xi_power = 1; for (j = 0; j <= deg_omega; j++) { if (omega[j] != 0) { num ^= gf_mult(omega[j], Xi_power); } Xi_power = gf_mult(Xi_power, Xi); } /* Compute denominator (lambda'(Xi)) */ int denom = 0; for (j = 1; j <= deg_total; j += 2) { /* Only odd powers */ if (total_loc[j] != 0) { /* Derivative term: j * loc[j] * Xi^(j-1) */ int deriv = gf_mult(total_loc[j], alpha_to[(j - 1) * index_of[Xi] % NN]); denom ^= deriv; } } if (denom != 0) { int err_val = gf_mult(num, gf_inv(denom)); recd[pos] ^= err_val; } else { err_flag = 2; break; } } } } else { err_flag = 0; /* No errors */ } } /* Print hex array */ void print_hex_array(int arr[], int start, int count) { for (int i = 0; i < count; i++) { printf("%02X ", arr[start + i]); } printf("\n"); } int main() { int acterr_num, err_pos[TT]; srand((unsigned)time(NULL)); generate_gf(); gen_poly(); do { printf("\nReed-Solomon (255,239) 解码测试\n"); printf("最大纠错能力: %d 个错误\n", TT); printf("输入注入错误数量(0-%d): ", TT); scanf_s("%d", &acterr_num); if (acterr_num > TT) { printf("错误数量超过纠错能力!\n"); continue; } /* 生成随机数据 */ for (int i = 0; i < KK; i++) data[i] = rand() % (NN + 1); /* 编码 */ encode_rs(); /* 构建码字 */ for (int i = 0; i < NN - KK; i++) recd[i] = bb[i]; for (int i = NN - KK; i < NN; i++) recd[i] = data[i - (NN - KK)]; /* 保存原始码字 */ int recd_copy[NN]; for (int i = 0; i < NN; i++) recd_copy[i] = recd[i]; /* 显示原始数据 */ printf("\n原始数据(前10个符号):\n"); print_hex_array(recd, NN - KK, 10); /* 手动输入错误位置 */ if (acterr_num > 0) { printf("输入错误位置(0-%d):\n", NN - 1); for (int i = 0; i < acterr_num; i++) { printf("错误 %d 位置: ", i + 1); scanf_s("%d", &err_pos[i]); if (err_pos[i] < 0 || err_pos[i] >= NN) { printf("位置无效!\n"); i--; continue; } } } /* 注入错误 */ printf("\n注入%d个错误...\n", acterr_num); for (int i = 0; i < acterr_num; i++) { int err_val = 1 + rand() % (NN - 1); // 非零错误值 int original = recd[err_pos[i]]; recd[err_pos[i]] ^= err_val; printf(" 位置 %d: %02X → %02X (错误值 = %02X)\n", err_pos[i], original, recd[err_pos[i]], err_val); } /* 解码 */ decode_rs(); /* 显示解码结果 */ printf("\n状态: "); switch (err_flag) { case 0: printf("未检测到错误"); break; case 1: printf("错误纠正成功"); break; case 2: printf("错误超出能力"); break; default: printf("未知状态"); } printf("\n\n解码后数据(前10个符号):\n"); print_hex_array(recd, NN - KK, 10); printf("原始数据(前10个符号):\n"); print_hex_array(recd_copy, NN - KK, 10); /* 验证结果 */ int errors = 0; for (int i = NN - KK; i < NN; i++) { if (recd[i] != recd_copy[i]) { printf("位置 %d: 原始值=%02X, 解码值=%02X\n", i, recd_copy[i], recd[i]); errors++; } } if (errors == 0) { printf("\n验证: 所有数据符号与原始一致!\n"); } else { printf("\n验证: %d个数据符号与原始不同\n", errors); } printf("\n按ESC退出,其他键继续..."); } while (_getch() != 27); return 0; }
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值