トップページ⇒tech
1001コメント331KB

【初心者歓迎】C/C++室 Ver.70【環境依存OK】

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2009/11/22(日) 16:04:30
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

【前スレ】
【初心者歓迎】C/C++室 Ver.69【環境依存OK】
http://pc12.2ch.net/test/read.cgi/tech/1256022655/

【アップローダー】(質問が長い時はココ使うと便利)
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm
http://codepad.org/ (コンパイルもできるし出力結果も得られるのでお勧め)

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か に置換すると見栄えだけはよくなります。
0153デフォルトの名無しさん2009/12/07(月) 20:48:58
>>152
ありがとうございます。大変参考になりました。
0154デフォルトの名無しさん2009/12/08(火) 16:54:58
>>150
デバッグ用のmsvcrtは配布されてないから、デバッグビルドは開発環境のないところで動かないよ
0155デフォルトの名無しさん2009/12/08(火) 21:05:24
学校で「gcc ○○.c -o □□.exe」と入力してコンパイルする方法を教わったのですが、
家のパソコンで同じようにやってみてもエラーが出て出来ません。
「'gcc'は内部コマンドまたは外部コマンド、
 操作可能なプログラムまたはバッチ ファイルとして認識されていません。」
↑こういうメッセージが出ます。どうすればよいでしょうか?
OSはどちらもVistaです。
0156デフォルトの名無しさん2009/12/08(火) 21:11:58
そりゃgccがインストールされてないんだろうよ。
0157デフォルトの名無しさん2009/12/08(火) 21:12:11
残念!あなたのPCにはGCCがインストールされていない!
0158デフォルトの名無しさん2009/12/08(火) 21:47:27
Windowsでgccを使いたかったらcygwinかmingwをインストールして下さい
0159デフォルトの名無しさん2009/12/08(火) 21:51:16
SFU にしろよ。
0160デフォルトの名無しさん2009/12/08(火) 22:09:24
BCC5.5は?
0161デフォルトの名無しさん2009/12/08(火) 23:10:28
>>160
ADLとテンプレート周りが腐ってるからだめだ
0162デフォルトの名無しさん2009/12/08(火) 23:30:17
TCC1.01 は?
0163デフォルトの名無しさん2009/12/08(火) 23:43:01
テンプレートがない(確か)
例外処理もないんじゃなかったか?
それに16bit専用だったと思うが
0164デフォルトの名無しさん2009/12/09(水) 00:07:42
じゃあ LCC-Win32 は?
0165デフォルトの名無しさん2009/12/09(水) 00:19:24
>>154
詳しい説明ありがとうございます
0166デフォルトの名無しさん2009/12/09(水) 12:49:50
>>163
つまり組み込み向け?
0167デフォルトの名無しさん2009/12/09(水) 15:59:32
DOS時代のコンパイラってだけ
0168デフォルトの名無しさん2009/12/10(木) 00:38:58
javaの場合staticなメソッドはインスタンスから独立しているため、一般的な作業に使われています
C++のstaticなメソッドもjavaと同じような感覚でいいのでしょうか?
0169デフォルトの名無しさん2009/12/10(木) 00:41:51
イエス。そのクラスの名前空間に入っているだけの関数と考えてもらって差し支えないです。
0170デフォルトの名無しさん2009/12/10(木) 01:21:11
まあでも本当に一般的な作業なら、クラスのメンバにしないけどな。
0171デフォルトの名無しさん2009/12/10(木) 01:32:06
>>170
staticしか持ってない管理クラスで一般的な作業させてるんだけど、おかしいか?
0172デフォルトの名無しさん2009/12/10(木) 01:34:15
JavaやC#では単なるメソッド集みたいなクラスがどうしてもできるけど、C++ではそういう
関数はグローバル関数にするのが一般的。
グローバル関数で実現可能なことは、わざわざメンバ関数にしない方が安全だ。
0173デフォルトの名無しさん2009/12/10(木) 01:37:23
>グローバル関数で実現可能なことは、わざわざメンバ関数にしない方が安全だ。
安全っていうと、どう違うん?
実質グローバルと変わらないと認識してたんだけど・・・。
0174デフォルトの名無しさん2009/12/10(木) 01:52:42
EffectiveC++の受け売りなんだが、グローバル関数のほうが強くprivateメンバを隠蔽出来る。
privateなデータメンバにアクセスできるものは極力減らした方が、安全性や保守性が高まる。
friendでないグローバル関数ならprivateメンバにアクセスできないことは自明なので、
privateメンバに手を加えるとき、考慮しなくてすむよね。
0175デフォルトの名無しさん2009/12/10(木) 02:02:06
単なる関数集クラスがあってもいいとは思うけど、それにメンバ変数を追加しだしたら赤信号。
0176デフォルトの名無しさん2009/12/10(木) 02:46:11
メンバ関数が静的なのか非静的なのか
はっきりしてほしいところ

Monostateパターンなのかどうなのかも
はっきりしてほしいところ

そこらへんが曖昧だから話が噛み合わない
0177デフォルトの名無しさん2009/12/10(木) 05:38:21
>>171
それは通常namespaceを使うんじゃないだろうか
0178デフォルトの名無しさん2009/12/11(金) 00:40:28
関数を実装するのに使うけど外に晒したくない関数が欲しいときはクラス化してstaticメンバにするかな
class make
{
public:
template<class xxx> static std::tr1::shared_ptr<xxx> shared(void)
{
return std::tr1::shared_ptr<xxx>(create<xxx>(), destroy<xxx>);
}
private:
template<class xxx> static xxx *create (void)
{
std::cout << "create" << std::endl;
return new xxx;
}
template<class xxx> static void destroy (xxx *ptr)
{
std::cout << "destroy" << std::endl;
delete ptr;
}
};
いい例がぱっと思いつかんけどこんなのとか
あとはてんぷらプログラミングとかやろうとすると、グローバルじゃなくてクラスメンバのほうが使い易い
既存のクラスにstaticを継ぎ足し継ぎ足しするのは危険だけどそうじゃなきゃグローバルよりできることは多いと思う
0179デフォルトの名無しさん2009/12/11(金) 22:56:05
みなさんは、演算子のオーバーロードについてどう思いますか?
0180デフォルトの名無しさん2009/12/11(金) 23:06:03
>>179
あって助かってる。
が、意味不明なオーバーロードされてると殺意を抱く。
0181デフォルトの名無しさん2009/12/11(金) 23:24:37
>>179
俺も>>180と同じ感想。
数をあつかうクラス書くときは凄い便利。
0182デフォルトの名無しさん2009/12/12(土) 03:03:38
ベクトル計算とかマトリクス計算とか便利すぎて死ねる
0183デフォルトの名無しさん2009/12/12(土) 05:19:40
reinterpret_cast< unsigned int >("hoge")

これの結果は環境によって変わったりしますか?
0184デフォルトの名無しさん2009/12/12(土) 05:25:03
する
0185デフォルトの名無しさん2009/12/12(土) 05:25:51
>>183
実行するごとに変わったり変わらなかったり。
0186デフォルトの名無しさん2009/12/12(土) 07:01:00
つーか、いわゆるユーザー定義型的なクラスを作る時には、演算子オーバーロードは
必須だよな
スマポやイテレータなんか、演算子オーバーロード無かったら糞以下だろう

そういう振る舞いを求められてないクラスで面白がって使う演算子オーバーロードは
ほとんどが害悪だけど
0187デフォルトの名無しさん2009/12/12(土) 07:05:50
STLのアルゴリズムを適用しやすいように比較演算子を定義したりとか。
0188デフォルトの名無しさん2009/12/12(土) 13:35:30
組み込み型を擬態するためにとかならいいけど、演算子は必要最低限にしとかないと意味が分かりづらい糞コードになる
0189デフォルトの名無しさん2009/12/12(土) 13:52:02
演算子を本来の意味とは全く違う用途、
例えば << や >> を streamとの入出力に使うとかって、最低だよな。

いやマジで。
0190デフォルトの名無しさん2009/12/12(土) 15:51:52
だがboost::formatは正直便利だ
0191デフォルトの名無しさん2009/12/12(土) 16:34:13
>>189 はきっと Boost.Xpressive で頭痛がして
Boost.Spirit で発狂した経験がある。
0192デフォルトの名無しさん2009/12/12(土) 16:53:15
シーケンシャルな演算子で丁度いいのがそれしか選択肢が無い
0193デフォルトの名無しさん2009/12/12(土) 16:55:12
>>183
それは要するに "hoge" という文字列の置かれたアドレスの一部あるいは全部を
unsigned int として返す、という式になるけど、処理系によってメモリの使い方が
ことなるから、当然定数のアドレスも異なる。
コードを書き換えてコンパイルし直せば、定数の配置も変わりうるからアドレスも変わりうる。

また、Windows や Linux では(バージョンやディストリビューションや設定によって変わるが)
ヒープやスタックの位置をランダムに変えているので、プロセスの起動ごとに変数や定数の
アドレスが変わるが、Mac OS X はそういうことはしていないので起動ごとにアドレスが
変わったりはしない。
0194デフォルトの名無しさん2009/12/12(土) 20:55:27
typedef struct _TAG_ELEMENT {
struct _TAG_ELEMENT *next;
char str[ 256 ];
} ELEMENT;

上の構造体を使って、線形リスト?を作りました。
で、strcmp()の仕様にのっとり、昇順にソートをしようとしたのですが、うまくいきません。
いったいどうしたらいいのでしょうか?
0195デフォルトの名無しさん2009/12/12(土) 21:05:23
>>194
どんなコードを書いて、どう上手くいかなかったの?
0196デフォルトの名無しさん2009/12/12(土) 21:11:09
>>194 とりあえず予約識別子ヤメロ
0197デフォルトの名無しさん2009/12/13(日) 00:11:57
CALLBACKって何のためにつけてるんですか?
関数ポインタに渡すときはつけないとダメなんでしょうか?
0198デフォルトの名無しさん2009/12/13(日) 00:26:28
何のため・・・難しいことを訊く
MS様がここはCALLBACKだとお決めになられた箇所には、CALLBACKを付ける
MS様がルールで、俺たち平民はそれに従うのみよ
関数ポインタならなんでも付けるわけじゃなくて、CALLBACK規約の関数ポインタの場合だけ付ける
まぁ呼び出し規約でぐぐってくれ
0199デフォルトの名無しさん2009/12/13(日) 00:30:59
>>197
それは呼出規約というものを指定しているんだ。
呼出規約というのは、関数の呼び出し方と値の戻し方を機械語レベルで規定したもので、
それが異なるとCのソースレベルでは同じに見える関数でも機械語レベルでは別物に
なってしまい、呼び出すことが出来なくなる。
0200デフォルトの名無しさん2009/12/13(日) 00:31:03
LinuxやMaxのアプリだとCALLBACKみたいなのは無いの?
0201デフォルトの名無しさん2009/12/13(日) 00:31:42
>>197
関数の呼び方にstdcallとpascalって二つあって、CALLBACKはその
どちらかに設定されてるんじゃないの?
0202デフォルトの名無しさん2009/12/13(日) 00:34:44
>>200
あるよ。というか、もともと呼出規約なんてものは処理系ごとに異なっているものだ。
さすがにそれじゃあ開発に支障をきたすので、ある程度規格化されているけど。
0203デフォルトの名無しさん2009/12/13(日) 00:36:52
>>200
もちろん呼び出し規約を指定することは出来るけど、わざわざ指定するような例は見たことないな・・
0204デフォルトの名無しさん2009/12/13(日) 08:42:15
>>197
誰も書かないので書いとくが、引数をスタックに積む順番が変わる。
関数呼び出しのエンディアンみたいなもんだね。
0205デフォルトの名無しさん2009/12/13(日) 08:55:14
いや、レジスタだけで渡したりとか色々ある
VCのnaked規約なんかに至っては、スタックフレームの生成もret命令もてめーで書け、
という潔さ
0206デフォルトの名無しさん2009/12/13(日) 13:05:33
nakedは割り込みハンドラをCのインラインアセンブリで書くときに使うかなぁ
gccだと__attribute__((naked))
0207デフォルトの名無しさん2009/12/13(日) 13:43:10
あぁ〜、objectみたな神様クラスがあれば楽なのに
0208デフォルトの名無しさん2009/12/16(水) 22:56:57
C++じゃなくてCなんですが、
可変の3次元配列を利用したい場合はどうしたらよいですか。

たとえば、int arrray[x_max][y_max][z_max]の3次元配列を使いたい場合、
1.十分大きな配列を確保して、array[i][j][k]とアクセス
2.array = malloc(sizeof(int) * x_max * y_max * z_max)とし、
  array[ (i*y_max + j)*z_max + k] でアクセスする。
の方法を考えたんですが、他に良い手法はありますでしょうか。
0209デフォルトの名無しさん2009/12/16(水) 23:09:16
int ***a;
としてループでmallocしまくる
遅いからおすすめはしないが
0210デフォルトの名無しさん2009/12/17(木) 00:09:50
(゚Д゚≡゚Д゚)
0211デフォルトの名無しさん2009/12/17(木) 00:27:33
>>208
可変ってどゆこと?
0212デフォルトの名無しさん2009/12/17(木) 00:39:04
>>208
標準Cなら俺の知る限りその2つの方法しかない。
しかし、1は容易にスタックオーバーフローを引き起こすのでお勧めできない。
int a[10][10][10]くらいですむならいいけどね。
02132122009/12/17(木) 00:43:56
すまん、そういえばalloca()もあるね。
でも1と同じでスタックオーバーフローに繋がるから、お勧めはできない。
0214デフォルトの名無しさん2009/12/17(木) 00:44:17
>208

3.int (*p)[Y][Z] = malloc(sizeof(int) * x_max * y_max * z_max)
とすればp[0][1][2]でアクセスできるよ。

ただしY, Zは固定。

Y,Zも可変にしたければ>209の方法しかない。
02152082009/12/17(木) 14:23:43
>>211
すみません、説明不足でしたね。
例えば、プログラム中で設定ファイルを読み込んだり、
途中で入力した数をx_max,y_max,z_maxに代入して、
arrray[x_max][y_max][z_max] を使いたいと言う事です。

>>209-214
結局は、可変な3数を使う配列を使いたい場合、
2.が良いと言う事ですね。
そうやって作ってみようと思います。
皆さんどうもありがとうございました。
0216デフォルトの名無しさん2009/12/17(木) 17:12:13
すみません初心者です。
1,・・・,100の整数から10個の整数を
非復元抽出でランダムで取り出すプログラムを教えてください。
0217デフォルトの名無しさん2009/12/17(木) 17:18:32
1~100の数字入れた配列つくってランダムに並び替えして前から10個取り出すとかわ?まぁ俺も初心者だからわからんけど
0218デフォルトの名無しさん2009/12/17(木) 17:20:02
初心者歓迎のスレだが初心者が回答をしていいとは言っていない
0219デフォルトの名無しさん2009/12/17(木) 17:41:06
文系の大学生で一般教養科目のC言語を履修しています。
途中の課題のソースファイルを自宅に持ち帰ったのですが、
学内のLinuxで見た時には一つだったのにWinでひらくと「Cファイル」と「C〜ファイル」の二つになっていました。
ワードパットで編集できるみたいですが、この場合両方に同じ編集を施して、
両方をファイルサーバーにコピーすると1つのファイルに戻ったりするのでしょうか?

いきなりファイルが増えて混乱してます。
よろしくお願いします。
0220デフォルトの名無しさん2009/12/17(木) 17:48:19
>>219
~がついているほうはエディタのバックアップファイルだと思う。
おそらくそっちは削除して、.cファイルだけ編集して書き戻せば平気。
0221デフォルトの名無しさん2009/12/17(木) 18:02:54
>>220
ホント助かりました!
ありがとうございます!
0222デフォルトの名無しさん2009/12/17(木) 20:25:13
課題系が増える季節か
0223デフォルトの名無しさん2009/12/17(木) 22:00:32
Test *t;
Test *t = new Test();
この2つは何が違うんですか?どっちも、自動で破棄されない点は同じですが
Test *t;はdelete t;をしても、デストラクタを実行してくれない
0224デフォルトの名無しさん2009/12/17(木) 22:12:03
>>223
前者はTest型へのポインタ、つまり「Test型のインスタンスのアドレス値の置き場」を
作っただけで、Test型のインスタンスを作っていません。
従って、デストラクタも実行されません。生まれていない生物が死ぬことはできないので。
02252232009/12/17(木) 22:13:57
>>224
なるほど、ありがとうございます。
Test *t();は単純に「Test t(); + ポインタ」だと思っていました
0226デフォルトの名無しさん2009/12/17(木) 22:24:10
いや
Test *t();
は、
「Test *を返すtという名前の関数の宣言」であって
Test *t;
とは全く別物だし。
0227デフォルトの名無しさん2009/12/18(金) 00:47:54
>>216
int a[100], i, j;
for (i = 0; i < 100; i[a] = i + 1, i++);
for (i = 0; i < 100; i++)
{
    j = (int)((rand() / (RAND_MAX + 1.0)) * 100);
    j[a] != -1 ? printf("%d\n", j[a]), j[a] = -1 : i--;
}
0228デフォルトの名無しさん2009/12/18(金) 01:33:52
なんという嘘だ
0229デフォルトの名無しさん2009/12/18(金) 01:44:16
>>216
int main()
{
  static int const range = 100;
  static int const num_samples = 10;
  int source[range];
  for (int i = 0; i < range; ++i) { source[i] = 1 + i; }
  srand(time(0));
  assert(num_samples <= range);
  for (int done = 0; done < num_samples; ++done)
  {
    int const num_remains = range - done;
    int const x = (int)((rand() / (RAND_MAX + 1.0)) * num_remains);
    printf("%d\n", source[x]);
    source[x] = source[num_remains - 1];
  }
  return 0;
}
0230デフォルトの名無しさん2009/12/18(金) 05:11:58
Visual C++つかってるんだけど
include <stdio.h>が普通に通るけど
stdio.hってファイルだよね?なんでこれでコンパイルが通る?
C:\Windows\System.なんとか.h
みたいに直接書かなくても良いのはなぜ?あとstdio.hの本体はどこにある?
0231デフォルトの名無しさん2009/12/18(金) 05:22:29
環境変数 INCLUDE でパスが指定されてるから。

#include <c:\\vc\\include\\stdio.h>
#include </vc/include/stdio.h>

のように絶対パスで指定することもできる。

ちなみに、

#include "stdio.h"

"" で囲むと先にカレントディレクトリから探してくれる。
で、無ければ INCLUDE で指定したパスから。
0232デフォルトの名無しさん2009/12/18(金) 05:22:55
>>230
ツール→オプション→プロジェクトおよびソリューション→V++ディレクトリ
0233デフォルトの名無しさん2009/12/18(金) 05:24:26
あ、Cが抜けた。最後は「VC++ディレクトリ」ね。
ここでインクルードファイルやらライブラリやらのパス設定を管理できる。
0234デフォルトの名無しさん2009/12/18(金) 06:04:10
環境変数だね。
0235デフォルトの名無しさん2009/12/18(金) 09:02:17
答えられないなら書き込まなくていいですよ^^
0236デフォルトの名無しさん2009/12/18(金) 18:39:51
C++です。初心者です。new がよくわかりません。

MyClass a;
MyClass b = MyClass;
MyClass c = MyClass();

上記それぞれ動きます。

MyClass d = new MyClass;

これはエラーがでます。なぜでしょうか。
0237デフォルトの名無しさん2009/12/18(金) 18:47:42
>>236
MyClass* d=new 略
0238デフォルトの名無しさん2009/12/18(金) 18:48:19
newはアドレス返すから
入門書読み直したほうがいい
0239デフォルトの名無しさん2009/12/18(金) 18:48:50
MyClass *d = new MyClass;
0240デフォルトの名無しさん2009/12/18(金) 19:06:16
>>236
のb,cはどう動作するの?
0241デフォルトの名無しさん2009/12/18(金) 19:13:57
コンストラクタが実行される
02422362009/12/18(金) 19:44:28
ありがとうございました。

>>238
とてもわかりやすい説明ありがとうございます。
>>239がいけるのは知っていたのでとても納得しました。

>>240
>>236の上3つは同じ処理です。省略したものです。
僕は new はもしかしたら省略可能で省略されているのかと思って質問したわけです。
0243デフォルトの名無しさん2009/12/18(金) 22:44:50
>>236
b はコンパイルエラーになるだろ。
ほんとに動くんなら、コンパイラどれ使ってるか教えて。
0244デフォルトの名無しさん2009/12/18(金) 23:54:59
MyClassがstaticとか
0245デフォルトの名無しさん2009/12/19(土) 00:03:20
>>244 はぁ?クラスが static ?
0246デフォルトの名無しさん2009/12/19(土) 16:11:06
>>236
Java だとそんな感じだよな。
02472362009/12/19(土) 17:40:58
>>243

コンパイルエラーになりました。すいませんでした。
0248デフォルトの名無しさん2009/12/21(月) 02:54:41
>>245
static class使わないの?
0249デフォルトの名無しさん2009/12/21(月) 10:49:11
>>248
Java はスレ違いです。
0250デフォルトの名無しさん2009/12/21(月) 12:46:47
>>249
すまん、C#スレ行ってくる
0251デフォルトの名無しさん2009/12/21(月) 13:28:22
そっちか
0252デフォルトの名無しさん2009/12/21(月) 13:36:37
 = 0 を見つめているとこれが形而上学的なものに思えてきて、
 = 0 を見つめ続けるとやがてゲシュタルト崩壊が始まる。
■ このスレッドは過去ログ倉庫に格納されています