C言語なら俺に聞け(入門編)Part 61at TECH
C言語なら俺に聞け(入門編)Part 61 - 暇つぶし2ch175:デフォルトの名無しさん
10/03/09 20:40:07
引数は整数になってると思うけど桁数を増やしたいって話?
20桁未満ならgccはlonglong使えるんじゃないか

176:165
10/03/09 21:15:02
>>174
試してみます。

>>175
桁数を増やすのと、

例えばint型を使っていて、
引数argv[1]がその上限を超えたときに
エラーにしてくれるようなチェック方法を知りたいです。


177:デフォルトの名無しさん
10/03/09 21:45:35
>>176
コマンドラインオプションの解析は getopt(3)でいいんじゃない?
自分で判定するのは面倒でしょ。

パラメタを整数にするのも、strtol とかstrtoll あたりでいいかと。
上限超えたらどうなるかは、man 見れば載ってると思う

178:デフォルトの名無しさん
10/03/09 23:12:10
ヘッダファイルで

#define RED 1
#define BLUE 2
.....

#define YELLOW 100

と数百個定義しているのですが(全部定義しているわけではない)
結構順番を入れ替えます.そこでインクリメンタル的なものをつかえないかと思っているのですが,
よい方法ございますでしょうか?

よろしくお願いします.


179:デフォルトの名無しさん
10/03/09 23:14:01
enum

180:デフォルトの名無しさん
10/03/10 16:36:16
ヒープメモリとスタックメモリって読み書き速度に差はあるの?

181:デフォルトの名無しさん
10/03/10 16:37:55
>>180
スタックは頻繁にアクセスされるためCPUキャッシュに乗った状態の可能性が高い

182:デフォルトの名無しさん
10/03/10 17:09:32
スタックもヒープも物理的に差はない。
C言語がやりくりする一定値のメモリがスタック。OSに問い合わせしないので解放取得が速い。
ヒープはOSに問い合わせる。
スタックもプログラム開始時にOSに問い合わせて取得する。
OSはこの二つの違いは認識しない。使われていなければ、スタックでもページアウトする。

183:デフォルトの名無しさん
10/03/10 17:12:31
100Mとか多めに確保したヒープにランダムアクセスしたら遅くなるが
確保できたとしてスタックでも同じ程度の速度。
はじめに一定値を確保してあるか無いかの違いだけ。

184:デフォルトの名無しさん
10/03/10 17:13:31
スタックはメモリプールという機能と同じってこと。

185:デフォルトの名無しさん
10/03/10 17:28:47
Windowsを初め、比較的新しいOSではスタックも追加確保
されるる時にOSに問い合わせます。

186:デフォルトの名無しさん
10/03/10 17:31:37
XPはスタックオーバーフローするが。
vistaからはそうなったか。

187:デフォルトの名無しさん
10/03/10 18:12:17
>>185
OSが許容するスタック上限値よりずっと低いスタック量で
プロセスを起動しても、行儀の良いプログラムだったら
問題がないんでそうしてるわけですね。
少し「仕事をする」(再帰とか使ってたり、ローカル変数に
配列とか大量に確保する)プログラムだったら当然それでは
足りないからスタックオーバーフローする。そのタイミングで
OSはスタックを追加してプロセスを停止させず続行するわけ
です。

188:デフォルトの名無しさん
10/03/10 18:30:49
OS的には、変数は極力グローバル変数に確保し、再帰を使わない
プログラムであることを望んでいるというわけですね

189:デフォルトの名無しさん
10/03/10 18:43:30
OSはスタック追加などしないぞ。OSから見たらカタックとヒープの違いはない。
MS-DOS Windwos3.1では区別はあったとおもうが。
Windwos3.1はスタックの固定領域を指定して使い切ったら駄目だった気がする。

190:デフォルトの名無しさん
10/03/10 19:00:26
MS-DOSにおいて、カーネルを含むプログラムの実行に確保できるメモリ空間(コンベンショナル・メモリ)は8086のアドレス空間の最大1MBである。
ほとんどのコンピュータでは、この空間にBIOS ROMやメモリマップドI/O、VRAMなどの空間も存在するため、
アクセス可能なメモリ空間は最大でも640KBから768KB程度であった。
ただし、バンクメモリやEMS、プロテクトメモリ(80286/386以降)等のコンベンショナルメモリ以外の領域・手段の利用が一般化していたため、
「貴重な」コンベンショナルメモリがこれらの領域によって圧迫されることはなかった。

日本語入力用のFEPなどの常駐型のデバイスドライバを使用すると一度に使用できるユーザーメモリはさらに減少するため、
ユーザーはEMSやXMS、HMAやUMBなどの拡張メモリの管理機能を利用して、
辞書や常駐部やMS-DOSシステムの一部をそれらへ配置し、コンベンショナルメモリの圧迫を少しでも避けることが重視されるようになった。

「とりあえず動く」という状態を作るだけであればエンドユーザーがこれらを直接操作する必要はほぼ無かったが、
「とりあえず」に飽き足らず無駄を省き最適な設定をするためには知見と試行錯誤が要求されるある種の職人芸的な資質が要求されたため、
これらの事情が「MS-DOSの環境設定は非人間的で困難なものであった」とする後世の評価を招く原因ともなった。
MS-DOS - Wikipedia

191:デフォルトの名無しさん
10/03/10 19:32:23
XPでもコンベンショナル・メモリのような設定あるんだがな。
デスクトップアプリケーションヒープ、非対話型サービスヒープの設定可能。
ここ変えないといくらメモリふやしても、メモリ不足改善しないことある。

192:デフォルトの名無しさん
10/03/10 20:22:20
Win3.1の場合、8086向けのコンパイラを若干改造した
もので生成出来るコードでGUIアプリが作れるという
のが基本設計
8086ではスタックの動的変更を行う一般的
方法のCPUアーキテクチャーレベルのサポートは
殆ど無いしコンパイラでもサポートしている例は
皆無。

193:デフォルトの名無しさん
10/03/10 20:26:14
おまえは勘違いしている。
スタックというのは、OSから見たら特別な領域でない。
スタックとヒープというのは、C言語(その他)から呼ばれているだけ。
どっちもOSに合わせたメモリ取得関数を呼び出して確保する。同じもの。

194:デフォルトの名無しさん
10/03/10 20:30:58
昔のOSは区別してあった領域があるかもしれないが
いまのメモリ確保はどれ使っても、OSレベルでは結局は一通りのメモリ確保しかないだろ。
レジスタとかGPUとかは別。

195:デフォルトの名無しさん
10/03/10 20:39:53
>>179
ありがとうございました.
うまくいきました.

196:デフォルトの名無しさん
10/03/10 21:20:04
暴れてる長文バカも
同じくらい環境依存なのに
startupコードやセクションの話になるとサクッと黙るんだよな

197:デフォルトの名無しさん
10/03/10 23:15:37
>>193
WindowsはCPUレジスタそのものを管理しないって?
んなことない。ないからこそ他のプロセッサ向けに移植
されていない。初期のWinNT(4.0まで)はプロセッサ
が今のように分化してないから対応できたんだろうが
さすがに無理になってしまって現在はIntel以外は非対応

198:デフォルトの名無しさん
10/03/10 23:19:13
レジスタやGPUメモリは専用命令で扱えるが
スタックとヒープを区別して扱う命令はない。
OSではこれらの差はない。

199:デフォルトの名無しさん
10/03/10 23:19:18
おっとMovail (CE)とかは上位レイヤーや言語インターフェース
の互換性があるだけでメモリアーキテクチャーはIntel版とは全然違ってると考えたいね。HD非搭載なマシンでも動作させる必要がある
わけだから違って当然だけど

200:デフォルトの名無しさん
10/03/10 23:25:22
入門スレであまり難しい話しないでよ

201:デフォルトの名無しさん
10/03/10 23:33:17
>>197
alpha とかサポートやめた主な理由は商業的なことで
儲かるとなれば技術的な問題はどうとでもなったはず

202:デフォルトの名無しさん
10/03/11 01:06:16
>>198
何を根拠にそういうこと言い切っちゃうの?

OSが無い環境もあるし、物理的にアクセス速度が違うメモリに振り分けられることもあるだろう。
結局は環境を絞らないと何も言えない。

203:デフォルトの名無しさん
10/03/11 02:11:18
Javaならどうだろうか?

204:デフォルトの名無しさん
10/03/11 02:36:13
Intelと一口に言っても、x86/x86-64とIA-64はまったく別物だしね。

205:デフォルトの名無しさん
10/03/11 02:55:40
CPUが特殊命令持っていて、スタック動作を速くすることが出来たとしても
それが付いてないCPUでも、スタック、ヒープメモリは使えないといけない。
これより、C言語のスタックとヒープはソフトウェアとしての用語。

206:デフォルトの名無しさん
10/03/11 02:58:52
コンパイラの実装次第だがWindowsXP以降では、
スタックもヒープも同一のメモリ確保関数を使っているだろう。
すべてのコンパイラを知っているわけではないが。
CPUレジスタやCPUキャッシュのみをスタックに使う実装も出来ないことはないけど
ないんでは。

207:デフォルトの名無しさん
10/03/11 03:24:29
「スタック処理支援命令が付いていないプロセッサなどCPUと
呼んではいけない」
という意見には必ずしも賛成ではないが、付いていることを
前提とするかしないかでは、OSのカーネル開発の開発者の
集団力学には大きな影響が発生し、それがOS全体に
作業環境全体に与える影響力は計り知れず、スタック支援命令が
ついたプロセッサ上のOSしか知らない俺にとっては
とてもじゃないが反対だとも言えない。

208:デフォルトの名無しさん
10/03/11 04:07:46
ハードウェアのスタック機能と、C言語のスタックとヒープは
名前と動作は似ていても別物。
C言語のスタックメモリは複雑だろ。auto変数や関数呼び出しや再帰とか。
ハードウェアの機能に丸任せできないだろ。

209:デフォルトの名無しさん
10/03/11 04:14:51
>>181で答え出てるのにまだ続けるのか

210:デフォルトの名無しさん
10/03/11 04:23:33
C言語に限らずプログラミングで頻繁に出現する
データ構造の総称的名称としてのスタックやヒープと
CPUが決定する「具体的な」ものとでは使われる
コンテクストが全く違うだろうな(特に範疇性)
同じ用語を用いていてもコンテクストが全く異なる
ので同じコンテクストで使われていると決めつける
と何かと混乱の原因になりやすい鴨

211:デフォルトの名無しさん
10/03/11 04:48:24
文字列が数値かどうか判定するのにisdigitを使うと
マイナスや小数が誤判定されてしまいますが
これらも正しく数値と判定させるためには自前で関数用意するしかないのでしょうか。

212:デフォルトの名無しさん
10/03/11 04:52:39
>>211
isdigitは数字かどうかを判定する(一般には)マクロ
なんで、数値かどうかの判定を一発でするのは
無理
受け取った文字列をsscanf等で数値に直したものを
人の目を通して確認してもらうのが一番
0.9994242123123232132という文字列を数値
に直したのを表示させた時に
0.9994242123123456789
となった場合にそれが問題なのかどうかは状況に
依存。

213:デフォルトの名無しさん
10/03/11 05:41:48
>>211
atoiやatof等で不満なら自作するしかないね。

214:デフォルトの名無しさん
10/03/11 06:01:50
レスどうもです。
sscanfだと"1xyz"みたいに先頭だけ数字の文字列も数値として通ってしまうなぁ・・
と試行錯誤してたらatofで完璧でしたどうもありがとうございます。

215:デフォルトの名無しさん
10/03/11 06:10:06
とおもったらatofでもやはり先頭が数字だとだめでした;;

216:デフォルトの名無しさん
10/03/11 06:32:11
>>208
べつに、auto変数や再帰や関数の引数で特別なことはやっていないし C 言語のスタックメモリが複雑とも思えませんけれども。

217:デフォルトの名無しさん
10/03/11 07:00:12
>>215
じゃぁ、自作だね。
チェック関数だけ書いて後はatofに流すのが無難かなっと思うけど
用途や目的次第なのでお好きにどうぞ。

218:デフォルトの名無しさん
10/03/11 13:54:53
>>215
#include<stdio.h>

double get_value(const char *str)
{
double value;
int n;

if(sscanf(str, "%lf%n", &value, &n)==1)
{
if(str[n]=='\0') return value;
}
return -1.0;
}

#define TEST(str) printf("[%s]=%f\n", str, get_value(str))

int main(void)
{
TEST("0.12345");
TEST(" 0.12345");
TEST("0.12345 ");
TEST("1xyz");
return 0;
}

219:デフォルトの名無しさん
10/03/11 15:01:30
素直にstrto{l,ul,d,f,ld}を教えてやれよ

220:デフォルトの名無しさん
10/03/11 18:54:28
スレチかもしれませんが
URLリンク(detail.chiebukuro.yahoo.co.jp)
これ、答えて下さいませんか?

221:デフォルトの名無しさん
10/03/11 18:56:35
>>220
スライドショー フリーソフト でggrks

222:デフォルトの名無しさん
10/03/11 19:57:20
断片化対策にこういうことってやっていいの?
サイズ違うのにキャストしても大丈夫かな?

void *my_allocate(size_t size)
{
    return malloc(size / 4 * 4 + 4);
}

void my_deallocate(void *address)
{
    free(address);
}

int main(void)
{
    char *pc = (char *)my_allocate(sizeof char);

    *pc = 'c';

    printf("%c", *pc);

    my_deallocate(pc);

    return 0;
}

223:デフォルトの名無しさん
10/03/11 20:05:17
>>222
多いのは大丈夫
不足するのはダメ

224:デフォルトの名無しさん
10/03/11 21:59:52
>>222
4バイト単位で大きさ調整しても意味なさそう。

225:デフォルトの名無しさん
10/03/11 23:24:21
その式だと、最初から4の倍数だった時、必要なサイズより4バイト大きくなってしまう
普通はビット演算を使うと思う
(size + 0x00000003) & 0xfffffffc

226:デフォルトの名無しさん
10/03/11 23:46:52
>225
それはsize_tが何バイトだと想定しているわけ
いや、むしろ何ビットといった方が良いのかな

227:デフォルトの名無しさん
10/03/12 01:10:36
(size + 3) / 4 * 4
だな

228:デフォルトの名無しさん
10/03/12 01:54:07
>>226
それなら、0xfffffffcを~(size_t)3にでもすればいいと思う。

229:デフォルトの名無しさん
10/03/12 02:32:04
~((size_t)3)かな

230:デフォルトの名無しさん
10/03/12 02:41:42
昔は乗除算は必ずシフトに展開しろと教わったもんだが
今のCPUだとコストに差はないのかな
(size + 3) >> 2 << 2

231:デフォルトの名無しさん
10/03/12 02:48:41
演算子の強度低減ぐらいなら処理系がうまく最適化してくれるので
意図をそのまま表現するのが良いとされるようになってきたような

232:デフォルトの名無しさん
10/03/12 02:59:55
/ 4 * 4 も >> 2 << 2 も & 0xfffffffc に最適化してくれるね

233:デフォルトの名無しさん
10/03/12 03:35:43
素直に「4の倍数に切り上げ」ってコメントに書くわ
どんなに簡単な処理でもコメントがあった方が読みやすいし
とくに何年も前に書いたソースだと

234:デフォルトの名無しさん
10/03/12 15:01:25
>>233
まさかとは思うが、こんなコードは書かんでくれよ。
++count; // カウントのインクリメント

235:デフォルトの名無しさん
10/03/12 15:08:47
教えてください。

システムソフト開発の会社に入ってそろそろ10年。
サポートや試験担当ということもあって、
まったく言語というものを知らずに来ました。

最近、なんかまずいかな?
と思い始めて「猫C」を買って勉強しています。

でも、特に目的がないせいか、
この本やったあと次はなにを勉強すればいいかわかりません。

なにかおすすめの書籍があれば教えてください。


236:デフォルトの名無しさん
10/03/12 15:11:00
なにがまずいの?

237:デフォルトの名無しさん
10/03/12 15:11:31
会社の言語やってるやつに聞け
実用で使われないやつやっても無用の長物
配置転換でリストラにならないように現場で使われる率高いやつ

