質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

解決済

C言語の可変長配列で配列の末尾を削除する方法で詰まっています。

whitehorse85921
whitehorse85921

総合スコア34

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

1回答

0評価

0クリップ

504閲覧

投稿2022/06/09 09:27

前提

「アルゴ式」の問題で、出力例と私の出力が違っています。

出力例
4
1
3
Error
2

私の出力
0
4
1
3
3

https://algo-method.com/tasks/828

実現したいこと

可変長配列で配列の末尾に要素を追加(Push)と 配列の末尾を出力してから、配列の末尾を削除(Pop)するプログラムを作っています。配列に要素がない場合「Error」と表示します。

発生している問題・エラーメッセージ

エラーはないです。

該当のソースコード

C

#include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef struct { int *array; int capa; int len; } DynamicIntArray; DynamicIntArray * DynamicIntArray_New(int n) { DynamicIntArray *self = calloc(1, sizeof(*self)); if (!self) { return NULL; } self->capa = n; self->array = calloc(self->capa, sizeof(int)); if (!self->array) { free(self); return NULL; } return self; } DynamicIntArray * DynamicIntArray_Resize(DynamicIntArray *self, int32_t capa) { int32_t byte = sizeof(int); int32_t size = byte * capa; int *tmp = realloc(self->array, size); if (!tmp) { return NULL; } self->array = tmp; self->capa = capa; return self; } DynamicIntArray * DynamicIntArray_PushBack(DynamicIntArray *self, int elem) { if (self->len >= self->capa) { if (!DynamicIntArray_Resize(self, self->capa * 2)) { return NULL; } } self->array[self->len++] = elem; return self; } /*DynamicIntArray_Removeのみ自身で追加。あとは既存のコードを少し改良しました。*/ DynamicIntArray * DynamicIntArray_Remove(DynamicIntArray *self) { return self->len--; } void DynamicIntArray_Del(DynamicIntArray *self) { if(!self) { return; } free(self->array); free(self); } void DynamicIntArray_Show(const DynamicIntArray *self) { printf("%d\n", self->array[self->len]); } int main(void) { int N; (void)scanf("%d", &N); DynamicIntArray *ary = DynamicIntArray_New(N); int A[101]; for (int i = 0; i < N; i++) { (void)scanf("%d", &A[i]); DynamicIntArray_PushBack(ary, A[i]); } int Q; (void)scanf("%d", &Q); for (int i = 0; i < Q; i++) { int query; (void)scanf("%d", &query); if (query == 0) { int v; (void)scanf("%d", &v); DynamicIntArray_PushBack(ary, v); } else if (query == 1) { int size = sizeof(DynamicIntArray) / sizeof(DynamicIntArray); if (size > 0) { DynamicIntArray_Show(ary); DynamicIntArray_Remove(ary); } else { printf("Error\n"); } } } return 0; }

試したこと

DynamicIntArray *
DynamicIntArray_Remove()関数を自身で追加しました。

補足情報(FW/ツールのバージョンなど)

「アルゴ式」のオンラインでジャッジするところでコードを書きました。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

hoshi-takanori

2022/06/09 09:41

その問題、配列は固定長で良いのでは…。
whitehorse85921

2022/06/09 09:44

hoshi-takanori様 固定長は他の方のコードで見ることができ分かったのですが、可変長で書かれているのが見当たらなかったので、ここで質問させていただきましたm( _ _ )m
Zuishin

2022/06/09 09:46

N は 100 以下なので、固定長で十分ですね。
whitehorse85921

2022/06/09 09:48

Zuishin様 固定長は他の方のコードを見て分かったのですが、どうしても可変長でのやり方を知りたくて、質問させていただきましたm( _ _ )m
Zuishin

2022/06/09 09:54

DynamicIntArray_Resize の戻り値を使用していないようですが、いいんですか?
hoshi-takanori

2022/06/09 09:56

Show の時に表示するものが間違ってますね。あと、Remove は無条件でデクリメントして大丈夫?
whitehorse85921

2022/06/09 09:58

Zuishin様 それは、DynamicIntArray_RemoveでDynamicIntArray_Resizeの戻りを使用していないという解釈で合っていますでしょうか?
Zuishin

2022/06/09 09:59

