片方向リストにおいて


以下の文は5つの数値の入力を受け取ってnumberlistとして値を返すプログラムです。  
双方向リストの勉強をしています。今回のコードは片方向リストです

最後にあるwhileループだけカンマを出力しないようにしたいのですが、こういうときはどうするのが最も空間計算量が少なくて済みますか？

一応、endという構造体のアドレスをつくってi=4のときに結びつけるようにしたつもりなのですがうまくいきません。

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    struct number{
      int num;
      struct number *next;
    };
    
    int main(){
      struct number *p, *head, *end;
      end=(struct number *)malloc(sizeof(struct number));
      int i;
      printf("input 5 number:");
      for(i=0;i<5;i++){
        if(i==0){
          p=(struct number *)malloc(sizeof(struct number));
          head=p;
          if(i==4){
            end=p;
            p->next=NULL;
          }
        }else{
        p->next=(struct number *)malloc(sizeof(struct number));
        p=p->next;
        }
        scanf("%d", &p->num);
        p->next=NULL;
      }
      p=head;
      printf("number list:");
      while(p!=NULL){
        if(p==end){
          printf("%d", p->num);
          p=p->next;
        }else{
        printf("%d, ", p->num);
        p=p->next;
        }
      }
      printf("\n");
      return 0;
    }
    
[/code]




こんな風に考えられます。

  * 変数は初期化しておきましょう。
[code]     struct number *p, *head, *end;

    
[/code]

  * これは不要です。
[code]     end=(struct number *)malloc(sizeof(struct number));

    
[/code]

  * `i`が`0`の時しか実行されない部分で`i`が`4`か判定しても意味が無いですよ。  
なので`while`ループでの`if(p==end){`の判定は常に成功しません。

[code]     if (i == 0) {

        ...
        if (i == 4) {
            end = p;
            p->next = NULL;
        }
    }
    
[/code]

  * `for`ループは他の処理も色々と冗長です。

まとめると以下のようになります。

[code]

    int main() {
        struct number * p = NULL, * head = NULL, * end = NULL; // 変数は初期化する
        //end = (struct number*)malloc(sizeof(struct number)); // これは不要です
        int i;
        printf("input 5 number:");
        for (i = 0; i < 5; i++) {
            // ループ内の処理を整理
            p = (struct number*)malloc(sizeof(struct number));
            p->next = NULL;
            if (i == 0) {
                head = p;
            }
            else {
                end->next = p;
            }
            end = p;
            scanf("%d", &p->num);
        }
        p = head;
        printf("number list:");
        while (p != NULL) {
            // 元の処理に近いならこちら
            if (p == end) {
                printf("%d", p->num);
            }
            else {
                printf("%d, ", p->num);
            }
            // あるいは @metropolis さんコメントの以下の処理にする
            //printf("%d%s", p->num, (p->next ? ", " : ""));
            p = p->next;
        }
        printf("\n");
        return 0;
    }
    
[/code]