238:デフォルトの名無しさん
10/03/12 15:13:50
C言語などいくらやっても徒労に終わる
基礎が出来ても完成品が出来るまでの道のりは険しい
自分でした独習など焼け石に水状態 
会社でやってるのをピンポイントでやるべき

239:デフォルトの名無しさん
10/03/12 15:17:38
ありがとうございます。

.NET(C#?)の問い合わせが多いので
その言語のサンプルを読めるようになると
サポートの幅は広がるよね。
とは言われました。

そうか、と思いつつ、
基本である(と思っている)C 言語の初歩本くらい
やっといた方がいいのかな、
と思ってせこせこやっていました。



240:デフォルトの名無しさん
10/03/12 15:20:59
あとC#で何分野やってるのかも聞くといい。 
GUIとかゲームとかネットワークとか。
その分野を重点してやる。

241:デフォルトの名無しさん
10/03/12 15:25:07
C#で開発ってXbox360かと思った。

242:デフォルトの名無しさん
10/03/12 17:16:54
>>239
土方を目指すのでなければCは必須

243:デフォルトの名無しさん
10/03/12 18:00:22
Cできたところで結局ドカタなんすけどね

244:デフォルトの名無しさん
10/03/12 18:37:40
switch(c->programming){
 case YES:
  printf( "Cができるとは素晴らしいですね\n" );
 default:
  c->status = "土方"
  break;
}

245:デフォルトの名無しさん
10/03/12 19:05:31

浮動小数を文字列に変換する方法について教えてください。
求める動作は次のとおりです:

* double型を文字列に変換
* printf系などの外部関数で変換しない
* 整数は整数として表示(小数点を付けない)
* 小数点以下の不必要な0は付けない
* 有効な精度(15桁程度?)で適当に丸める
* 出力が長い場合も扱える(例えば、「12340000000000000000000」など)

いろいろやってみたのですが思い通りのものが作れなかったので・・・
アイデア・ヒントいただければと

自分で作ってみたものも一応晒しておきます。
↓だと、「456」のときに「459.9999...」となってしまいうまくいきません。
URLリンク(codepad.org)


246:245
10/03/12 19:07:20
↑の「459.9999...」は「455.9999...」の間違いでした。
申し訳ない。


247:デフォルトの名無しさん
10/03/12 19:44:29
配列を関数に渡して、その値を取得したいんですが、上手くいきません
どうすればいいでしょうか?

248:デフォルトの名無しさん
10/03/12 19:46:36
>>247
[50] を除けばいいかも

249:デフォルトの名無しさん
10/03/12 19:58:47
すみません、取得したいというのは

int test[10];

func( &test );

a = test[ n ];

というつもりでした

250:デフォルトの名無しさん
10/03/12 21:00:10
>>249
質問がよく判らんが、こういうことか?

void func(int * test)
{
test[0] = 1;
}

void caller()
{
int test[10];
func(test);
int a = test[0];
}

251:デフォルトの名無しさん
10/03/12 21:47:19
>>250

それだと関数の中で1を代入しても関数を呼ぶ側では変化しないと思うんですが
普通の変数をポインタで引数を渡して変更した値を取得するプログラムの配列バージョンみたいなのは可能でしょうか?

252:デフォルトの名無しさん
10/03/12 21:56:56
変化しましたけど。。
URLリンク(codepad.org)

253:デフォルトの名無しさん
10/03/12 22:57:46
勘違いしてました
解決しました
ありがとうございます

254:デフォルトの名無しさん
10/03/12 23:31:42
>>238
違うね
「基礎ができて」ない奴の道のりが険しいだけ

計算をしっぱなしな奴と、ちゃんと検算する習慣がある奴の違いは
小学校で受けた教育の質から来る

255:デフォルトの名無しさん
10/03/12 23:33:45
基礎からやればいいじゃん
簡単なプログラム書くときでもホーア論理とか記述的意味論とか使って検証しながら書くとかさ

256:デフォルトの名無しさん
10/03/12 23:58:26
>>222
mallocがアライメント調整してるのに自前でもやる意味あるのかな?

257:デフォルトの名無しさん
10/03/13 00:04:47
「何故かは分からんが出来たからいいや」

こういうタイプは一生伸びない。
応用できるのは何故そうなったか、つまりプロセスの部分であり、解は応用できないからである。

258:デフォルトの名無しさん
10/03/13 00:12:55
うるせーばか
既解決問題の証明を一生再生産してろ

259:デフォルトの名無しさん
10/03/13 00:19:19
こうしてHTMLは死んだ

260:デフォルトの名無しさん
10/03/13 01:23:10
>>256
malloc()がアライメント調整してない場合も、pragma指定かAPIで調整できる場合が多いね。

261:デフォルトの名無しさん
10/03/13 05:35:26
>>239
10年っていったらもう30前後なんだろ?
今更言語やっても身につかないし
そんな奴は役に立たない

262:デフォルトの名無しさん
10/03/13 08:36:24
確かに>>261は役に立たない

263:デフォルトの名無しさん
10/03/13 12:47:32
>>261
お前使えねーな

264:デフォルトの名無しさん
10/03/13 12:52:07
>>261
ごめん。相当気持ち悪いな、お前

265:デフォルトの名無しさん
10/03/13 13:06:55
261の人気にシット☆

266:デフォルトの名無しさん
10/03/13 13:16:18
shit?

267:デフォルトの名無しさん
10/03/13 17:04:47
執刀

268:デフォルトの名無しさん
10/03/13 19:58:55
ファイルが存在すれば追記でオープン
ってのを格好よく書くにはどうしたらいいかな

あればエラー無ければ作成ってオプションならfopen()にあるけど
逆なんだよな~access()使うの面倒くさいな~

269:デフォルトの名無しさん
10/03/13 20:04:45
質問です
ネストって一般的に何重が限度ですか?

270:デフォルトの名無しさん
10/03/13 20:12:56
何のネストだよ

271:デフォルトの名無しさん
10/03/13 20:14:30
>>268 "r+" でよくね?

272:デフォルトの名無しさん
10/03/13 20:17:32
>>270
if文のです

273:デフォルトの名無しさん
10/03/13 20:40:30
C言語の弱点はネストだな。短い文で使えばいいけど
間に沢山あるとわかりにくくなる
for{}つかえときはcontinue;で括弧を引きずらないようにするといい
場合によってはgotoもいい
長い部分は関数化

274:デフォルトの名無しさん
10/03/13 20:51:43
>>269,272
> 5.2.4.1 Translation limits
> The implementation shall be able to translate and execute at least one
> program that contains at least one instance of every one of the
> following limits:
> - 127 nesting levels of blocks
> - ...

275:デフォルトの名無しさん
10/03/13 20:52:04
>>272
みっつくらいじゃね?

276:デフォルトの名無しさん
10/03/13 20:55:31
>269
ISO/IEC 9899:1999 (E)
5.2.4.1 Translation limits
1 The implementation shall be able to translate and execute at least one program that
contains at least one instance of every one of the following limits:13)
127 nesting levels of blocks
63 nesting levels of conditional inclusion
63 nesting levels of parenthesized declarators within a full declarator
63 nesting levels of parenthesized expressions within a full expression
13) Implementations should avoid imposing fixed translation limits whenever possible. number of characters as the corresponding universal character name, if any)14)
14) See ``future language directions'' (6.11.3).
15 nesting levels for #included files
1023 case labels for a switch statement (excluding those for any nested switch statements)
63 levels of nested structure or union definitions in a single struct-declaration-list
ネスト以外の限界については省かせてもらった
やっぱり63か
>274
その一つ下じゃないか

277:デフォルトの名無しさん
10/03/13 20:56:03
>>273

ネスト深くてもわかりやすい言語なんかねーよ
安易にgoto勧めんなよ
場合によって、の解釈でとんでもないことになるし
goto排斥主義者の人が来ちゃったら揉めるだろ



278:デフォルトの名無しさん
10/03/13 20:58:54
だからgoto使わなければいいだけ

279:デフォルトの名無しさん
10/03/13 21:10:33
>>276
"conditional includion" は 6.10.1 にある #if とかの話。

280:デフォルトの名無しさん
10/03/13 21:13:57
>276
あっ、ほんとだ
プリプロセッサの話だ

281:デフォルトの名無しさん
10/03/13 21:21:24
>>280
許してやる

282:268
10/03/13 21:21:26
>>271
あー、オープンしてから自分でシークすりゃいいだけか。
ありがとう。

283:デフォルトの名無しさん
10/03/13 22:19:58
プログラム勉強始めたばかりの初心者です。例えば以下のようなif文があるとします。
カッコを入れるタイミングと位置がよく理解できていません。
なんで下記のように2回連続カッコが続いて記述されるのでしょうか?
きっとそれぞれのカッコがどこで始まり終わっているのかが理解できていないと思います。
必ず対になるので偶数個になるのは理解できていますが・・・
 おかしな日本語で大変申し訳ありませんが、どなたかわかりやすく解説をお願いできますでしょうか。
よろしくお願いします


if (条件1) {
if (条件2) {
文1;
}
else {
文2;
}
} ←これは何に対してのカッコ?なんで2回連続なんだろう???
else {
文3;
}

284:デフォルトの名無しさん
10/03/13 22:25:09
>>283
2回連続しているけど、意味は別もの。
ネストしているカッコをそれぞれ別のカッコと考えれば分かると思うよ

  if(条件1)「
   if(条件2)『
     文1
      』else『
     文2
      』
 」
  else


285:デフォルトの名無しさん
10/03/13 22:26:00
>>283
例にあげた if 文自体が間違っています。
わからなくて当然です。
なんの本にかいてあったんですか?どこのサイトですか?

286:デフォルトの名無しさん
10/03/13 22:31:48
>>283です
解説ありがとうございます。いまからじっくり読んで見ます。汗
サイトはこちらです。コピペした時におかしくなっただけかもしれません 汗
URLリンク(www9.plala.or.jp)

287:デフォルトの名無しさん
10/03/13 22:51:51
>>284さんありがとうございます。
初心者の私にはこのように見えます。

if(条件1)「 ①
   if(条件2)『 ②
     文1
②』else『 ③
     文2
③ 』
 」①  ←上記の番号がきっとそれぞれ対になっていると思っています。ただ、
     条件1が満たされなかったら下のelse文に続くからこの閉めカッコは何?とも感じます。
     きっと私は文の構成の初期的なところを理解していないと思われます 汗

else

288:デフォルトの名無しさん
10/03/13 22:56:51
才能無い奴はやめてしまえ
おまえがC言語をやらなくてもかわりはいくらでもいる
ゴミなんだよお前は

289:デフォルトの名無しさん
10/03/13 22:58:46
むやみに煽りすぎだろ。

290:デフォルトの名無しさん
10/03/13 22:59:35
最初のうちは↓のような書き方をした方が分かりやすいかも

if (条件1)
{
  if (条件2)
  {
    文1;
  }
  else
  {
    文2;
  }
}
else
{
  文3;
}

291:デフォルトの名無しさん
10/03/13 23:00:31
煽り?どこがだよ!お前もそうおもうだろ!正直に言えよ!

292:デフォルトの名無しさん
10/03/13 23:01:36
ifの中にifがはいってるってことはわかってる?
「ネスト」で調べてみましょう

293:デフォルトの名無しさん
10/03/13 23:12:57
>>291
ま、正直、あまりに根本的なところで、なんで?なんで?って聞かれるとイラっとはする。

294:デフォルトの名無しさん
10/03/13 23:13:35
>>288
視野が狭いな
まさに土方の考え方だわ

295:デフォルトの名無しさん
10/03/13 23:15:27
>>294
はぁ?じゃあお前がちゃんと答えればいいじゃねえか!てめえがびしっとこたえねえからこんな事になってんだろ!クソが!

296:デフォルトの名無しさん
10/03/13 23:17:04
まず落ち着いて入門書を読むレベルだろコレ
おまえらが半端に親切にするからチャット状態で何も考えずに質問しちゃうんだよ

297:デフォルトの名無しさん
10/03/13 23:18:52
九九の表を覚えないのに掛け算するレベル。

298:デフォルトの名無しさん
10/03/13 23:21:26
この程度で才能なのかよ。
可哀想だなお前ら。。

299:デフォルトの名無しさん
10/03/13 23:25:00
この程度もできないのはまさに才能だろうな。

300:デフォルトの名無しさん
10/03/13 23:25:07
>>287 
疑問の回答になってるかわからないけど、

 if( 条件1 ){
   略
 }                     ←このカッコ
 else {
      略
 }

このカッコは、"else"があれば終わりが分かるんだから
不要じゃないか?っていう疑問なら、確かにその通り。
でもそれは"else"が来る場合限定の話で、else の来ない場合はそうじゃない。

C言語は、カッコでくくったブロックが基本単位になってるんだけど、
この辺りの感覚が分かってくると、閉じカッコが2重につくのも納得いくと思うよ

301:デフォルトの名無しさん
10/03/13 23:26:58
変なところでひっかかる人はたまにいる
んで、引っ掛かりが取れたらグンと伸びることも結構ある
283もそうなのかは分からんけどね

302:デフォルトの名無しさん
10/03/13 23:28:06
んじゃとりあえず期待。

303:デフォルトの名無しさん
10/03/13 23:28:08
>>287
条件1が満たさた場合、「 ①から」①までが実行される。
どこからどこまでか範囲を指定してるから、どこまでを示す閉めカッコが必要。
範囲じゃない場合は省略できるが、最初のうちは必ず{}でくくっておいた方がいいと思う。

304:デフォルトの名無しさん
10/03/13 23:29:55
if (条件1) {
if (条件2) {
文1;
}
else {
文2;
}
}
else {
文3;
}

if ( (条件1) && (条件2){ 文1;}
else if( 条件1) { 文2; }
else {文3;}と等価でよいでしょうか?

305:デフォルトの名無しさん
10/03/13 23:32:55
実際に条件式書いてコンパイルしてみたら分かるでしょ。

306:デフォルトの名無しさん
10/03/13 23:33:00
if (条件1) {
  if (条件2) {
    文1;
  }
  else {
    文2;
  }
}
else {
  文3;
}

307:デフォルトの名無しさん
10/03/13 23:34:32
>>304
一般的には等価ではない。条件1を再度評価したとき同じ結果が
返るとは限らないから

308:デフォルトの名無しさん
10/03/13 23:35:21
>>304
条件1が評価時に変化しなければ等価

309:デフォルトの名無しさん
10/03/13 23:38:28
そんな条件の条件があるのなら等価じゃないだろ

310:デフォルトの名無しさん
10/03/13 23:40:24
そもそもコーディングの意図が明らかに違う

311:デフォルトの名無しさん
10/03/13 23:41:36
だから適当な変数を用意して
int 条件1結果;

条件1結果=(条件1)?1:0;

if ( (条件1) && 条件2 ){文1;}
else if(条件2) {文2;}
else {文3;}
と書くのがもっとも無難じゃないかと...

312:デフォルトの名無しさん
10/03/13 23:41:39
質問に答えてください

313:デフォルトの名無しさん
10/03/13 23:44:41
ここで聞くより入門書を買って読んだ方が手っ取り早い

314:デフォルトの名無しさん
10/03/13 23:47:31
ここは
「C言語なら俺に聞け(入門編)」
です
煽るだけの奴は去れ

315:デフォルトの名無しさん
10/03/13 23:48:00
>>312
お前が質問するのは自由だが、それに答えるかどうかもこっちの自由だ。


316:デフォルトの名無しさん
10/03/13 23:49:48
煽るだけじゃなく、例えば荒らしもする奴は居てもいい。


317:デフォルトの名無しさん
10/03/13 23:50:22
>>314
スレタイにだまされるな。
初心者の質問をネタに雑談するスレだ。

318:デフォルトの名無しさん
10/03/13 23:50:52
>>1
>C言語の*入門者*向け解説スレッドです。

質問または答えない奴はここにいる資格は無い

319:デフォルトの名無しさん
10/03/13 23:51:47
じゃあ俺に聞けなんて自信満々にいわないでください
スレタイをC言語なら入門書を読んだ上でたまになら俺に質問してもいいよ(入門編)に改名するべきです

320:デフォルトの名無しさん
10/03/13 23:53:01
質問を議題とし、初心者同士がディスカッションするスレだよ

321:デフォルトの名無しさん
10/03/13 23:53:14
自信満々に答えられないなら来なきゃいいのに。

322:デフォルトの名無しさん
10/03/13 23:53:20
>>317
それでいいんだよ
通ぶってても規格票と違っている事を固く信じ込んでいる事はよくある

323:デフォルトの名無しさん
10/03/13 23:53:54
>>319
「俺に聞け」なんて不遜な言い方、ジョークに決まってるだろ。

324:285
10/03/13 23:54:08
>>283
んー、私が間違っていましたね。
これであっています。失礼いたしました。
で、こういう書き方をすればわかりやすいかもしれませんが、いかがでしょうか。
if (a == 0) {
  if (b == 0) {
    x = 0;
  } else {
    y = 0;
  }
} else {
  z = 0;
}

325:デフォルトの名無しさん
10/03/13 23:54:37
マジに、ただひたすら初心者様に奴隷のように教えるだけのスレになったら回答者なんてだれもよりつかなくなるよな。

326:デフォルトの名無しさん
10/03/13 23:57:57
低レベルな回答者はいらないです。

327:デフォルトの名無しさん
10/03/13 23:59:01
逆ギレすんなよ

328:デフォルトの名無しさん
10/03/14 00:05:41
ヤフの質問箱とかOKWebとかなら、むやみに煽られないんじゃないのかね。
あそこらは「君たちは質問の意図を理解してませんね。
そういうことはいいから早く質問にこたえなさい」系の物言いも許されるイメージ。
あんまり見てないから知らんけど。

329:デフォルトの名無しさん
10/03/14 00:17:35
if文のネストで巧くいかなかったら
条件式を工夫してみろ

条件式をいじってうまくいかなったら
if文のネストを工夫してみろ

両方駄目だったらあきらめろ

言えることはこれくらいかな

330:デフォルトの名無しさん
10/03/14 00:29:35
聞くだけならいくらでも聞いてやる
ただし答えるとは誰も言ってない

331:デフォルトの名無しさん
10/03/14 00:32:42
答えないならせめてずっと黙ってろ

332:デフォルトの名無しさん
10/03/14 00:34:53
いや質問があるなら俺に聞けよ

333:デフォルトの名無しさん
10/03/14 00:34:56
<object width="480" height="385"><param name="movie"
value="URLリンク(www.youtube.com)">
</param><param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="URLリンク(www.youtube.com)"
type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"
width="480" height="385"></embed></object>


このプログラムを教えてください。私のレベルは、cを少しかじっただけです。

334:デフォルトの名無しさん
10/03/14 00:35:56
>>329
最初から理屈だけで覚えようとすると得てして失敗しやすいからな

335:デフォルトの名無しさん
10/03/14 00:38:15
>>333
Cをかじったなら、それはCじゃないってわかるだろ。

336:デフォルトの名無しさん
10/03/14 00:40:14
おCりかじり虫~

337:デフォルトの名無しさん
10/03/14 01:08:45
鉄分ミネラルビタミンCは

338:デフォルトの名無しさん
10/03/14 11:08:49
保存済みのメモ帳に書いてある10個の数字からランダムに5個読み取りたいんですけど、
fopen、fscanf、for、ifのみを使ってそのようなプログラムを作ることって可能なのでしょうか?

339:デフォルトの名無しさん
10/03/14 11:11:26
不可能

340:デフォルトの名無しさん
10/03/14 11:12:15
手書きだったら、スキャナで読み取って画像認識しなければ
ならないから、相当難しいだろうな。
しかも使える関数や構文にも強い制限があるみたいだし....

341:デフォルトの名無しさん
10/03/14 11:16:10
/dev/randomとかある環境ならいけるんじゃね?とか思うけど

342:デフォルトの名無しさん
10/03/14 11:16:21
宿題はC/C++宿題スレへ。テンプレート持って。

343:デフォルトの名無しさん
10/03/14 11:17:06
ってnotepad.exeで作成したテキストファイルじゃなくてリアルメモ帳かよ!

344:デフォルトの名無しさん
10/03/14 11:40:26
木綿生地以外は全部ナイロンに分類してしまう某民族みたいな話だな

345:デフォルトの名無しさん
10/03/14 12:26:11
randとかの関数のアドレス調べておいて
それでfopenを上書きすればいいんじゃね
あるいはランダムな数字が入ってるテキストファイル用意しておくとか

346:デフォルトの名無しさん
10/03/14 12:27:13
却下

347:デフォルトの名無しさん
10/03/14 13:00:38
>>338
できるよ

348:デフォルトの名無しさん
10/03/14 13:26:37
fopen、fscanf、for、ifだけじゃ無理だろ。
カッコや演算子もないとプログラムの書きようがない。

349:デフォルトの名無しさん
10/03/14 13:29:57
糞スレ

350:デフォルトの名無しさん
10/03/14 13:30:27
開くだけ開いて閉じないってのはなぁ

351:デフォルトの名無しさん
10/03/14 13:36:40
必要な関数を全部挙げろよカス

352:デフォルトの名無しさん
10/03/14 13:37:04
>>348
なんか小学生みたいだな

353:デフォルトの名無しさん
10/03/14 15:05:35
hoge.hにint num;というグローバル変数を宣言?します

全然関係ない所から、#include "hoge.h"をしてhoge.hのint num;を使うと
numのスコープはどうなるのですか?

354:デフォルトの名無しさん
10/03/14 15:10:57
記憶クラス指定子にextern付けとけ
どっかのコンパイル単位でint numで定義すればいい

355:353
10/03/14 15:36:26
>>354
ひとまず、グローバル変数にはexternをつければいいことは分かりました
でも、いつグローバル変数が死ぬかわかりません

356:デフォルトの名無しさん
10/03/14 15:42:23
グローバルに限らず静的変数はmain()が始まってから終わるまで生きてる。
寿命をスコープと言わない。スコープってのは名前の有効範囲。

357:デフォルトの名無しさん
10/03/14 16:00:40
>>350
fopen()で開いたストリームは、プログラムが終了すると自動で閉じられるんで、
閉じるのは省略しても問題ないって場合もある。

358:353
10/03/14 16:06:29
すみません、まだexternとグローバル変数について分からないので教えてください

staticのまとめ
1.#include "hoge.h"とした時に初期化(定義)される
2.staticは何度も#include "hoge.h"としても、1度しか初期化されない
3.プログラムのすべてが終わると自動的に、削除される
4.オブジェクト指向のpublic?

externのまとめ
1.#include "hoge.h"とした時に初期化(定義)される
2.#include "hoge.h"とする度に初期化されてしまうので、多重定義になってしまう
3.プログラムのすべてが終わると自動的に、削除される

359:デフォルトの名無しさん
10/03/14 16:29:24
>>358
#includeと切り離して説明すると、

file1.cとfile2.cで、それぞれ、static int n = 1; とstatic int n = 2; と宣言されていたら、
この二つのnはそれぞれ別の変数になる。
それぞれ1と2で初期化される。
file1.cで宣言されたnはfile1.cの中からしかアクセスできない。よそからは見えない。
file2.cで宣言されたnはfile2.cの中からしかアクセスできない。よそからは見えない。


file1.cとfile2.cで、それぞれ、int n = 1; とextern int n; と宣言されていたら、
この二つのnは同じ変数になる。
1で初期化される。
file1.cとfile2.cでnを書き換えると、同じ変数だから、とうぜん、file1.cとfile2.cから
みえるnは同じように書き換えられる。



360:353
10/03/14 16:52:37
>>359
わかりました、ありがとうございます
また、疑問に思う事があったら質問します

361:デフォルトの名無しさん
10/03/14 17:56:37
C言語の入門サイトではヘッダの作り方がかかれていませんが、
C言語では普通ヘッダを作らないのでしょうか?

ちなみに、*.cを*.hにするだけじゃダメなんですか

362:デフォルトの名無しさん
10/03/14 18:37:33
if(1)
{~}
else
{~}

elseブロックは最適化で消滅する?

363:デフォルトの名無しさん
10/03/14 18:46:39
>>361
ちょっと規模が大きいとファイルを複数にわけるんで、ヘッダを作るのが普通。
ヘッダには定数とか関数のプロトタイプを入れるもんなので、.cを.hに変えるだけじゃだめ。

364:デフォルトの名無しさん
10/03/14 18:51:50
だめだお。

365:デフォルトの名無しさん
10/03/14 18:52:32
>>362
おまえさんが使っているコンパイラに聞いてみろ

366:デフォルトの名無しさん
10/03/14 19:05:19
>>245
ソース見たら、たぶん20行から28行までのところを、なんかしたら、なんかなるかもなぁ~~って気がしたんで、
そこのところをあてずっぽうでいじったら、456 って出た(^_^/わーい

ソースの、ここのところを
/* 各桁の数字を、有効な桁まで計算しておく */
for(i = 0, trunc = 0; i < 15; ++i) {
m = modf(n, &n);
buf[i] = (int)n;
n = m * 10.0;



こういうふうに変えてみたです。あとはいっしょです
/* 各桁の数字を、有効な桁まで計算しておく */
double def = n; // ここと
for(i = 0, trunc = 0; i < 15; ++i) {
m = modf(n, &n);
buf[i] = (int)n;
n = ( modf( ((def+pow(10.0,-15)) * pow(10.0,i)), &n ) * 10.0 ); // ここ

わかんないけど、「誤差とかが、掛け算で、かける10ってのを何度もしてると、誤差がでるのかなぁ~」とかおもったので、
まいかい全部バ~~って、かける1000とかして一気にやったらどうかな?って思ってやったけどダメだったので、
しょうがないので0.00000......1 て小さい1足して、四捨五入しちゃえ~~ えいや~~ってやったら、なんか偶然456 ってなった。 よかった。

すいません、ぜんぜん知的じゃなくて(・_; 算数的な根拠はないです。なんかラッキー頼りですみません(orz はずぅ~~い


367:デフォルトの名無しさん
10/03/14 19:25:05
>>363
thx

368:デフォルトの名無しさん
10/03/14 20:40:38
C言語のことならなんでも聞いてくれるんですか。

369:デフォルトの名無しさん
10/03/14 20:50:21
難しいのはちょっと・・・

370:デフォルトの名無しさん
10/03/14 20:51:50
さあ願いを言え
どんな願いも一つだけ
聞き流してやろう…

371:デフォルトの名無しさん
10/03/14 22:05:45
いくらでも聞くよ

372:デフォルトの名無しさん
10/03/14 22:40:35
>>366
pow()のアルゴリズムを知っているか? 知っていればすぐに判ることだが非常に誤差が発生しやすい。
従って、第二パラメータが整数になるなら使わない方が無難。
後は、その分の計算量をどこでどう分散させるかだな。

373:デフォルトの名無しさん
10/03/15 01:32:38
いまだにミドルウェアっていうのがよくわからない

374:デフォルトの名無しさん
10/03/15 11:29:44
>>373
ミドルウェアってのはOSとソフトウェアの中間に値する物
ミドルウェア = DBMSって覚えておけばok

375:デフォルトの名無しさん
10/03/15 11:49:53
ヘッダファイルには全ての関数/変数に、extern/staticを付けなければならないんですか?

376:デフォルトの名無しさん
10/03/15 12:44:34
いいえ

377:デフォルトの名無しさん
10/03/15 12:50:48
>>375
そもそも、ヘッダファイルで定義をしてはいけません。

378:デフォルトの名無しさん
10/03/15 15:01:24
中間搾取w

379:デフォルトの名無しさん
10/03/15 15:04:54
元ダフ屋が金券ショップになりやがて中央銀行になったようなもの

380:デフォルトの名無しさん
10/03/15 21:58:35
>>338

#include <stdio.h>
#include <stdlib.h>
void main(int argc, char** argv ) {
char str[0xFF]; double n[1000]; int n_max = 0; int i=0;
FILE* fp = fopen( argv[1], "r"); while( fgets(str,0xFF-1,fp) != NULL ){ n[n_max++]=strtod( str, NULL ); }
srand((unsigned)(time(NULL)));
while( i < 5 ) { int r = rand()%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}

くじびき的な何か?

381:デフォルトの名無しさん
10/03/15 22:02:18

fopen、fscanf、for、ifのみを使って

という条件を満たしていない気がするのだが、いいのか。

382:デフォルトの名無しさん
10/03/15 22:10:58
うむ、randが使えないのが難点だな

383:デフォルトの名無しさん
10/03/15 22:11:06
>>380
fgets()の第二パラメータの意味を誤解していそうだ。

384:デフォルトの名無しさん
10/03/15 22:45:47
せめて現在時刻がわかれば乱数のように使えるのに
制限が厳しすぎる

385:デフォルトの名無しさん
10/03/15 23:27:10
__asm は使ってもいいですか? 関数じゃないからいいよね?

386:デフォルトの名無しさん
10/03/15 23:53:32
乱数の代わりに初期化していない自動変数の中身を読むってのは無し?

387:デフォルトの名無しさん
10/03/16 00:14:56
厳密なことをいうと、十分にランダムである保証がない
特に乱数や、乱数の種、ましてや暗号関係で使うのは厳禁

あと初期化されていない変数って、規格上は読んでいいんだっけ?

388:デフォルトの名無しさん
10/03/16 00:18:33
定義されていないだけで、読むのは別にいいんでない

389:デフォルトの名無しさん
10/03/16 00:39:10
>>381

#include <stdio.h>
#include <stdlib.h>
static double s;
static int rnd(void){ int p; if(s>1e+8){s*=1e-4;}; if(s<0){s*=1e+8;} s += 0.1*s; return((s<0.0)?-s:s); }
void main(int argc, char** argv ) {
char str[0xFF]; double n[1000]; double d; int n_max = 0; int i=0;
FILE* fp = fopen( argv[1], "r"); for( ; fscanf( fp, "%lf", &d ) != EOF ; ){ n[n_max++]=d; }
s=((double)((long)&str)); rnd();
for( i=0; i<5 ; ){ int r = rnd()%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}

な、なんか意味あんのん?… この制限て…(・_; ばたり…

390:デフォルトの名無しさん
10/03/16 00:43:09
もうひとつ制限がありました。7行で書いてください

391:デフォルトの名無しさん
10/03/16 00:47:44
改行しなきゃいいだけ

392:デフォルトの名無しさん
10/03/16 00:53:39
>>390

#include <stdio.h>
static int rnd(double* s){ int p; if(*s>1e+8){*s*=1e-4;}; if(*s<0){*s*=1e+8;} *s += *s*0.1; return((*s<0.0)?-*s:*s); }
void main(int argc, char** argv ) {
double n[1000]; double d; int n_max = 0; int i=0; double s =(double)((long)&n); rnd(&s);
FILE* fp = fopen( argv[1], "r"); for( ; fscanf( fp, "%lf", &d ) != EOF ; ){ n[n_max++]=d; }
for( i=0; i<5 ; ){ int r = rnd(&s)%n_max; if( n[r] != 1e+306 ) { printf( "%f\n", n[r] ); n[r]=1e+306; i++; }}
}

もぅ寝まつ…(つ_\

393:デフォルトの名無しさん
10/03/16 01:08:23
>>338
これでどうだ
ウチでは実行するたびに結果が変わったよ
#include<stdio.h>

#define DATA_NUM 1000

int main(void)
{
unsigned long rand_pool[DATA_NUM], rand_num[5];
int value[10], i, index;
FILE *fp;

if((fp=fopen("hoge.txt", "r"))==NULL) return 1;

for(i=0;i<10;i++) if(fscanf(fp, "%d", &value[i])!=1) return 2;

for(i=0;i<DATA_NUM;i++) rand_num[i%5]^=rand_pool[i];

for(i=0;i<5;i++)
{
index=rand_num[i]%(10-i);
printf("%d\n", value[index]);
value[index]=value[10-1-i];
}

return 0;
}

394:デフォルトの名無しさん
10/03/16 02:27:07
回答が知りたい。
こんな問題を出した意図とか。

どうせ>>338が問題を書き間違えて重要な情報が抜け落ちてたってオチだろうけど。

395:デフォルトの名無しさん
10/03/16 16:26:46
関数で参照渡しするときの所作を詳細に教えてくささい

396:デフォルトの名無しさん
10/03/16 16:30:29
まず、参照渡しの定義をしてから質問してください

397:デフォルトの名無しさん
10/03/16 16:36:06
C言語では参照渡しはできません
JAVAを使いましょう

398:デフォルトの名無しさん
10/03/16 16:37:08
もどきはできるじゃん

399:デフォルトの名無しさん
10/03/16 16:37:44
ポインタによる間接参照

400:デフォルトの名無しさん
10/03/16 22:08:09
>>395
洒落じゃね?

401:デフォルトの名無しさん
10/03/16 22:45:29
sprintfを使って整数から文字列に変換しようとするとき
"%04d",i みたいに前をゼロで埋める指定で、0で埋める個数って変数にできないんですかね?

402:デフォルトの名無しさん
10/03/16 22:49:04
*

403:デフォルトの名無しさん
10/03/16 23:05:00
なるほど、%0*d , (int) , i でいけました
ありがとうございます

404:デフォルトの名無しさん
10/03/17 23:08:23
超初心者ですがよろしくお願いします。
Macでも使えて軽いコンパイラってありますか?

405:デフォルトの名無しさん
10/03/17 23:26:55
gccでいいだろうに

406:デフォルトの名無しさん
10/03/18 06:44:00
軽いコンパイラって、どんなコンパイラだよ。

407:デフォルトの名無しさん
10/03/18 14:35:10
じゃ軽いライブラリで

408:デフォルトの名無しさん
10/03/18 15:30:45
俺の作ったコンパイラすごいぜ。

5年前のノートPCなのに、円周率計算させると2秒で5億桁まで出力する。

VisualStudio2008ってソフトなんだけど。

409:デフォルトの名無しさん
10/03/18 15:42:31
ネタだろうけど、GMPより糞速いじゃん
URLリンク(gmplib.org)

410:デフォルトの名無しさん
10/03/19 00:39:07
gccでプログラム作ってます。
例えば、buff=(char *)malloc(sizeof(char) * 10);とメモリを確保したあと
配列が不足するたびにreallocでメモリを増やしていこうと考えてます。
buff=(char *)realloc(buff, sizeof(char) * 20);という具合に。
そこで悩んだのですが、ある時点でbuffにどれくらいメモリが割り当てられてるか
確認する方法ってないですか?
「* 10」を「* i」みたいに変数を使って確認するしかないんでしょうかね?

411:デフォルトの名無しさん
10/03/19 00:41:37
サイズを保存するしか無いよ

412:デフォルトの名無しさん
10/03/19 00:46:46
>>411
ありがとう。そうします。

413:デフォルトの名無しさん
10/03/19 01:11:33
>>410
> buff=(char *)realloc(buff, sizeof(char) * 20);という具合に。
出たよ。メモリ確保できないときにリークが確定するパターン。
初心者に realloc() 教えるとすぐこれをやらかす。

414:デフォルトの名無しさん
10/03/19 01:16:08
鬼の首でも取ったのか?
喜びすぎだろ

415:デフォルトの名無しさん
10/03/19 01:20:57
喜んでるわけが無いだろjk
うんざりしてるんだよ。

416:デフォルトの名無しさん
10/03/19 02:32:19
#include <stdio.h>
#include <stdlib.h>
// 構造体 B
typedef struct tagB { int max_size; char* buff; } B;

// B を初期化する命令
void B_init( B* b ) { b->max_size=10; b->buff =(char*)malloc(sizeof(char) * b->max_size); }

// B のメモリを10ふやす命令
void B_realloc( B* b ) { b->max_size += 10; b->buff = (char*)realloc( b->buff, sizeof(char) * b->max_size ); }

// Bに char を一文字セーブする命令 ( B の buff が短かったら自動的に伸ばしてくれる )
void B_write( B* b, char c, int index ) { if( index >= b->max_size ){ B_realloc(b); B_write( b, c, index ); } b->buff[index] = c; }

// Bから char を一文字ロードする命令 ( B の buff が短かったら自動的に伸ばしてくれる ) 
char B_read ( B* b, int index ) { if( index >= b->max_size ){ B_realloc( b ); B_read( b,index ); } return( b->buff[index] ); }

void main() { B b; B_init( &b ); B_write( &b, 'A', 12345 ); printf("%c\n", B_read( &b, 12345 ) ); }

おこられそう…w(^_^

417:デフォルトの名無しさん
10/03/19 02:52:10
>>416
怒りはしないが、ダメダメ。
ロードする関数でrealloc()しても、増えた領域に何にも書いてないから不定値が返るぞ。
それに、セーブする方も任意のindexを指定できるのに一度に伸ばせるのが高々10文字だから簡単に範囲外書き込みになってしまう。
それに、sizeof(char)なんて無意味なことは書くべきじゃない。

418:デフォルトの名無しさん
10/03/19 02:55:55
>>413
出たよ。問題の本質と関係ない話をする奴。
buffの宣言がないじゃん、と言ってるのと同レベルだぜそれ。
初心者じゃなくなったと思い込んでる初心者はすぐこれをやらかす。

419:デフォルトの名無しさん
10/03/19 02:56:52
そもそも、メモリ確保ができなくなる心配をする前にすることがあるだろうと。

420:デフォルトの名無しさん
10/03/19 02:57:08
その程度のサイズでrealloc使うとか、何の冗談だよw

421:デフォルトの名無しさん
10/03/19 03:00:21
足りなければ倍にするというやんちゃな方式が時として功を奏することもあるよ
とりあえず、ポインタを元にアロケーションしているサイズを知ることはできないので他で管理しましょう

>>420
ええと。

422:デフォルトの名無しさん
10/03/19 09:12:57
どうしても必要ならともかく、入門レベルでrealloc使わせるのはどうかと思うが。
余裕をもとって大きめに領域確保するほうがよっぽどマシ。

423:デフォルトの名無しさん
10/03/19 09:15:29
>>413
すぐそのあとに、if (buff == NULL) exit(1); と書けば問題なし。
メモリ不足なら、ほかのところだってまともに動くわけないんだから。

424:デフォルトの名無しさん
10/03/19 09:32:48
>>422
それはそれでイヤン

425:デフォルトの名無しさん
10/03/19 11:07:20
>>424
サイズをオーバーするかどうかちゃんとチェックするならありじゃね?

426:デフォルトの名無しさん
10/03/19 14:55:30
>>425
オーバーしそうになったらどうすんの?

427:デフォルトの名無しさん
10/03/19 15:50:24
>>426
・ごめんなさい、私には無理です
・オーバーする分はなかったことにしていいよね

どちらでもお好きに。

428:デフォルトの名無しさん
10/03/19 16:08:53
一行が長いテキストファイルを開くと落ちるエディタ
一行が長いと後ろのほうが切り捨てられるエディタ

どっちもいやだなぁ

429:デフォルトの名無しさん
10/03/19 16:10:43
4G以上のファイルとかどうやって扱ってんのか気になる

430:デフォルトの名無しさん
10/03/19 16:27:26
>>429
4GB以上のファイルを普通に扱える環境なら、64ビットアドレッシングで使うのが当たり前だから特に工夫は要らないよ。
32ビット環境で扱いたいなら、一度に全部開かなければいいだけだからやはり、4GB以上だからといって別段大仰な手間は要らない。

>>428
初心者が作るのなら、取り敢えずそれでもいいのでは? まさか、そのまま保存するわけでもあるまいし。

431:デフォルトの名無しさん
10/03/19 19:50:57
文字配列についてお尋ねします

char buf[6] = {'A', 'B', 'C', 'D', 'E', '\0'};
と宣言したとします。

このとき
buf[1]は 'B'が格納されており文字コードが例えば66だとします
buf[1]は数値そのものであるので、if(buf[1] == 66)もしくはif(buf[1] == 'B')のような比較が可能です。(ですよね?)
ここでbufとするとABCDEという文字列を表すことになりますが、このときbuf自体の数値は
bufのアドレスが入っています。(ですよね?)

ここで疑問なのですが、bufは一体どこのアドレスが入っているのでしょうか?
例えば、buf[0]のアドレスと同じものであればAとしか表示されないはずです。
ABCDE\0をもってくるにはbuf[0]からbuf[5]までのアドレスが必要なはずです。

buf自体はアドレスの開始地点で終端文字の\0が現れる部分までのオフセットを割りだし
そのアドレスをすべて与えて文字列を表示しているということでよろしいでしょうか?
回答よろしくお願いします。

432:デフォルトの名無しさん
10/03/19 20:01:01
>>431
buf と等価なのは &buf[0]

433:デフォルトの名無しさん
10/03/19 20:04:08
>>431
だいたい合ってるが、1点だけ。

> ここでbufとするとABCDEという文字列を表すことになりますが、
bufがABCDEという文字列を表しているわけではない。
あくまで文字列の先頭のアドレスを保持しているにすぎない。
buf == &(buf[0])

puts(buf)で"ABCDE"と表示されるのは、以下のような処理をしているため。
for(char *p = buf; *p != '\0'; p++) { *pを出力; }

434:デフォルトの名無しさん
10/03/19 20:07:07
>>431
配列は配列であってポインタじゃない

435:デフォルトの名無しさん
10/03/19 20:10:42
char buf[] = {'h', 'o', 'g', 'e', '\0'}
char *p = buf;

buf

'h' 'o' 'g' 'e' '\0'

0x00..... ← p

436:デフォルトの名無しさん
10/03/19 20:13:39
グダグダ言ってないでデバッガで変数見りゃいっぱつだろうが

437:デフォルトの名無しさん
10/03/19 20:14:09
>>431
>ここでbufとするとABCDEという文字列を表すことになりますが
ここでってどこだよw

438:デフォルトの名無しさん
10/03/19 20:26:53
>431
言っていることはその通り何だけど
NUL('\0')終端文字列はNULが現れるまでを文字列とみなすから表示させたい最初の文字のアドレスを渡すだけでいいのよ
あなたにお薦めなサンプルプログラム

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

int
my_print(char const*str)
{
  size_t i;
  for ( i = 1; i < str[0]+1; ++i ) {
    putchar(str[i]);
  }
  return i-2;
}
int
main(int argc, char **argv)
{
  char foo[6] = {'a', 'b', 'c', 'd', 'e', '\0'};
  char bar[16] = {'a', 'b', 'c', 'd', 'e'};
  char baz[] = {3, 'b', 'a', 'z'};
  memset(bar+5, '\100', 10); /* ゴミを入れる */
  bar[15] = '\0'; /* NUL終端させる */
  printf("%s\n", foo);
  printf("%s\n", &foo[0]);
  printf("%s\n", &foo[3]);
  printf("%s\n", bar);
  my_print(baz);
  return 0;
}

439:デフォルトの名無しさん
10/03/19 21:22:55
配列はメモリ上連続しているので、先頭アドレスと型がわかれば計算で出ます。
コンパイラは &buf[5] を &buf[0] + (5 * sizeof(char)) と捉えます。

440:デフォルトの名無しさん
10/03/19 21:33:35
プログラミングに使う単語って英語ですか?

441:デフォルトの名無しさん
10/03/19 21:37:20
基本的には

442:デフォルトの名無しさん
10/03/19 21:43:31
皆さんは英語ペラペラですか?

443:デフォルトの名無しさん
10/03/19 21:44:01
My English is poor.

444:デフォルトの名無しさん
10/03/19 22:17:57
>>442
fuck u

445:431
10/03/19 22:18:43
>>433
buf自体がが先頭アドレスなのは↓に書いたように知ってます
>buf自体はアドレスの開始地点
結局全部
for(char *p = buf; *p != '\0'; p++) { *pを出力; }
これやってるだけなんですね…

446:431
10/03/19 22:24:21
>>439

buf[5]を例えばprintfするときはオフセットで
文字列を全部表示するときはポインタをズラす方法で表示しているのですか?

for(char *p = buf; *p != '\0'; p++) { *pを出力; }
このようにポインタをズラしているのか、
それとも
&buf[5] を &buf[0] + (5 * sizeof(char))
のようにオフセットで計算しているのか
内部の処理はどっちなんでしょうか?

それが>>431の質問で一番知りたいことなんですが


447:431
10/03/19 22:26:02
>>436
オフセットで計算したものか、ポインタをズラしたものなのか
格納されたアドレス見るだけじゃわからないんですよ…

448:デフォルトの名無しさん
10/03/19 22:26:32
どういう風にprintfを作るかなんて決まってないしコンパイラメーカーが勝手にやってるだけだよ
きっと、前者だろうなって気はするけど

449:デフォルトの名無しさん
10/03/19 22:27:39
前者な気がする

450:431
10/03/19 22:28:24
>>448
そうなんですか…
どっちが主流なのか知りたかったのですが(速度とかいろんな意味で)

451:デフォルトの名無しさん
10/03/19 22:30:39
そんなこと知ってどうすんだろ

452:デフォルトの名無しさん
10/03/19 22:31:24
速度とかそれこそきまってねえだろ
おまえはなにか?コンパイラは全て同じ中身じゃないといけないと思ってんのか?主流ってなんだ?どの環境の主流だ?
クソして寝ろや

453:デフォルトの名無しさん
10/03/19 22:33:28
>>450
もう答えは出てるだろう。文字列探索程度のコストを気にするより
もっと他の所の速度を気にしろ。

454:デフォルトの名無しさん
10/03/19 22:35:29
簡単なプログラムつくって、最適化全部はずしてバイナリを逆アセンブルして追っかけてみれば?
ペンティアム以降になると急に難しくなるから、LSICの試食版あたりからははじめて
あるいはgccならprintfもソースみれるよ

そうやって3,4個調べてみれば主流もわかるんじゃね

455:デフォルトの名無しさん
10/03/19 23:38:50
robot C わかる人いる?

456:デフォルトの名無しさん
10/03/19 23:41:38
ボクは個人的には
char c[1234]
ってのを

putchar( c[0] ); putchar( c[1] ); putchar( c[2] ); putchar( c[3] ); putchar( c[4] ); putchar( c[5] ); ~~~ずーっとつづく
って書くよりも

char* p=c;
putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ ); putchar( *p++ );  ~~~ずーっとつづく
って書く方が、コピペが楽なので好きですw


457:デフォルトの名無しさん
10/03/19 23:43:53


458:デフォルトの名無しさん
10/03/19 23:44:02
頭おかしいのかおまえ

459:デフォルトの名無しさん
10/03/19 23:52:53
俺がコンパイラなら syntax error 出すわな

460:デフォルトの名無しさん
10/03/19 23:53:21
最終的にはsystem callを追っかけてlibcやkernelに入りそうだな

461:デフォルトの名無しさん
10/03/19 23:59:13
int 21Hで終わりでいいじゃん

462:デフォルトの名無しさん
10/03/20 00:06:12
char c[1234];
ってのは、使うときは putchar( c[3] ) みたいにして使います。 c[0] なら最初の文字、c[3]なら3番目の文字です。  

&c[3]  みたいに、頭に&マークをつけると、このデータがメモリのどこに書かれてるかがわかります。配列の先頭が、メモリのどこにあるかは &c[0] でわかります。

使うときにカッコを取って c って書くと、 &c[0] って書いたときと同じ数字がわかります。 この c そのものを c++ ってやって一個増やすと、
char型の配列なら、char一個分だけメモリをさしてる場所が増えます。 だから c++ とすると、つぎに使うときは c は &c[1] といういみになります。

int型の配列なら、int i[1234];

463:デフォルトの名無しさん
10/03/20 00:08:19
i++ で int の大きさ分だけ増えます。 

や~めた

464:デフォルトの名無しさん
10/03/20 00:14:26
>462
またまたご冗談を

465:デフォルトの名無しさん
10/03/20 00:19:03
>>462
そんなコンパイラなんて…
あるかもしれないが規格無視じゃないか

466:デフォルトの名無しさん
10/03/20 00:27:03
>>462
その場合cは定数だからc++なんて出来ないだろアホ


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch