Error[8]: Undefined offset: 1808, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    }[+++][+++][+++] doubleStack[+++][+++][+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1809, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    }[+++][+++] doubleStack[+++][+++][+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1810, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    }[+++] doubleStack[+++][+++][+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1811, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack[+++][+++][+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1812, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack[+++][+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1813, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack[+++][+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1814, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack[+++][+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1815, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack[+++]


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1816, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack


    [+++] [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1817, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack


     [+++][+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1818, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack


     [+++]
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Error[8]: Undefined offset: 1819, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack


     
[+++]

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
堆栈应用四则运算表达式求值_C_内存溢出

堆栈应用四则运算表达式求值

堆栈应用四则运算表达式求值,第1张

以最简单的方式实现几个C语言课程设计的常见题目,适合大一或者刚学习C语言的同学学习参考。使用Code::Blocks编译器创建的纯C项目,将其中的源码粘贴进其他编译器或C++项目也可直接运行。因为部分同学没有学习过数据结构,所以尽量使用传统的数组进行存储,规避没有学习过的知识点,但鼓励大家自己改进。为了使得程序更加简单方便阅读,基本上没有进行对用户输入的容错,可以自己添加。

Code::Blocks安装和使用 https://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

项目源码会在文章末尾给出

文章目录
  • 中缀表达式 vs. 后缀表达式(逆波兰表达式)
  • 分割字符串 和 类型转换
  • 字符串转数字
  • 栈 和 队列 的实现
  • 中缀表达式 转 后缀表达式
  • 后缀表达式计算
  • 附录——全部代码

参考文章:https://blog.csdn.net/qq_42446156/article/details/108162504
https://www.bilibili.com/video/BV1xp4y1r7rc?spm_id_from=333.337.search-card.all.click

中缀表达式 vs. 后缀表达式(逆波兰表达式)

中缀表达式: *** 作符在 *** 作数的中间,就是我们常见表达式的类型,需要括号来帮助定义计算的顺序,如果把结果去掉就会产生歧义。
1 + ( ( 2 + 3 ) × 4 ) - 5:2+3=5;5×4=20;1+20=21;21-5=16
1 + 2 + 3 × 4 - 5:3 × 4 = 12;1+ 2 = 3;3 + 12 = 15;15 - 5 = 10

后缀表达式: *** 作符在 *** 作数的后面,不需要括号,不会产生歧义。 1 2 3 + 4 × + 5 –
1 2 3 + 4 × + 5 –:2 3 + = 5;5 4 × = 20;1 20 + = 21;21 5 - =16

中缀表达式 转 后缀表达式的步骤:
初始化运算符栈s 和 结果队列q;
从左至右扫描中缀表达式:
遇到 *** 作数时,将其加入q;
遇到运算符t时:
1.s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级,运算符t入栈s;× / 优先级大于 + -
2.否则,不断将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级(t的优先级和栈顶元素优先级相同也是需要d出的),然后运算符t入栈。
遇到括号时:
1.如果是左括号“(”,则直接压入s
2.如果是右括号“)”,则依次d出s栈顶的运算符加入q直至遇到左括号"("为止,左右括号丢弃并不加入到q中

看一下上面的例子:

分割字符串 和 类型转换

首先,你要求用户输入的表达式是一个字符串,你需要分割出哪些是数字,哪些是 *** 作符。下面的代码仅供参考。

#include 
#include 
#include 

//输入字符是否是 *** 作符 + - * / ( )
//是返回1,否返回0
int isOperator(char key)
{
    if (key == '+' || key == '-'
        || key == '*'|| key == '/'
        || key == '('|| key == ')')
        return 1;
    return 0;
}

int main()
{
    //原始输入
    char rawInput[50];
    printf("输入中缀表达式:");
    scanf("%s", rawInput);

    //字符串分割后的输入
    char processedInput[50][20];
    //分割后包含几个项
    int cnt = 0;

    int index = 0;
    for (int i = 0; i < strlen(rawInput); ++i)
    {
        //如果该字符是 *** 作符
        if (isOperator(rawInput[i]))
        {
            //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项
            ( 0i > && isOperator ([rawInput-i 1 ])== 0 )[
            {
                processedInput]cnt[]index= ';' =0
                index ; ++;
                }cnt//存储 *** 作符,然后将当前项设置为下一项
            [

            ]
            processedInput[cnt0]=[ ] rawInput;i[]
            processedInput[cnt1]=';' ++ ;}
            //如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse
        [
        ]
        [
        {
            processedInput]cnt=[index] ; rawInput++i;if
            (index==
            strlen (i ) -1rawInput) [ ][
            {
                processedInput]cnt=';'index++ ; }}
                }cnt//输出测试
            printf
        (
    "%d\n\n"

    ,
    );for( cntint=
    0 ;< i ; ++) i printf cnt( "%s\n"i,
        []); processedInputreturni0;}

    # include#
include

字符串转数字

接下来实现,从char数组到double数字的变换

#include 
#include 
//字符串 转 小数double 
string2Double( 

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}int
    main result(
)

char [20]
{
    ; tscanf("%s",
    );printf( t"%lf",
    string2Double()) ;returnt0;}

    # include#
include

栈 和 队列 的实现

栈 先进后出,队列 先进先出。我们本实验所使用的队列只有基本的 全部入队 全部出队,所以直接使用普通的数组代替即可。下面是栈的实现。

#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
int qCnt main ()

int ;char[
{
    20 cmd]
    ; inputwhile(1)
    printf("\t\t0 退出\n\t\t1 入栈\n\t\t2 出栈\n\t\t3 查看栈顶元素\n\n")
    {
        ;scanf("%d",
        &);if (cmd==0

        ) breakcmd ; switch(
            )case
        1:cmdprintf
        {
            ( "输入元素:") ;scanf("%s", );push( input); break;inputcase2 :pop
            ( ); break;case3 :printf
            ( "栈顶元素:%s\n", top()) ;break;}} return0
        ;
    }

    # include#
include

中缀表达式 转 后缀表达式
#include 
#include 
char[ 
50] 

[ stack20];//栈顶位置,初始时没有元素int=-
1
; sTop //入栈 voidpush(
char
* )++; strcpykey(
{
    [sTop]
    ,)stack;sTop}//出栈 keyvoidpop
(
)
-- ;}//查看栈顶元素,无元素返回NULL
{
    charsTop*
top
(
)if (==-
{
    1 )sTop return NULL;else
        return []
    ;
        } stackcharsTop[50
]

[ queue20];//队列中的元素个数int=0
;
//字符串 转 小数 qCnt double string2Double(

char
* )double=0 key;
{
    //小数点的位置,-1表示没有小数点 result int =-
    1
    ; index for (int=
    0 ;< i strlen () i ; ++)keyif( [i]
    {
        == '.'key)i= ; }else
        {
            index = i*
        10
        +
        {
            result ( result [ ] - '0'key)i; } }if(
        !=
    -
    1 )index /= pow(10
        result , strlen()- -1key) ; index return ;}//输入字符是否是 *** 作符 + - * / ( )
    //是返回1,否返回0 resultint
isOperator

(
char
) if(== key'+'
{
    || ==key '-' || == key '*' ||
        == key '/' ||== key '(' ||
        == key ')' )return key 1 ;return
        0 ;}
    //运算符 a的优先级大于b的优先级返回1,否则返回0 inthighPriority
(

char
, char)if a( ( b==
{
    '*' ||==a '/' ) && a ( =='+' || ==b '-' ) ) b return 1;return
        0 ;}
    int main(
)

//原始输入 char[50
{
    ]
    ; rawInputprintf("输入中缀表达式:")
    ;scanf("%s",
    );//字符串分割后的输入char rawInput[50

    ]
    [ processedInput20];//分割后包含几个项int=0
    ;
    int cnt = 0;

    for index ( int=
    0 ;< i strlen () i ; ++)rawInput//如果该字符是 *** 作符if (iisOperator
    {
        (
        [ ]))rawInput//如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项i(0&&
        {
            isOperator
            ( [i > - 1 ])rawInput==i 0 )[] [ ]=
            {
                processedInput';'cnt=0index; ++ ;}
                index //存储 *** 作符,然后将当前项设置为下一项 []
                [cnt0
            ]

            =
            processedInput[cnt];[] [ rawInput1i]=
            processedInput';'cnt++;}//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束 else []
            [cnt]
        =
        [
        ]
        {
            processedInput;cnt++;indexif ( rawInput==istrlen(
            )index-
            1 )i [ ][rawInput] = ';'++
            {
                processedInput;cnt}}index} //中缀 转 后缀 for(
                intcnt=
            0
        ;
    <

    ;
    ++ )// *** 作数 i if (isOperator i ( cnt[ ]i[
    {
        0
        ] )==0processedInput)istrcpy([], [ ])
        {
            ;++queue;qCnt}// ( processedInputelseiif([
            ]qCnt[
        0
        ]
        == '(' )processedInputpushi([]) ; }// )
        {
            elseifprocessedInput(i[][
        0
        ]
        == ')' )processedInputwhilei(1)if ( top(
        {
            ) [0]
            {
                == '(')pop();break ; }else
                {
                    strcpy([]
                    ,top
                (
                )
                {
                    );queue++qCnt;pop ();}}
                    }qCnt// + - * /
                    else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级while(
                top
            (
        )
        !=
        NULL
        {
            &&
            top()[0 ] != '(' &&highPriority([][ 0 ] , top(processedInput)i[0])== 0)strcpy([], top ()
            {
                );queue++qCnt;pop ();}push
                (qCnt[
                ]);}
            }
            while(processedInputtopi()!=
        NULL
    )
    strcpy ([], top ()
    {
        );queue++qCnt;pop ();}//测试输出后缀表达式
        forqCnt(
        int=0;
    <


    ;
    ++ )printf i ( "%s ", i [ qCnt] )i;
        printf("\n") queue;ireturn0;
    }#include#include

    # include#
include

后缀表达式计算

预备一个空栈s
从左至右扫描后缀表达式:
遇到 *** 作数时,将其加入s;
遇到运算符t时:d出栈顶的两个元素,进行运算,将结果入栈

附录——全部代码
char[ 
50] 
[20 
]; 

//栈顶位置,初始时没有元素 stackint=-1;//入栈void
push
( sTop char *)++
;
strcpy ([] ,key)
{
    ;sTop}
    //出栈voidstackpopsTop() key--;
}
//查看栈顶元素,无元素返回NULL
char *top(
{
    )sTopif
(
==
-1 )returnNULL
{
    ; elsesTop return [];
        } char[
    50
        ] stack[sTop20]
;

//队列中的元素个数 queueint=0;//字符串 转 小数doublestring2Double
(
char qCnt * )double

=
0 ;//小数点的位置,-1表示没有小数点int= key-
{
    1 result ; for(
    int
    = index 0 ;<strlen
    ( ); i ++ )if i ( []key=='.' )i=
    {
        ; }keyelsei= * 10+
        {
            index ( i[
        ]
        -
        {
            result '0' result ) ; } }keyifi( != -1)
        /=
    pow
    ( 10index , strlen()
        result - -1); return;key} //输入字符是否是 *** 作符 + - * / ( ) index //是返回1,否返回0 intisOperator(
    char result)
if

(
==
'+' ||=='-' key||
{
    == '*'key || == '/' key || ==
        '(' key || ==')' key ) return
        1 key ; return0 key ; }//运算符 a的优先级大于b的优先级返回1,否则返回0
        int highPriority(
    char ,char
)

if
( (=='*' a|| == b'/'
{
    ) &&(a == '+' || a == '-') ) returnb 1 ; return b 0 ;}int
        main ()
    //原始输入 char[
50

] ;printf(
{
    "输入中缀表达式:"
    ) rawInput;scanf("%s"
    ,);//字符串分割后的输入char
    [50][ rawInput20]

    ;
    //分割后包含几个项 processedInputint=0;int=0
    ;
    for cnt ( int=

    0 index ; <strlen
    ( ); i ++ )//如果该字符是 *** 作符 i if (isOperatorrawInput([ ]i)
    {
        )
        //如果前一个字符不是 *** 作符,那么在当前项的末尾加一个'if'表示当前项数字结束,并将当前项设置为下一项 (0&&rawInputisOperatori([-
        {
            1
            ] )i > == 0 )[rawInput]i [ ]=';' = 0;
            {
                processedInput++cnt;}index//存储 *** 作符,然后将当前项设置为下一项 [ ][
                index 0 ]=
                [cnt]
            ;

            [
            processedInput]cnt[1]= ';' rawInput++i;}
            processedInput//如果该字符不是 *** 作符,那么把该字符添加到当前项的末尾,即当前项的数字还没有结束cntelse[][ ] =[
            ]cnt;
        ++
        ;
        if
        {
            processedInput(cnt==strlenindex( ) rawInput-i1)
            [index]
            [ ]i = ';'++rawInput; } }}
            {
                processedInput//中缀 转 后缀cntfor(indexint = 0;
                <cnt;
            ++
        )
    // *** 作数

    if
    ( isOperator( i [ ][ i 0 cnt] )i==
    {
        0
        ) strcpy([processedInput]i,[]); ++ ;}
        {
            // (elsequeueifqCnt([ processedInput]i[0]
            ==qCnt'('
        )
        push
        ( [ ]processedInput)i;}// )else if ([
        {
            ][processedInput0i]==')'
        )
        while
        ( 1 )processedInputifi(top() [ 0]
        {
            == '(')pop
            {
                ( );break;}elsestrcpy ( []
                {
                    ,top()
                    );
                ++
                ;
                {
                    pop(queue)qCnt;} }}// + - * /else//将s栈顶的运算符d出并加入q中直至 s空 / s栈顶为"(" / 运算符t的优先级大于栈顶元素的优先级
                    whileqCnt(
                    top()!=
                NULL
            &&
        top
        (
        )
        {
            [
            0]!='('&& highPriority ( [ ][0],top ( ) [ 0]processedInput)i==0)strcpy( [],top()) ; ++;
            {
                pop(queue)qCnt;} push([])
                ;qCnt}
                }while(top
            (
            )!=processedInputNULLi)strcpy(
        [
    ]
    , top()) ; ++;
    {
        pop(queue)qCnt;} //测试输出后缀表达式printf("后缀表达式:")
        ;qCntfor
        (int=0
    ;


    <
    ;++)printf(
    "%s " ,[ i ] ); i printf qCnt( "\n"i)
        ;double[50 queue]i;int=
    -1;//后缀表达式计算for

    ( doubleStackint=0;
    < sDTop ; ++)if
    (
    isOperator ([ i ] [0 i ] qCnt) )idouble
    {
        = 0;doublequeue=i[];--;double
        {
            = result [ ];
            -- tb ; doubleStackswitchsDTop([
            ]sDTop[
            0 ta ] doubleStack)sDTopcase'+'
            :sDTop=
            +;queuebreaki;case'-':=
            {
                - ;break result ; ta case tb'*' :=
                * ;break result ; ta case tb'/' :=
                / ;break result ; ta } tb++ ;[
                ] =; result } ta else tb++ ;[
            ]
            =sDTopstring2Double
            doubleStack(sDTop[ ] result)
        ;
        }
        {
            }sDTopprintf
            doubleStack(sDTop"结果:%lf\n" , [0queue]i);return
        0
    ;

    } doubleStack


     

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/713510.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-24
下一篇 2022-04-24

发表评论

登录后才能评论

评论列表(0条)

保存