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

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2007/02/18(日) 10:24:47
math.hで

int main()
{
float i,j;

printf("atan2()\n");

i=1;
j=0;

printf("atan2(1,0)(→)は%d\n",atan2(i, j));

getch();

       ・・・ry

のようなプログラムを書いて出力したのですが、

atan2()
atan2(1,0)(→)は1610612736
atan2(0,1)(↑)は0
atan2(-1,0)(←)は1610612736
atan2(0,-1)(↓)は1610612736

返ってきた値は以上で、
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/vclib/html/_crt_atan.2c_.atan2.asp
にあるように、
>?π 〜 π ラジアンの範囲で返します。
返してくれないんですが、使い方が間違っているのでしょうか?
953デフォルトの名無しさん:2007/02/18(日) 10:28:30
>>951
関数レベルで排他制御を行っているような典型的な実装なら、
1) fputs()やfprintf()等を用いて、常に\nで終わる文字列をstdioに
 与えるようにする。
2) _IOLBFモードを設定しておく
ことで、出力がcritical section内で完結し、行レベルでatomicになる。
「出力を崩したくない」というのは、通常はそういう意味のはず。
954デフォルトの名無しさん:2007/02/18(日) 10:29:34
>>952
× %d
○ %f
955デフォルトの名無しさん:2007/02/18(日) 10:31:12
>>954
orz

atan2()
atan2(1,0)(→)は1.570796
atan2(0,1)(↑)は0.000000
atan2(-1,0)(←)は-1.570796
atan2(0,-1)(↓)は3.141593

ちゃんと帰ってきました。
ありがとうございました↓↓
956デフォルトの名無しさん:2007/02/18(日) 10:36:12
○%f
◎%g
957デフォルトの名無しさん:2007/02/18(日) 11:04:50
>>934
俺がマルチスレッドでログ出すときは改行までを1回の関数コールでしているな。
2回の関数コールで文字を出したりすると間に別の文字が入るから。

場合によってはミューテックスつきの自作printf風ログ関数を必ず使うようにしている。
# 俺はstd::coutを使わないprintf派。
958デフォルトの名無しさん:2007/02/18(日) 11:44:33
俺はスレッド単位でログ出力先変える派
スレッド数少ない時限定だけど。
959934:2007/02/18(日) 12:32:42
レスありがとうございました。
マルチスレッドでは単純な文字列の出力でも
同一のリソースにアクセスすることになって面倒なことになるようですね。
勉強になりました。ありがとうございます。
960デフォルトの名無しさん:2007/02/18(日) 13:09:18
お願いします。

下のプログラムは数値を入れ替えるプログラムsort.cである。以下の問いに答えよ。
1.プログラム内の@〜Eに適当な命令を入れてプログラムを完成せよ。ただし@とAは複数の回答がある。可能な限り全て答えよ。
2.変数aがメモリの1000番地に格納されていた。int型が4バイトとすると、変数bは何番地に格納されるか答えよ。
3.関数間のデータ受け渡しにポインタを使うメリットとデメリットを説明せよ。

#include<stdio.h>
/*ポインタ渡しでデータの交換*/
void swap(int *x, int *y);
int main(void)
{
int a=1731, b=935;
int *p1, *p2;
/*ポインタに代入*/
p1=&a;
p2=&b;
printf("初期状態\t");
printf("a=%d b=%d\n",a,b);
swap(@,A);
printf("swap終了後\t");
printf("a=%d b=%d\n",a,b);
return(0);
}

void swap(int *x, int *y)
{
B z;
z = C;
*x = D;
*y = E;
}
961デフォルトの名無しさん:2007/02/18(日) 13:11:36
宿題スレ池ヴォケ
962デフォルトの名無しさん:2007/02/18(日) 16:34:41
C++で、静的メンバ変数に関数ポインタを指定するにはどうすればいいのでしょうか?

class CA{
public:
static int (*s_m_func1)();
};
int * CA::s_m_func1();

これだと『'CA::s_m_func1()'は'CA'のメンバーではない』って言われて、コンパイルできません。
お助けお願いしますー。
963デフォルトの名無しさん:2007/02/18(日) 16:38:24
>>962
何そのありえない構文
964デフォルトの名無しさん:2007/02/18(日) 16:43:26
>>962
int (*CA::s_m_func1)() = 0;
965デフォルトの名無しさん:2007/02/18(日) 16:44:30
>>962
クラス内でstatic int (*s_m_func1)();と宣言したら、
その定義は機械的にstaticを外して名前にクラス名::を付けるだけで作れる。
int (*CA::s_m_func1)();
966デフォルトの名無しさん:2007/02/18(日) 16:48:55
>>963
馬鹿でごめんなさいm(_ _)m
>>963-965
ありがとうございました!
おかげでできました。
967デフォルトの名無しさん:2007/02/19(月) 10:45:27
質問です。
placement newのoperator delete(void *p, void* pMemory);で、
渡された*pの型を取得する方法はありませんでしょうか。
operator delete(void *p, void* pMemory)の中でデストラクタを呼んでやりたいのです。

通常のdeleteは、
delete pHoge;
で、Hogeを正しく解体できますし、デストラクタも呼んでいますよね。
これは正しい型情報(pHogeの型のものでしょう。void*にキャストしてから渡すとデストラクタは動きませんから)がdeleteに渡されているからだと思うのですが…。

968デフォルトの名無しさん:2007/02/19(月) 12:14:51
operator deleteの仕事は、メモリを適切に解放するだけです。もうデストラクタは呼ばれているはず。
969デフォルトの名無しさん:2007/02/19(月) 12:25:47
>>968
ありがとうございます。
なるほど。確かに通常のdeleteでは、その中に入る前にデストラクタが呼ばれていますね。
となると通常のdeleteはどんなトリックを使っているのでしょうか。
単純に「C++のコンパイラが、そこにデストラクタを呼ぶコードを自動で入れてるんだよ」ということでしょうか。

現在、こんなようなコードになっています。

template<class T>
class CHoge
{
/*省略*/

void test()
T* p;
p = new(pMemory) T;
operator delete(p, pMemory);
}
};

ここには二つの障害があるように思えます。
・Tのデストラクタをどうやって呼び出すか。
・そもそも、Tにデストラクタが無かったらエラーになってしまう。
この2点について、解決できる手法がありますでしょうか?
970デフォルトの名無しさん:2007/02/19(月) 12:33:05
デストラクタを明示的に呼び出してあげてください。こんな感じで

p->~T();

こことか参照 http://www.fides.dti.ne.jp/~oka-t/cpplab-placement-new-2.html
971デフォルトの名無しさん:2007/02/19(月) 12:38:14
new演算子の仕事 : operator newでメモリを確保 → コンストラクタ呼び出し
delete演算子の仕事 : デストラクタ呼び出し → operator deleteでメモリ開放

new/delete演算子と、operator new/deleteの意味の違いに気をつけよう、とMore Effective C++で読んだ。
972デフォルトの名無しさん:2007/02/19(月) 13:37:47
>>970
ありがとうございます。
intなどにもデストラクタが存在するというのは盲点でした。
思い込みにとらわれて、p->~T()がコンパイル通るか試していなかったのが恥ずかしいです。

>>971
なるほど。
その上で、placement new/delete にはnew/delete演算子形式の書式がないので自前でデストラクタを呼ぶ必要があるというわけですね。
ありがとうございます。

思ったとおりの実装ができそうです。
これにて967の質問は解決とさせていただきます。
ありがとうございました。
973デフォルトの名無しさん:2007/02/19(月) 17:55:49
new 演算子で確保した配列メモリのサイズを、
sizeof()で配列のサイズを得るようにするにはどうしたらいいのでしょうか…

ググり方が下手で見つけられませんでした…
    出来ればどうググったらよいのかも

もう一つ、reallocの動作をさせるのには、
いったんnewで別に配列メモリを確保して、古い配列メモリをdeleteした上で、
今確保したアドレスを代入するのが最良なのですか?

int *pa = new int[5];


int *pat = new int[10];

for(i = 0; i <= 5; i++){
pat[i] = pa[i];
}
delete [] pa;
pa = pat;

のような…
このとき最後にdeleteすべきなのはpa? pat?
974デフォルトの名無しさん:2007/02/19(月) 18:04:54
そんなことしないで、素直にstd::vector使えよ。
975デフォルトの名無しさん:2007/02/19(月) 18:49:06
質問があります。
class A
{
public:
Test();
};

class B
{
public:
Here();
};

と言うクラスがあるとします。
現在classBのHere()内にいてclassAのTest()関数を呼び出したいのですが、
どうするのが一番良いのでしょうか?
実際は他にもメンバがある状態でTest()のみを使用したいので継承はないかと思ってます。
となると、Here()内でclassAをインスタンス化して呼び出すか、classBに同じ関数を作るという方法を
思いついたのですがどうなのでしょうか?
よろしく御願いします。
976デフォルトの名無しさん:2007/02/19(月) 18:54:51
A::Testというのは普通Aのインスタンスを弄ると想定されるわけだが、
B::Hereにおいては、Aのインスタンスの変更以外の作用が欲しい、というところか?

A::Testのうち、インスタンスに依存しない部分を切り出すのはどうだろうか。
977975:2007/02/19(月) 19:02:09
説明不足ですいません。
A::Test()はclassAのメンバを弄るのではなく、引数で複数の変数ポインタを渡し
それらを計算してアドレスを返すという関数なんです。
classAのメンバ関数内でで数回呼び出すのでclassAのメンバ関数とした訳ですが、
構造的に悪かったですか?
978デフォルトの名無しさん:2007/02/19(月) 19:06:32
弄らないならstaticにでもしとけ。
979973:2007/02/19(月) 19:08:05
>>974
stringとかvector使うと
INIファイルを弄るあたりが面倒になるので、あまり使いたくないのですが…

たとえばGetPrivateProfileStringやGetWindowTextなどでバッファは配列アドレスを渡す必要があるので…
980975:2007/02/19(月) 19:10:18
>>978
あ、そういう手がありましたね。有り難うございました。
981デフォルトの名無しさん:2007/02/19(月) 19:17:10
>>979
vectorでできないわけないだろ・・・
982デフォルトの名無しさん:2007/02/19(月) 19:23:57
ジェネリック医薬品なテンプレート定義
983デフォルトの名無しさん:2007/02/19(月) 19:26:52
何のための&vector[0]だよ。
984デフォルトの名無しさん:2007/02/19(月) 20:01:04
>>979
std::vectorの要素はメモリ上で連続していることが保障されていて、
真にmalloc/realloc/freeなどと同じように動的メモリとして使える。
983の言うとおり先頭要素へのポインタという形で取り出せばよい。

ただしイテレータはポインタで実装されているとは限らないので、
begin()は狩にお前使っている処理系で使えたとしても使うべきでない。
985デフォルトの名無しさん:2007/02/19(月) 20:23:13
std::vector<char> v(0x1000, '\0');
std::fgets(v, v.size(), stdin);
std::vector<char>::iterator pos = std::find(v.begin(), v.end(), '\0');
std::string line(v.begin(), pos);

とかキモいな。
どうせC関数とインタフェースするところなんて、多かれ少なかれ汚いんだから、
適材適所で使い分ければいいんでねーの?

char v[0x1000];
std::fgets(v, sizeof v, stdin);
std::string(v);

のが記述が簡単で効率もいいだろ。
986985:2007/02/19(月) 20:24:42
ごめん
- std::fgets(v, v.size(), stdin);
+ std::fgets(&v[0], v.size(), std::stdin);
987デフォルトの名無しさん:2007/02/19(月) 20:37:03
なんでstd::findするの?string(&v[0])でいいじゃん。
vector<char>をNUL埋めする意味もわからん。
988デフォルトの名無しさん:2007/02/19(月) 20:39:58
そもそもなぜstd::getline使わない

>>987
どうせ省略しても'\0'で初期化されることに変わらない気がする
989973:2007/02/19(月) 20:40:13
…動的メモリとして使えるコトを全く知りませんでした…
vectorなんて使い必要ないじゃんとか考えていて……

バカなことばっかですいません。
990デフォルトの名無しさん:2007/02/19(月) 20:41:31
iostreamは遅い、というのが定説だからじゃないの。
991デフォルトの名無しさん:2007/02/19(月) 20:52:10
俺の周りでは定番なんで貼っとく。

>>989
http://www.s34.co.jp/cpptechdoc/article/vectorastemp/index.html
> テンポラリ・バッファとしての std::vector の利用
992デフォルトの名無しさん:2007/02/19(月) 20:57:35
>>990
それだったらOSのAPIを呼べよと俺は思ってしまう。
993985:2007/02/19(月) 21:02:05
>>987
前者はその通りだな。
後者は、予め領域は確保しなきゃならんでしょ?その副作用。

malloc()のように「確保だけする」手段ってstd::vectorにはないよね?
指定しなくとも、必ず何かデフォルト値で埋められる。
つまり効率が少なくともcalloc()並に落ちるということ。

auto配列とは比較にならないね。

>>988
単にC関数とインタフェースする例だよ。
別にfgets()である必要は全く無い。
994デフォルトの名無しさん:2007/02/19(月) 21:06:16
要素数固定でよければ、boost::arrayがいいと思っていた時期があった。
995973:2007/02/19(月) 21:07:32
>>991
そもそもvectorの根本的な使い方わかってなかったみたいです…

ともかく、おつきあいいただきありがとうございました。
996デフォルトの名無しさん:2007/02/19(月) 21:08:46
reserve()の立場は
997デフォルトの名無しさん:2007/02/19(月) 21:13:10
>>996
size()で得られるインデックス以上の要素にアクセスしてはならない以上、
固定長のバッファが欲しいときに使う性質のものではない。
998デフォルトの名無しさん:2007/02/19(月) 21:19:42
組込みのauto配列はコンパイル時固定サイズだが、それでは困るって場合には
alloca()使えばいい。
移植性にやや難があるけどな。
999デフォルトの名無しさん:2007/02/19(月) 21:24:12
allocaは不足しても延ばせないからなー
1000デフォルトの名無しさん:2007/02/19(月) 21:25:17
つ std::get_temporary_buffer
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。