1から9まで足したり引いたりして100をつくろう

情報処理の課題の解説です。
以下問題の説明

123456789
これの間に、+ または - をいれて、100 になるようにします。
ex: 1+2+3-4+5+6+78+9
これのように、数字の順をいれかえてはいけませんし、括弧を使ってもいけません。
こんな式を全て表示するプログラムを作りなさい。

なんか口調がおかしいですがこんな問題です。

                                                                                                                                                    • -

以下自分なりの解説

まぁ、まず総当たりに数式を生成してそれを計算し、100になったら表示する方法をとるのがいいんじゃないでしょうか。
1から9までの間に空白を1個づつ空けた文字配列を作って、その空白部分を8重forループぶん回して、空白、+、-、の順に右側から入れ替えていけばいいでしょう。
そして、できた配列から空白を取り除き、それを計算させます。その結果が100ならば表示させればいいんじゃないでしょうか。

以下ソースコード

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

int evalstr(char *dst, const char *exp);

int
main()
{
  char str[17+1] = "1 2 3 4 5 6 7 8 9";
  char str2[64];                        /* 印字用           */
  char ops[3+1] = " +-";
  int i[8];

  /*
    数式を生成するループ
    右側から符号を変えていることに注意
  */
  for(i[0] = 0; i[0] < 3; i[0]++)       /* 目に痛いループ群 */
    {
      str[1] = ops[i[0]];
      for(i[1] = 0; i[1] < 3; i[1]++)
        {
          str[3] = ops[i[1]];
          for(i[2] = 0; i[2] < 3; i[2]++)
            {
              str[5] = ops[i[2]];
              for(i[3] = 0; i[3] < 3; i[3]++)
                {
                  str[7] = ops[i[3]];
                  for(i[4] = 0; i[4] < 3; i[4]++)
                    {
                      str[9] = ops[i[4]];
                      for(i[5] = 0; i[5] < 3; i[5]++)
                        {
                          str[11] = ops[i[5]];
                          for(i[6] = 0; i[6] < 3; i[6]++)
                            {
                              str[13] = ops[i[6]];
                              for(i[7] = 0; i[7] < 3; i[7]++)
                                {
                                  str[15] = ops[i[7]];
                                  if (evalstr(str2, str) == 100)
                                    printf("%s\n",
                                           str2);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
  return 0;
}

/*
  数式を投げると計算する関数

  @param[out] dst 印字用の数式(スペースなし)
  @param[in]  exp 計算する数式
  @return         計算結果
  
  ただし、加減しかできない。
  関数ポインタを使えば乗除もできるかも。(計算順を考える必要があるけれど)
  ただ、こっちの方が記号が少ない。
  スペースをすべて取り除くようにしてある。
*/
int
evalstr(char *dst, const char *exp)
{
  char ops[2] = "+-";
  int i, j;             /* i: 配列へのインデックス
                           j: どっちの演算子か       */
  int size;             /* 数式のサイズ              */
  char *literal = dst;  /* atoi に渡すための数字の頭 */
  int result = 0;
  char *p, *q, *end;    /* p:   空白の位置
                           q:   移動してる文字
                           end: 数式の終端           */

  /* 作業領域にコピーして準備 */
  strcpy(dst, exp);
  size = strlen(dst);
  end = dst + size;

  /* 空白をはずす */
  for(p = end; p > dst; p--)       /* 終わりから探索 */
    if (*p == ' ')                 /* スペースが     */
      {                            /*   あったら     */
        for (q = p; q <= end; q++) /* いっこっつ     */
          *q = *(q + 1);           /* つめていく     */
        end--;
      }

  /* あらためてサイズをセット */
  size = strlen(dst);

  /*
    計算部分

    符号をいったん退避しておいて、そこまでを atoi で
    数字になおし result に足していく。
  */
  for (i = 0; i < size; i++ )      /* 数式の最後まで */
    for (j = 0; j < 2; j++ )       /* + or - を探し  */
      if (dst[i] == ops[j])        /* あったなら     */
        {
          dst[i] = '\0';           /* 直前の数字を   */
          result += atoi(literal); /* 数にかえて足す */
          literal = dst + i;
          dst[i] = ops[j];         /* 符号を復元する */
        }

  result += atoi(literal);         /* 最後の部分も   */

  return result;
}

コメントをたくさん付けてあるのでこまかくは見てください。