PushBack です。
whitehorse85921

2022/06/09 10:01

hosi-takanori様 1.具体的にはShowはどのようにするとよろしいでしょうか? 2.Removeはどのような条件でデクリメントしたらいいのか分からないです。
hoshi-takanori

2022/06/09 10:07

1. 現在 self->array[self->len] を表示してますが、これは配列の最後の値ですか? 2. 出力例のデータでは、最初に 2 要素あって、その後 1 要素 Push して、それから何回 Pop してますか?
hoshi-takanori

2022/06/09 10:09

「どうしても可変長でのやり方を知りたくて」と言うなら、他人のコードを何も考えずにそのまま使うのではなく、それが何をしてるか理解しないと意味ないのでは…。
Zuishin

2022/06/09 10:11

realloc は再割り当てに成功した場合、新しいアドレスを返しますが、それを破棄しています。 拾ったコードの信ぴょう性を確かめずそのまま使うのは良くありませんね。 まず固定長で作り、それで問題ないことを確かめた上でその可変長配列とやらに差し替えてみてください。 なお、C 言語で「可変長配列」という言葉は通常、ここで言われているものとは別のものを指します。 独自の言葉を使っている点で「臭い(信用できない)」と思ってください。
whitehorse85921

2022/06/09 10:12

hoshi-takanori様 1.私のつたない解釈ではPushした後の配列の最後の値だと考えております。 2.5回Popしてると思います。
whitehorse85921

2022/06/09 10:17

hoshi-takanori様 仰る通りです。。。 貴重なお時間割いてしまいすみません。
whitehorse85921

2022/06/09 10:22

Zuishin様 貴重なお時間割いてしまいすみません。 まずは固定長で作ってみます。 あと、大変申し訳ないのですが、どの「可変長配列」が正しいのか分からないので、おすすめのネット上の記事があれば教えて頂きたいのですが駄目でしょうか?
whitehorse85921

2022/06/09 10:32

Zuishin様 ありがとうございます!!! さっそく読んでみたいと思います!!!
hoshi-takanori

2022/06/09 10:54

C の可変長配列は、配列のサイズを途中で増やせないので、質問者さんのやりたいこととは違うでしょうね。しかも、最近の C 言語規格では廃止されたらしいし…。 1. 長さ len の配列の場合、要素は array[0] から array[len - 1] までしかありません。array[len] にあるのはゴミです。 2. ちゃんと数えましょう。1 が 4 つ並んでるので、Pop は 4 回です。そして、最初に要素が 2 つあり、1 つ増えて 3 個になって、その後 4 回 Pop したらどうなりますか? それを防ぐにはどうすれば良いと思いますか?
whitehorse85921

2022/06/09 11:20

hoshi-takanori様 1.配列がのインデックスが0から始まるからarray[len-1]なのですね。lenだと現在の要素数になってしまうのですよね? 2. 4回Popしたら配列に要素がなくなるのでErrorですよね。。。?
tmp

2022/06/09 11:31

hoshi-takanoriさん 2は、多分、int size = sizeof(DynamicIntArray) / sizeof(DynamicIntArray); で長さを計算しているつもりだと思います。
thkana

2022/06/09 12:30

hoshi-takanoriさん > C 言語規格では廃止されたらしい 廃止じゃなくて、オプションに落ちた、です。C99を2013年まで採用しなかった某MSが嫌ったのでしょうか。
tmp

2022/06/09 13:05

size = sizeof(DynamicIntArray) / sizeof(DynamicIntArray);が要素の数だと思っているように思えて hoshi-takanoriさんの2の指摘だと、whitehorse85921さんは、要素の数で判断してErrorを出している思っているので気が付きにくいと、思って書いたつもりです。 whitehorse85921さん、aryの要素の数はいくつですか?
whitehorse85921

2022/06/11 09:11

tmp様 お心遣いありがとうございます。 aryの要素の数は4つだと思ってます。
whitehorse85921

2022/06/11 09:12

皆様方々へ 少し体調を崩して返信が遅くなり大変に申し訳ございません。
whitehorse85921

2022/06/11 09:57

皆様方々へ!!! 私じゃ思いつかない、問題提起ありがとうございました!!! 皆様方々にも感謝です!!!

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。