[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 1001- 2chのread.cgiへ]
Update time : 05/24 21:17 / Filesize : 258 KB / Number-of Response : 1002
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:デフォルトの名無しさん [2007/06/03(日) 22:33:55 ]
エスケープシーケンスやWin32APIなどの環境依存な物でもOK。
ただしその場合、質問者は必ず、環境を書きましょう。
※sage禁止です。
【前スレ】
【初心者歓迎】C/C++室 Ver.37【環境依存OK】
pc11.2ch.net/test/read.cgi/tech/1178432985/l50
【アップローダー】(質問が長い時はココ使うと便利)
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.htm


672 名前:デフォルトの名無しさん [2007/06/18(月) 00:47:53 ]
質問
void hoge()
{
何かの処理
#ifdef DEBUG
  printf("Debug %s, nanka);
#endif
何かの処理
#ifdef DEBUG
  printf("Debug %s, nanka);
#endif
↑こんな調子で数百行位ある
}
こういう汚い関数を直したいんだが

void DebugPrint(char *str)
{
#ifdef DEBUG
  printf("Debug %s, str);
#endif
}
void hoge()
{
何かの処理
  DebugPrint(nanka);
何かの処理
  DebugPrint(nanka);
}
って感じに直したいんだが、やったら動作変わっちゃう?
#ifdefあんま使ったこと無いから教えてくださいな

673 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 00:48:22 ]
そりゃそうだろ

674 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 00:49:09 ]
>>673
すんません
分かり易く解説お願いします

675 名前:673 mailto:sage [2007/06/18(月) 00:49:19 ]
>>671
の事ね

VC6が出来たのはだいぶ前だから

676 名前:672 mailto:sage [2007/06/18(月) 00:50:28 ]
>>675
あ、すんません
タイミング良かったんで即レス来たのかと思っちゃいましたw

677 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 00:57:26 ]
#ifdef DEBUG
  #define DEBUG_PRINT(a) printf("Debug %s, (a))
#else
  #define DEBUG_PRINT(a)
#endif


void hoge()
{
何かの処理
  DEBUG_PRINT(nanka);
何かの処理
  DEBUG_PRINT(nanka);
}

こういうのはよくやるな。
ただ、printfは引数の数が可変だから、引数の数にばらつきがあるとまた別の対策が必要になるが。

678 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:04:08 ]
>>677
おぉ、なるほど

後、確認なんですけど、自分が書いた>>672だと動作変わっちゃうんですよね?

勉強として実際のソース見て動きを理解しろ
とか言われてるんですが、こんなソースばっかで
見づらくてしょうがないんで
何とかしたくて・・・
コメントアウトと/*2007/6/19追加バージョン6.2*/等と#ifdef何チャラの嵐です・・・Orz

679 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:05:32 ]
別に動きは変わらんと思うが

680 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:11:32 ]
>>679
あ、そうなんですか?
ありがとうございます

個人的にはDebugPrintの部分は他から呼びたいので
関数化したいな〜と思ってたんですけど、
#ifdefとかはコンパイル時に読み込まれるとか有ったので
動作変わっちゃうのかと・・・糞初心者ですんません
(もう、たまにソース直せと言われるとおっかなビックリっす・・・)




681 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:12:16 ]
失礼、
×他から
○他からも


682 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:13:48 ]
動きは変わらないが、
後者は関数呼び出しのオーバーヘッドが発生する。


683 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:20:02 ]
関数本体の中にやたらと#ifdefなんかが入ってるのは、
あんまりいいコードとはいえないな。
「見づらくてしょうがない」というその感覚は限りなく正しい。
改善する方法をいろいろ考えるべきだな。


684 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:25:43 ]
>>682
すいません

そのオーバーヘッドって遅くなるって事ですよね?
どの程度遅くなりますか?

>>683
ありがとうございます
パワハラ上司なんで聞くに聞けなくて
ここでたまに質問してます
見やすくしろって教えてくれたのもこのスレです


685 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:39:54 ]
関数を呼び出すという処理は、それ自体スタック操作や
プログラムカウンタの移動などの処理が行われる。
だから、>>672 のように関数を呼ぶ形にすると、その分オーバーヘッドが発生する。
一方で>>677の方法だと、不要なときには関数呼び出し自体がなくなるので、
そういう心配がない。この方法が好んで使われる所以。

ただ実際は、よほどタイミングがシビアだったり、デバッグプリントがめちゃくちゃ多かった
りしなければたいしたオーバーヘッドではないので問題にはならない。

でも、リリースバージョンのプログラムの中に、不要な関数呼び出しが残るのって
美しくないとは思わないかい?


686 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:47:04 ]
>>685
なるほど、詳しい解説ありがとうございます

せっかく用意したDebugPrintなのに
リリース等の時は実際は使わないのに
その度にDebugPrintの文だけより道、遠回りしちゃうって事ですね
確かに綺麗じゃないですね

687 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 01:56:30 ]
可変長引数マクロを使えるコンパイラならこんなこともできる
#if DEBUG
#define DebugPrint(...) fprintf(stderr, "\nDebugPrint : File %s - Line %d\n", __FILE__, __LINE__),fprintf(stderr, __VA_ARGS__)
#else
#define DebugPrint(...)
#endif

688 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:01:41 ]
リリース版ではインライン関数にして、
コンパイラの最適化に期待する手もある。

689 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:02:11 ]
/* 古いコンパイラで使える技 */
#if DEBUG
#define DebugPrint(args) printf args
#else
#define DebugPrint(args)
#endif

/* 使い方(一回余計に括弧で括らないといけないのが欠点だが) */
DebugPrint(("%d\n", 1234));

690 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:03:19 ]
古くなくてもできることないか?



691 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:03:47 ]
>>687,>>689
おぉ、凄いですね

色々ご教授ありがとうございます

>>688
もし良ければその方法も教えて頂けないでしょうか・・・

692 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:16:33 ]
1. インライン関数の定義を別ファイルに分ける

2. inline を INLINE マクロに置き換える
  INLINE マクロの定義は以下の通り(これは自分で定義する)

#ifdef NDEBUG
#define INLINE inline
#else
#define INLINE
#endif

3. リリース版の場合はヘッダファイルでインクルードする

#ifdef NDEBUG
#include "***.***"
#endif

4. デバッグ版の場合はソースファイルでインクルードする

#ifndef NDEBUG
#include "***.***"
#endif

693 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:16:49 ]
#if DEBUG
#define DebugPrint printf
#else
#define DebugPrint (int)sizeof
#endif

694 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:17:09 ]
C++なら、こんなことできるお

class DebugPrinter {
 DebugPrinter(const char *filename, int line) {...}
 void out(const char *format, ...) {...}
};

#if DEBUG
#define DebugPrint DebugPrinter(__FILE__, __LINE__).out
#else
#define DebugPrint
#endif

695 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:21:38 ]
>>694 リリースでエラーにならないか?

696 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:30:28 ]
>>695
エラーにはならないがデバッグ用のコードが完全には消えないという問題がある。

697 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:30:35 ]
>>695
たぶん、ならんよ。リリース時は
DebugPrint("%d, %d", f(x), f(y)); → ("%d, %d", f(x), f(y));
ってなるだけだから。

ただ、これがいやなら、>>693のようにsizeofしちゃうか、
dummyの関数作って
#if DEBUG
#define DebugPrint DebugPrinter(__FILE__, __LINE__).out
#else
inline DebugPrintDummy(const char *filename, ...) {}
#define DebugPrint DebugPrintDummy
#endif
って感じにしちゃうのがいいかもね

698 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:33:27 ]
VC++ なら ((void)0) (VC6まで)か __noop (VC2002以降)にした方がいいね。

699 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:34:36 ]
if(1); else に置換するという技もある。
多分最適化で消える。

700 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:39:27 ]
>>697
関数 f が副作用を持ってたら問題があるな。



701 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:39:55 ]
VC++ならTRACEで以上では?

702 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:41:56 ]
皆さん
感謝、感激雨あられです

ちょっとF1見てる隙にこんなに書き込みが・・・

色々参考にさせてもらいます

703 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:52:34 ]
何F1見てんだよこのヤロー

704 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:55:55 ]
ああ、F1押すと長々と待たされた後で
役に立たないヘルプが出るよね

705 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:56:43 ]
>>700
まあ、必要なら>>699で多分消せるじゃね?

>>701
TRACEは問題点は以下の3つ。
1,Windows限定
2,Boost.Formatなどの他の形式が使えない
3,出力先が変更できない
他にもあるかもしれんがよく分からん

706 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 02:57:53 ]
必要ならって言うか、必須なんだぜ。

707 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:02:02 ]
>>706
いや、そういう意味じゃなくて、
関数の副作用をどうしても消したいならって意味だお。
残したい場合も当然あるでしょ?

708 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:06:34 ]
>>699 だと式のつもりが文になってしまうね。

709 名前:デフォルトの名無しさん [2007/06/18(月) 03:10:09 ]
ちょっと相談です。
言語はCでもC++でも構いません。
ちなみに開発環境はWin2000+VisualStudio2005です。

DLLで用意された、既存の関数 Func(char* str) を呼び出す必要があります。
この関数は、処理結果を文字列として str に返してくれます。
strに渡される文字列の長さは *不明* です。
DLL、および関数Funcの中身を弄ることは出来ないものとします。

この時、長さの不明なstrを、安全に処理するテクニックがあれば教えてください。


710 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:18:04 ]
>>708
これならいけるかな?
#define DebugPrint 1 ? (void)0 : DebugPrintDummy



711 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:18:48 ]
>>709
static str[100000000];
ではどうだ?
そうですか、足りませんかすいません。

712 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:19:32 ]
>>709
Func を呼び出すことで、str の指すアドレスに
文字列が書き込まれるのであれば、安全に処理する方法は無いです

通常は、どの程度の長さが必要かを返す関数があったり、
渡したバッファの大きさを知らせる引数を付けたりします。

例えばFuncがファイル名を返す関数であるならファイルシステムが許す最大パス長などがあるので、
関数の仕様以外から最大の長さを決めることが出来るかも知れません

713 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:21:19 ]
>>711
charが抜けた。すいません。

714 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 03:25:49 ]
>>707
そういやそうだな。

715 名前:709 mailto:sage [2007/06/18(月) 03:28:23 ]
即レスサンクス。
やっぱ無理そうですね。boostあたりでなんか何とかならないかなーとか淡い期待を抱いてましたが。

>711
とりあえず1万バイトくらいでがんばろうと思います。

>712
バッファサイズ関連のパラメータとか、実際に無いものは仕方ないんで諦めます(笑)


716 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 09:01:59 ]
>>715
え、本当にどうしようもないの?
仕様上から決まる例(>>712 が言ってるMAX_PATH) とか、
NULL渡したら戻り値で必要length返るとかって挙動もないの?

そりゃDLLの設計が糞としか言いようがないが…

717 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 09:45:43 ]
gets を安全に使うにはどうすればいいですか?
っていう質問と一緒だね。残念ながら無理だ。

718 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 10:59:41 ]
仕様上から決まる例で32bit整数が最大値だとわかれば
常にその大きさの配列渡せば安心、かな

719 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 11:10:29 ]
メモリ使い切って落ちるに1票

720 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 11:12:45 ]
OS の API 直呼びで仮想メモリに頼ってしまう手もあるんジャマイカ?
それにしても 32bit 最大値はやりすぎだろうけど。



721 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 11:50:56 ]
パイプとかその辺のOSの用意したプロセス間通信機能でどうにかするしかないんじゃね?

722 名前:デフォルトの名無しさん [2007/06/18(月) 13:48:29 ]
すいません、また質問させてください。

#include <iostream>
using namespace std;
class base {
public:
int a;
base(int x) {a=x;}
};
class sub1 : virtual public base {
public:
sub1() : base(0) {}
};
class sub2 : virtual public base {
public:
sub2() : base(0) {}
};
class sub3 : public sub1, public sub2 {};
int main() {
sub3 obj;
obj.a = 10;
return 0;
}


これがコンパイル通らないんですが、baseクラスに引数のないコンストラクタを
追加するとコンパイル通るようになります。virtual指定で継承すると、引数のない
コンストラクタを呼ぶというルールなのでしょうか?


723 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 14:17:15 ]
#include <iostream>

namespace test_ {
  class base {
  public:
    base() { std::cout << "base::base()" << std::endl; }
    base(int x) { std::cout << "base::base(int x)" << std::endl; }
  };

  class derived1 : virtual public base {
  public:
    derived1() : base(0) { std::cout << "derived1::derived1()" << std::endl; }
    derived1(int x): base(x) { std::cout << "derived1::derived1(int x)" << std::endl; }
  };

  class derived2 : public derived1 {};
}
int main() {
  test_::derived2 a;
  return 0;
}
そのようですね
なので混乱を避けるために出来るだけデフォルトコンストラクタも定義しておきたいところです

724 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 14:53:20 ]
>>722
>引数のないコンストラクタを呼
んでるじゃないか、自分で。
>sub3 obj;

725 名前:709 mailto:sage [2007/06/18(月) 15:00:50 ]
>716
一応、strに渡されるのは1024バイト以内という仕様は一応あります。一応。
3000とか4000とか飛んでるのを何度か見たことはありますが。

726 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 15:21:26 ]
>>725
>一応、strに渡されるのは1024バイト以内という仕様は一応あります。一応。
>3000とか4000とか飛んでるのを何度か見たことはありますが。

そりゃーDLLが糞でFAじゃね?
もしくは文書に反映されてないだけで仕様が4096に変わってるとか…。
仕様であるならstrncpyでもなんでもやって1024以内にすべきだし。
仕事絡みなら、バッファサイズ1024で書いて落ちる&再現性ありの状態を作って、クレームつけるとかかね。

まぁがんがれw

727 名前:デフォルトの名無しさん [2007/06/18(月) 18:05:42 ]
#include <iostream>
#include <string>
#include <boost/function.hpp>
#include <boost/bind.hpp>

class Writer { public: void run(const std::string& str) { std::cout << str << std::endl; } };

class Module1 {
public: typedef boost::function<void(const std::string&)> func_t;
private: func_t func;
public:
  Module1(func_t func_) : func(func_) {}
  void run() { func("message"); }
};

int main() {
  Writer w;
  w.run("test");

  using boost::bind;
  Module1 module(
    static_cast<Module1::func_t>( bind(&Writer::run, &w) )
    );
  module.run();
  return 0;
}
Writerクラスのrun()をコールバック関数として、boost::bindを使ってクラスModule1に渡します
Module1はboost::functionを用いてこのコールバック関数を保持します
これを実現したいのですがエラーどころか、コンパイラ(VC2005のcl.exe)が落ちます(汗
どうすればこの動作を実現できるんでしょうか?

728 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 18:09:09 ]
自己解決しました
bind(&Writer::run, &w)→bind(&Writer::run, &w, _1)
引数とる場合はプレースホルダが要るんですね(汗

729 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 19:34:13 ]
>>722
class sub3 : public sub1, public sub2
{
  sub3() : base(1) {}
};
仮想基底クラスのコンストラクタは、最派生クラスから引数を指定してやることになっている

730 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 20:43:11 ]
こんばんは、皆さんに質問です
テンプレートの定数の引数をエレガントに記述する方法が分かりません

template <class Type, int Length> Array
{
   …Arrayの実装…
};

class Color : public Array< unsigned char, 3 > // RGBなので3
{
public:
   static const int ColorDimension = 3; // これは使えない…
   …Arrayの実装…
};

ここに出てくる3をエレガントに記述する方法が分かりません
グローバルで定義したりdefineディレクティブで定義したりは汚いですし、
無名namespaceやconst staticなグローバルの定数はヘッダなので避けたいです。



731 名前:デフォルトの名無しさん [2007/06/18(月) 20:48:52 ]
元々汚いんだからエレガントなんて求めなくて良い

732 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 20:50:52 ]
少しはきれいに書ける方法としては派生元で定義してしまう方法ですが…

template <class Type, int Length> Array
{ …Arrayの実装… };

class ColorBase
{
public:
  const static int Dimension = 3;
}

class Color : public ColorBase, public Array< unsigned char, ColorBase::Dimension > // RGBなので3
{  …Arrayの実装… };

なんか微妙です…第一、継承する意味があるのかと…う〜ん。
でもnamespaceだと関連性の記述があいまいです。

さらにはこんな方法もあるのですが…
class TColor<int Length> : public ColorBase, public Array< unsigned char, Length >
{  …Arrayの実装… };

typedef TColor<3> Color;

結局これでは定数をtypedefに移しただけで意味がなく、
const TColor::Dimension=3;
typedef TColor<TColor::Dimension> Color;
とまでして構造をめちゃくちゃにするのなら、
そのまま3って書いておいたほうがましな気がします。
何かよい方法があるのでしょうか?

733 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 20:53:19 ]
>>731
では、その元々汚いものを綺麗にする方法を教えてください。

734 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:00:58 ]
>>730
Arrayに手を付けていいなら、

template <class Type, int Length_> Array
{
public:
  static const int Length = Length_;
  //...
};

class Color : public Array<unsigned char, 3> // RGBなので3
{
public:
  static const int ColorDimension = Length;
  //...
};


735 名前:デフォルトの名無しさん [2007/06/18(月) 21:10:10 ]
int g1;int g2; int ga[10];
main(){
int li;int l2; int la[10]; int lb[10][10];

printf("%d\n", &g1);
printf("%d\n", &g2);
printf("%d\n", &l1);
printf("%d\n", &l2);

printf("%d\n", &l1-&l2);
}


↑のようなプログラムの
printf("%d\n", &l1-&l2);の表示結果の意味と
大局変数ga と局所変数la がどのように並んでいるのかを答えろって
課題なのですが、全くもって意味が分かりませんorz

ちなみにprintf("%d\n", &l1-&l2)の箇所の表示結果は”1”でした。
これはどういう事を意味しているのでしょうか?

ga[10]とla[10]に関してですが、これは[0]〜[9]までの配列が用意されてるって事で良いんですかね?

ヒントの方よろしくお願いしますorz



736 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:14:01 ]
なぜに&

737 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:15:51 ]
>ちなみにprintf("%d\n", &l1-&l2)の箇所の表示結果は”1”でした。
>これはどういう事を意味しているのでしょうか?
「鼻から悪魔がでてきて私をたぶらかした結果である」

738 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:16:17 ]
すみません、いくつか質問させてください。
1、ArrayクラスのLength変数はテンプレートが使用されたときに初期化されるのですか?
  int i = Array<int, 3>::Length;
  とかやったら(この例では最適化はされるでしょうが)アクセスしたその瞬間に
  初期化が行われるのでしょうか?

2、int i = Color::ColorDimension;
  とアクセスしたときは派生元のArrayから初期化が行われることは保証されていますか?

ちなみに、せっかく答えていただいたのに恐縮ですが、
class Color : public Array<unsigned char, 3>
の、3がマジックナンバーとなっているのを何とかしたかったのですが…
やはり無理でしょうか?何度も質問して申し訳ありません。失礼します。

739 名前:730 mailto:sage [2007/06/18(月) 21:18:19 ]
あ、私は730で>>734さんに対してのコメントです

740 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:20:20 ]
>>735
ヒント:課題スレではない


しかし答えておいてやろう
「&変数」は、メモリ上における変数のアドレスを意味している。
つまり、画面に表示されるのは各変数のアドレスだ。
&l1-&l2が1であるというのはつまり、ローカル変数は連続してるってことだ。




741 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:23:23 ]
>>735
>printf("%d\n", &l1-&l2);の表示結果の意味と
ぅゎぁ…課題だしたド阿呆を連れてきてくれ。説教してやるから。
配列を指すポインタであれば、例えば
&la[4] + 3 = &la[7] であり、逆に &la[7] - &la[4] = 3 なわけだが
配列でもなんでもないポインタの引き算に意味なんかない。
メモリ上、int のサイズ分離れた場所に割り当てられていると
答えさせたいんだろうが、課題として激しく相応しくない。
>[0]〜[9]までの配列が用意されてるって事で
おk。

742 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:27:19 ]
クラスを増やしたり、
define使ったり、
グローバルなenum使ったり
namespaceを使ったり
できないのなら、それは不可能ってことだよ。
別にグローバルにColorDimensionを定義してもいいじゃん。

743 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:44:32 ]
ここは格好良く可変引数取れるArrayにして
Array<unsiged char, RED, BLUE, GREEN>みたいに出来るようにしかないな
俺はやり方知らん上、この方法でもRED,BLUE,GREENをenum型か何かで定義しないと駄目だけど

744 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:49:54 ]
>>741
理論上は意味ないかもしれないけど、
実装を見るというのなら、意味ないこともないような気がしないでもない。

745 名前:デフォルトの名無しさん [2007/06/18(月) 21:51:47 ]
>>736
頭のおかしい講師に言ってくださいよorz
ほんと変な人で・・・
殆ど説明せずに課題をポンとだし、回答及び解説は次週って感じで
授業を進めるんです。

>>740
神様有難う。スレ違いだったんですか・・・。申し訳ないです。
&l1-&l2の件、理解しました。

>>741
神様レス有難う。
ga[10]とla[10]の件理解しました。


>ぅゎぁ…課題だしたド阿呆を連れてきてくれ。説教してやるから。
やっぱり、おかしいですよねえ??
Cのプログラムを受け持ってる髭面の汚らしい講師なんですが、
どうも変な奴なんですよ・・・。



746 名前:730 mailto:sage [2007/06/18(月) 21:54:59 ]
>>742
グローバルの名前空間は絶対に汚せない環境というのがございまして…
#define COLOR_DIMENSION 3
class Color : public Array< unsigned char, COLOR_DIMENSION > // RGBなので3
{
  …Arrayの実装…
};
#undef COLOR_DIMENSION
とかwww、もう何がなんだか…
#undef _COLOR_DIMENSION 3
あたりで我慢っすかねぇ

>>743
しかし、ArrayはColorとはあんまり関係なかったりして…
そもそも、public継承なのかprivate継承なのかという問題までありまして…

template <int Dimension = 3> class Color : public Array< unsigned char, Dimension > // RGBなのでデフォルトは3
{
public:
   Color() { assert(Dimension==3); }
}
とか…いや、assertで比較している3がまたマジックナンバーに…
なんかもう、素直にあきらめたほうが良いかも

747 名前:594デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:57:33 ]
C言語の全角半角処理について二点程分からないので、宜しかったらアドバイスを頂けたらと思います。
仕様してるのはVisualStudio2005で、プロジェクトはWin32コンソールアプリケーションのMFC付与です。
(CDatabaseクラスとかCRecordsetクラス等も使うこともできます)。
現在、入力された文字列に「@全角記号、半角記号、全角数字、半角数字を一文字でも含むならエラー」
(つまり@の処理は漢字や平仮名カタカナや英字は入力出来ます)
という処理と、「A全角半角のハイフン以外の全角半角記号を一文字でも含むならエラー」
(Aは、@の通過可能な条件に、全角半角数字が含まれます)
という処理と、「B全角半角の数字と全角半角のハイフンはOK」という処理の3つのロジックを組んでます。
半角記号や半角数字はASCIIコードを見ながら「for文で文字列を回してコードの中の記号を表す数字ならエラー」というロジックで
どうにかなってますが、Aのハイフンの判別ができずに詰まってます。
使ってるソースは、
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/joyful.cgi?mode=thr&no=3606
こちらの掲示板に
書き込んでおきます。
長くなりそうなので、続きの質問文はそっちのほうに書きます。
もし宜しかったお手数ですが、見てやって下さい。(投稿者名を「全角半角処理」にしておきます)。

748 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 21:58:46 ]
>>745
とりあえずグダグダうるせえ。




749 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 22:00:47 ]
>730
というか、継承では"Color is an Array"が成立するかという問題がある
ので、素直に包含関係にしてしまえ。

750 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 22:03:07 ]
>747
ShiftJISの仕様についてもうちっと調べるべき、かな。
まあ、一旦wcharに変換して扱う手もあるけどネ。



751 名前:デフォルトの名無しさん [2007/06/18(月) 22:17:19 ]
クラスと構造体の違いはデフォのアクセス制御以外に何かありますか?
継承、仮想関数も構造体で定義できるので、両者の違いは「文化的、歴史的」なモノだけだと思って良いでしょうか?

752 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 22:21:47 ]
classでレガシーな初期化はできなかった希ガス。
class Foo {int bar; int barz;} foo = {1, 2}
できたらごめん。

753 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 22:39:10 ]
>752
全メンバをpublicにすればコンパイルできた。
まあ、当然といえば当然か。

754 名前:デフォルトの名無しさん [2007/06/18(月) 22:49:14 ]
サンクス。
しかし、C++標準仕様は金を出さんと見れないのが癪だわ。。。
内緒にしとくもんでもなかろうて。

755 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 23:00:50 ]
質問
 1. 死ぬまでenumハックを使うべきなのか。
 2. 死ぬまでexportは使ってはならないのか。

756 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 23:07:21 ]
>>755
1. そうです
2. そうです

早死にしないように気をつけて

757 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 23:10:24 ]
1 VC6を窓から投げ捨てりゃいいんじゃね
2 EDG使ってないコンパイラを窓から投げ捨てりゃいいんじゃね

758 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 23:16:47 ]
>>754
www.jisc.go.jp/app/pager?%23jps.JPSH0090D:JPSO0020:/JPS/JPSO0090.jsp=&RKKNP_vJISJISNO=X3014


759 名前:デフォルトの名無しさん mailto:sage [2007/06/18(月) 23:44:18 ]
>738
初期化は実行時に起こる。
テンプレートが使用された時、というのはコンパイル時の話。

件の場合、定数化されてしまうというのを無視すると

int i = Array<int, 3>::Length;

とすると、Array<int, 3>::Length に相当する定義がコンパイル時に生成される。
で、その生成されたソース中に初期化が存在するから、コンパイルした結果のコードでも
初期化が実行される。タイミングは普通の初期化と一緒で main 到達前。

>2、int i = Color::ColorDimension;
>  とアクセスしたときは派生元のArrayから初期化が行われることは保証されていますか?
実際には Color::ColorDimension は定数と見なされるので Array と無関係に単なる 3 として評価されると思われ。

760 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 06:38:16 ]
いくつかのサイトで見られたのですが、
STARTUPINFO si = {sizeof (STARTUPINFO)};
は何をやっているんでしょうか?
STARTUPINFO si = {0};
や、
STARTUPINFO si;
memset(&si,0,sizeof (STARTUPINFO);
si.cb = sizeof(STARTUPINFO);
などなら分かるのですが。



761 名前:760 mailto:sage [2007/06/19(火) 07:24:58 ]
あ、すみません。
構造体の第一メンバをsizeof (STARTUPINFO)で、
残りのメンバを0で初期化している事が分かりました。
値を設定してないと0で初期化されるようですが、
STARTUPINFO si = {};
のような使い方では0で初期化される保証はないのでしょうか?


762 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 07:59:43 ]
>>760
定義時初期化で済むことを、わざわざバグの混入する可能性のあるmemset()にする理由はなかろう。
また、STARTUPINFOに先頭にサイズを入れておくお約束があるならやはり初期化で入れるのが一番。

>STARTUPINFO si = {};
コンパイル通った?

763 名前:760 mailto:sage [2007/06/19(火) 08:56:24 ]
はい。VC2005でコンパイルが通り、結果も0で初期化されてることを確認しました。
コンパイル通らない可能性もあるんですね。それなら使いません。

あと、STARTUPINFO si = {0}; による初期化でも、/NODEFAULTLIBでビルドすると
「error LNK2001: 外部シンボル "_memset" は未解決です。」と出ることがあります。
これはmemset()が使われてるということなんでしょうか?

764 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 08:56:28 ]
>>761
全部省略できるのは C++ だけ。

765 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 09:59:42 ]
>>763
そうみたいだね。 memset() は標準ライブラリだから、
リンクできることを前提にしてるんだろう。

766 名前:デフォルトの名無しさん [2007/06/19(火) 10:21:17 ]
すみません、このスレでいいのか迷うんですが、
Windows2000やXP、Vistaで、アプリからサービスを一時的に停止したり
開始したりする方法を教えて下さい。
宜しくお願いします。

767 名前:760 mailto:sage [2007/06/19(火) 11:07:01 ]
>>764
おお、なるほど。C++でした。
>>765
ありがとうございます。
みなさん、どうもありがとうございました。

768 名前:766 mailto:sage [2007/06/19(火) 12:48:11 ]
解決しますた

769 名前:デフォルトの名無しさん [2007/06/19(火) 12:57:26 ]
今現在BMPの画像をexeファイルで表示する方法をやってるのですが
よろしければ必要最低限のプログラムのソースを教えていただけませんか?
よろしくお願いします。

770 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 13:01:28 ]
>>769
>>1
>ただしその場合、質問者は必ず、環境を書きましょう。



771 名前:デフォルトの名無しさん [2007/06/19(火) 13:10:27 ]
>>469 とりあえずこれで"今現在BMPの画像"を表示できるプログラムができる
#include <stdio.h>

int main(){
printf("今現在BMPの画像");
return 0;
}

772 名前:デフォルトの名無しさん mailto:sage [2007/06/19(火) 13:11:07 ]
どうせWindowsだろ
猫でも読んどけ






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<258KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef