- 1 名前:デフォルトの名無しさん mailto:sage [2007/06/25(月) 06:14:52 ]
- C言語の入門者向け解説スレです。
・C++言語はスレ違いです。 ・分からない事をなるべく詳しく書いて下さい。 ・ソースコードを晒すと答えやすくなるかもしれません。 ・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。 前スレ C言語なら俺に聞け(入門篇) Part 14 pc11.2ch.net/test/read.cgi/tech/1181735298/ 教えて欲しいのではなく丸投げしたいならこちらへ C/C++の宿題を片付けます 91代目 pc11.2ch.net/test/read.cgi/tech/1182607405/
- 321 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 19:38:48 ]
- Cは昔のアセンブラみたいなもん。
良いも悪いもない
- 322 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 20:28:23 ]
- ガウシアンフィルタを作りたいんですが、質問させてください
フィルタをかけたい画素を中心に3×3のマスクをつくるとします。 teo.sourceforge.jp/doc/TeoProgrammingGuide/img/gaussian_kernel2.png みたいなガウシアンフィルタを作って、この行列の各要素の数値を マスクの行列の同じ場所の画素値にかけて、 その合計で中心画素の値を割ればいいんですか? マスクがとしたら 1 3 3 4 6 2 1 2 3 1×0.07 + 3×0.12+・・・+3×0.07=SUM 6/SUMがフィルタをかけた後の値ですか?
- 323 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 20:32:30 ]
- >>321
アセンブラに昔も今もあるのかよ
- 324 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 20:38:06 ]
- >>323
Cの話でしょ?w
- 325 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 21:52:45 ]
- >>322
そうだと思うけど、まずはやってみればいいんでね?
- 326 名前:デフォルトの名無しさん mailto:sage [2007/06/29(金) 22:33:26 ]
- >>322
そのコーディング方法が分からないんで無ければ 画像処理スレかどっかで聞いた方がいいんでね?
- 327 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 00:14:23 ]
- 最近ちょっとさわり始めたのですが、
memcpyのように引数にvoid*をとるとき、どうやってvoid*の中の物を 取り出すんですか?普通に配列のように[0]とかってやってもエラーになるし…
- 328 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 00:14:47 ]
- 適当なポインタ型にキャストすればいい。
- 329 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 00:48:34 ]
- >>328
その場合、中身が構造体などの場合にはどうしたらいいんでしょうか? char*などにキャストした後から戻せるのでしょうか?
- 330 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 00:54:00 ]
- 構造体でキャストすればいいんじゃ
- 331 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 00:57:58 ]
- >>330
該当する構造体でキャストすればいいのはわかるのですが、 memcpyのようになんでもコピーできるようにするにはどうしたら いいのかなと思ったのですが、これはあまりmemcpyを 使わない方がいいと言われるのと何か関係があるのでしょうか?
- 332 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 01:01:30 ]
- そんなもんchar*にキャストして1バイトずつ読み書きしているだけと思っていればいい。
実際には高速化するため複数バイトずつ読み書きするなど工夫しているいるけど。
- 333 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 01:51:53 ]
- >>332
参考になりました! ありがとうございます。
- 334 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:08:51 ]
- まぁ、間違っても構造体のコピーにmemcpy()なんて使うなよ。
- 335 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:09:15 ]
- 表示した画像を消すときはどんな関数を使いますか?
- 336 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:11:56 ]
- CLS 3
- 337 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:15:50 ]
- >>336
それってBASICじゃないですかw
- 338 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:18:01 ]
- あ、Cで表示した画像を消すときはどんな関数を使いますか?
- 339 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:20:43 ]
- 画像を表示するのにどんな関数使ってますか?
- 340 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:21:15 ]
- >>338
真っ白な画像を用意して、消したい画像の代わりに表示してはいかがでしょう。
- 341 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 02:35:45 ]
- もはやCのスレではなくなったな
- 342 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 03:05:44 ]
- exit(1);
- 343 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 03:36:59 ]
- goto >>343;
- 344 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 07:38:21 ]
- 教えてください。
main関数から、ある関数に引数を渡す場合は、次のような 感じで渡してもOKですか?ダメみたいなんすが、その理由が わからないです。 もちろん、実行する場合は引数を指定します。 a.out A.txt のように。 extern int p(char *filename) int main(int argc, char*argv[]) { p(argv[1]); }
- 345 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 07:41:09 ]
- &argv[1]
argv
- 346 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 07:51:38 ]
- >>344
どうダメなの? それでいけると思うのだけど。 >>345 プロトタイプ宣言と型が合いません。
- 347 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 07:52:44 ]
- 単にダメって言うんじゃなくて具体的にどんなエラーがでたとかさ・・・
- 348 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 07:58:13 ]
- パス指定なしのファイル名だけ書いていて、起動ディレクトリと違うところにあって見つからないとか。
- 349 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 08:04:09 ]
- 申し訳ないです。
セグメンテンションフォルトです。
- 350 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 08:09:50 ]
- 問題があるのはp()の方だろ
- 351 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 08:13:32 ]
- >>350
なるほど、呼び出す先のp関数がわるのかなぁ。 引数でわたってきたファイル名をfopen()を呼んでいるだけなんですが。
- 352 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 08:19:35 ]
- 微妙に日本語がおかしいのが気になる
- 353 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 08:21:27 ]
- どうもあがとうございました。
呼び出す先のp関数が悪いみたいです。 if (f=fopen(filename,"f")) "f" -> "r" ですね。すいませんでした。 このようなif文で代入はOKなのかなぁ?
- 354 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 09:05:16 ]
- >>353
間違ってはいないがお勧めしない。 Cのエキスパートを自称するロートルは、しばしば「代入と比較を一行で書けるのがCらしさだ」とのたまうが、 バグの混入の原因になりかねないし、第一必ずしも読み易くない。
- 355 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 10:55:48 ]
- ifの中で代入すると大抵警告が表示されるしな。
if ((f = fopen()) != NULL)とするやつもいるが俺は好きになれない。
- 356 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:02:07 ]
- 80カラムに収まるならついやっちゃうな・・・
f=NULL; f=fopen("ようじょ", "w"); if(f==NULL){ puts("ひゃぅん?"); } ここまでするとクドイ感じもするが・・・
- 357 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:03:31 ]
- fopenって失敗したらNULL返すんだからf=NULL;は要らなくね?
- 358 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:14:05 ]
- 我が家ではこうしてますね・・・
基本的に使う前と使った後はクドクドと初期化
- 359 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:17:27 ]
- よくこういうふうにやる
FILE* fp = fopen(); if (f)
- 360 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:20:07 ]
- FILE* fp;
FILE *fp; この二つの違いって何かあるの? 単なるコーディング流儀の違い?
- 361 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:22:46 ]
- 流儀の違い
- 362 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:22:50 ]
- そう、流儀の違い。
構文上は、FILE*fp;もFILE * fp;も可能。
- 363 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:23:41 ]
- FILE
* fp ; だっていいZE
- 364 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:23:58 ]
- >>360
前者はC++使いに多く、後者はC使いに多い。 両方使う私は、だからと言うわけではないがFILE * fp = fopen(...);と書く。
- 365 名前:デフォルトの名無しさん [2007/06/30(土) 11:33:59 ]
- for文とwhile文の明確な違いって何ですか?
たとえばfor文ではできるけどwhile文ではできないこととか・・・。
- 366 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:38:13 ]
- continue 時にも for(A;B;C) の C が実行されるってのが
while だと実現が面倒。
- 367 名前:デフォルトの名無しさん [2007/06/30(土) 11:41:46 ]
- バッファの割当の数とか数字を#defineしてしまうのは、なぜですか?マジックナンバーを使いたくないのはわかるのですが、
その都度malloc、もしくはreallocしてはいけないのですか? または、そのバッファの割当の数はどうやって決まるのですか? どうもCを書いていると全部mallocしたくなるのですが、C言語のハッカーさん教えてください。
- 368 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:41:58 ]
- for文の括弧内の式はどれも省略可能。
while文の括弧内の式は省略不可能。
- 369 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:42:12 ]
- forは式を省略できるがwhileは省略できない。
なので、無限ループはwhile (1) {...;}ではなくfor (;;) {...;}を使う。
- 370 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:47:09 ]
- もうしわけないです、コーディングは以下の理解でよいでしょうか。
だめ:× if (f=fopen(filename,"r")) よい:○ f=fopen(filename,"r"); if(f!=NULL)
- 371 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:47:14 ]
- >>367
malloc したら free しないとダメじゃん。 管理の手間が増えるからなるべくやりたくない。 必要な時はするがね。 ガベコレのある言語と一緒に考えない方がいいよ。
- 372 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:48:39 ]
- >>370
「だめ」ではなくて、「好ましくない」程度で。 他人が書いたものを読むときに、「だめ」と思わずに許容してあげましょう。
- 373 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 11:48:56 ]
- >>370
文法上の問題はないが推奨されない:△ if (f=fopen(filename,"r")) よい:○ f=fopen(filename,"r"); if(f!=NULL)
- 374 名前:デフォルトの名無しさん [2007/06/30(土) 11:50:26 ]
- whileでは無限ループはできないんですか?
- 375 名前:367 mailto:sage [2007/06/30(土) 11:54:14 ]
- >371
どもです。なるほど。確かにガベコレある言語でしかマジメに開発したことがないので、納得できていませんでした。 別物ですね。別物。 でも、その際に使用するMAX_BUF_NUMとかは一般的に1024とか使用されているのですが、何ゆえその数字が決まるのですか? 質問ばかりですいません。
- 376 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:07:15 ]
- 1KB程度でいいんじゃねって感じじゃね?
- 377 名前:367 mailto:sage [2007/06/30(土) 12:15:56 ]
- > 376
サンクス しかし、1KBにするか4KBにするかといったことに悩むんですよね。 作りたいアプリの仕様が1KB程度だから、ここは1KBにするか、と考えるのは普通のような気もするのですが、 アプリを作りたいのではなくて、自分用の便利ライブラリを作成する際にどの数字を採用するか、 と考えるのが非常につらい。 つか、こんな考え方の俺ってガベコレ言語を使いすぎですか。
- 378 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:20:37 ]
- ライブラリならバッファの大きさなんてユーザから指定を受け付けるものに決まっているだろ。
- 379 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:23:07 ]
- C が嫌なら C++ で string とか vector とか使えばいいよ。
- 380 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:23:59 ]
- >>369
for(;;) は可読性が乏しいから while(1) の方が好きだな。
- 381 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:25:18 ]
- >>372 373
ありがとうございました。
- 382 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:33:22 ]
- >>377
Cでライブラリ作るときは内部でバッファを抱えない。 (char *buf, size_t bufsize) で受けるのがお約束。 高級にやりたいならmalloc, freeでやってバッファがあふれたらreallocで拡張。 手を抜きたいなら#defineで固定バッファであふれたらASSERTでとめるか放置してバッファオーバーフロー。 大体この三種類だな。重要度とパフォーマンスを秤にかけて好きにしとけ。 1kbと4kbのどっちが妥当かなんて答えようがない。
- 383 名前:367 mailto:sage [2007/06/30(土) 12:45:56 ]
- >> 382, 379, 378
どうもありがとうございました。 後は、自分で考えることができそうです。 ついでにもう一つ聞いてもいいですか? 文字列の配列を作るときに、 ダブルポインタを採用するのがいいか、リンクリストを採用するのがいいか迷っています。 どちらがお勧めですか?
- 384 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:48:35 ]
- それは定数か? それとも実行中に作りたいのか?
- 385 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:50:49 ]
- >>383
使い方によるだろ よくわからないならダブルポインタの方が扱いやすいかな?
- 386 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 12:55:20 ]
- リストなんて糞なもん使わずにchar**な配列作っとけ
- 387 名前:367 mailto:sage [2007/06/30(土) 13:02:55 ]
- >>385, 384
ありがとうございます。 構造体でどちらで定義しようかな、と考えていました。 typedef struct { char *dstr; int dlen; } DATUM; typedef struct { DATUM *ptr; int size; } DATUMLIST; とするか、 typedef struct _DATUMLIST { char *dstr; char dlen; struct _DATUMLIST *next; } DATUMLIST; とするか迷っていたのです。まぁ、迷わずに実装してしまえば、どちらでもいいような気がしますが。
- 388 名前:367 mailto:sage [2007/06/30(土) 13:06:07 ]
- >>386
それも考えました。 無駄に考えるのがよくないのですかね。 この際、char**な配列の方が楽のような気がしてきた。
- 389 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:08:33 ]
- int型を指すポインタ int* p;
一次元ポインタ配列 int** p; 二次元ポインタ配列 int*** p; 三次元ポインタ配列 int**** p; って風にスターを増やしていってもいいの?
- 390 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:09:42 ]
- #include <stdio.h>
int multiple(int, int); main() { } int multiple(int x, int y) { if(y%x == 0) return 1; else return 0; } multiple関数を使って二つの整数を比較し 二つ目の整数が一つ目の整数なら1(真)、 それ以外なら2(偽)を返すというプログラムを作りたいのですが main関数をどうすればいいのかわかりません
- 391 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:11:44 ]
- >>389
int** p; は int* 型を指すポインタだ。 それが必要になれば使う。普通に使う。
- 392 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:12:34 ]
- >>390
main 関数で何がしたいのか分からないので こちらにもどうすればいいのか分かりません。
- 393 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:14:28 ]
- >>389
スターじゃなくてアスタリスクじゃね?
- 394 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:16:08 ]
- 普通にどちらも使う。
フォントによっては実際に星型なってることもあるし。
- 395 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:16:22 ]
- >>391
ありがとう >>390 if(y%x == 0) ってyに0が入ってきたらy%xは必ず0になって比較にならないんじゃね?
- 396 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:20:45 ]
- >>395
0 はあらゆる数の倍数(0 倍)だから動作的に問題ない。
- 397 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:23:12 ]
- xが0の時のほうがまずいよな。
- 398 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 14:30:47 ]
- まあ、どこまでエラー処理するかは状況次第だな。
assert するだけにしておくか、 それともエラー時に何か特別な処理をしてエラー復帰するか。
- 399 名前:390 mailto:sage [2007/06/30(土) 15:24:33 ]
- main関数では、変数を二つスキャンして
それをmultiple関数に渡し、multipleでの結果を main関数に返してプリント というふうにしたいです
- 400 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 15:27:56 ]
- そう書けばいいんじゃないかな。
- 401 名前:390 mailto:sage [2007/06/30(土) 16:26:43 ]
- その書き方がわからなくて困ってます
- 402 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 16:30:21 ]
- そうですか。
- 403 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 16:30:50 ]
- エラー出てもいいからとりあえず書いてみれ。
それでも分からなければ、 自分でどうやってみたかをここにコピペしてみれ。
- 404 名前:390 mailto:sage [2007/06/30(土) 17:12:58 ]
- どうしてこんなにお願いしているのに教えてくれないんですか。
もったいぶらないで今すぐに教えてください。
- 405 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:20:13 ]
- #include <stdio.h>
int multiple(int, int); int main(void) { int x, y; scanf("%d %d",&x,&y); if(x == 0) return 1; printf("%d\n",multiple(x,y)); return 0; } int multiple(int x, int y) { return (y%x!=0)+1; } 二つ目の整数が一つ目の倍数なら1 と解釈してやってみた つかここ宿題スレだっけ?
- 406 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:20:22 ]
- うわ・・・
- 407 名前:390 mailto:sage [2007/06/30(土) 17:21:03 ]
- #include <stdio.h>
int multiple(int, int); main() { int a,b; scanf("%d%d\n", &a, &b); printf("%d\n", multiple(a,b)); return 0; } int multiple(int x, int y) { if(y%x == 0) return 1; else return 0; } このプログラムだと一応実行できるのですが 整数を二つ入力しても動かず、もう一つてきとうに整数を入れると 最初の二つの整数について判断します。 例えば 2 4←ここで4は2の倍数なので1が返ってくる はずなのですがそこでは処理がされず 5←さらに適当に整数を入力する 1←すると結果が返ってくる と、こんな感じです 整数を二つ入力した時点で処理結果を返したいのですが いいでしょうか?
- 408 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:22:14 ]
- >>404
>main関数をどうすればいいのかわかりません >というふうにしたいです >その書き方がわからなくて困ってます 一度もお願いなんかされてないんだが。
- 409 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:25:25 ]
- >>408
行間も読めないんですか? とか言われそうだなw >>407 scanf()とprintf()のフォーマット文字列は互換性がないと思ったほうがいい。 あんたのコードは明らかにscanf()のフォーマット文字列が間違っているぞ。
- 410 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:26:28 ]
- >>409
お前こそ行間が読めてないなw
- 411 名前:409 mailto:sage [2007/06/30(土) 17:30:06 ]
- >>410
大丈夫、初めから読もうとしてないから。
- 412 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:37:36 ]
- これはひどい
- 413 名前:390 mailto:sage [2007/06/30(土) 17:43:19 ]
- >>409
助言ありがとうございます それと404は私ではないのであしからず
- 414 名前:390 mailto:sage [2007/06/30(土) 17:57:37 ]
- main()
{ int a,b; printf("整数1:"); scanf("%d", &a); printf("整数2:"); scanf("%d", &b); printf("%d\n", multiple(a,b)); return 0; } 407のmain部分を上のようにしたら理想通りに実行されたのですが なぜ上手くいったのかがよくわかりません。 誰かその理由を説明してください。
- 415 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 17:59:15 ]
- >>414
>>409の最後の行
- 416 名前:390 mailto:sage [2007/06/30(土) 18:02:29 ]
- 間違っていることはわかりましたが
407のscanf()はどういけないんですか?
- 417 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 18:02:51 ]
- \n
- 418 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 18:03:23 ]
- >>416
\n
- 419 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 21:07:21 ]
- もし A、B、C、Dのいずれかを満たしたら、、、と出力
それ以外なら。。。と出力 とするにはどうやればいいですかね?
- 420 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 21:20:02 ]
- >>419ですけど自己解決しますたー
- 421 名前:デフォルトの名無しさん mailto:sage [2007/06/30(土) 23:23:30 ]
- #include<stdio.h>
#include<string.h> main(){ char c[3]; char s1[]="abcdefghijklmnopqrstuvwxyz" char s2 [100]; s2[0]='\0'; printf("s1 inital value:\"%s\"\n",s1) printf("s2 inital value:\"%s\"\n",s2) if cstrcmp(s1,s2)==0){ printf("s1==s2\n");} else{printf("s!=s2\n");} printf("Push ENTER to proceed."); fgets(c,2,stdin); strcpy(s2,s1); printf("s1 current value:\"%s\"\n",s1); printf("s2 current value:\"%s\"\n",s2); if(strcmp(s1,s2)==0) { printf("s1==s2\n");} else{prinf("s1!=s2\n");} } のプログラムのfgets(c,2,stdin); ってなんですか?なんの役割ですか?
|

|