5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

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

1 :デフォルトの名無しさん:2010/01/29(金) 23:15:45
エスケープシーケンスやWin32APIなどの環境依存なものでもOK。
ただしその場合、質問者は必ず環境を書きましょう。
※sage禁止です(と代々スレに書いてありますが自己判断で)。

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

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

◆ソースのインデントについて
半角空白やTABでのインデントはスレに貼ると無くなります。
そのため、アップローダーに上げるのも手ですが直接貼る場合は、
全角空白か に置換すると見栄えだけはよくなります。


936 :デフォルトの名無しさん:2010/02/27(土) 17:48:47
bcc32 の日本語エラーを重宝していますが。

937 :デフォルトの名無しさん:2010/02/27(土) 17:53:48
cxx

938 :デフォルトの名無しさん:2010/02/27(土) 19:21:09
VC++, g++かな。
Comeau C++はいつか買いたい。
それ以外はなぁ。。。


939 :デフォルトの名無しさん:2010/02/27(土) 19:54:36
VC++2008EEでC++0xで遊びたいときはGCCかな

940 :デフォルトの名無しさん:2010/02/28(日) 08:32:27
低スペッコマシンで動くvc++6.0とg++は最高っすね。

941 :デフォルトの名無しさん:2010/02/28(日) 10:03:54
int n= (1>=0);
こうやった時にnが1になるのは実装依存ですか?

942 :デフォルトの名無しさん:2010/02/28(日) 10:33:05
>>941 いいえ、規格で定められた動作です。

943 :デフォルトの名無しさん:2010/02/28(日) 10:54:33
>>942 ありがとうございます

944 :デフォルトの名無しさん:2010/02/28(日) 12:11:45
「0以外になる」じゃなくて「1になる」って規格で決まってたのか

945 :デフォルトの名無しさん:2010/02/28(日) 12:16:27
今までC#をやっていてC++をはじめたんですが
C++のヘッダファイルとソースファイルに分けるのが面倒(というか慣れてない)ので
ヘッダファイルのクラス定義の中で(C#みたいに)実装もしちゃおうと思ってるんですが(慣れるまで)
注意すべき落とし穴とか教えてください

946 :デフォルトの名無しさん:2010/02/28(日) 12:17:39
>>945
書き忘れました
環境はMinGW+EclipseCDTです

947 :デフォルトの名無しさん:2010/02/28(日) 12:28:38
修正する度にコンパイル時間がかかる。

948 :デフォルトの名無しさん:2010/02/28(日) 12:33:12
クラスに直接実装すると、暗黙的にinlineが付く
そのため量が多いコードを書いて
それが多数の箇所で引用されるようなら
無駄にインライン展開された分のオーバーヘッドがかかる

949 :デフォルトの名無しさん:2010/02/28(日) 12:44:02
>>944
決まってるよ
>=演算子の結果は0か1

ISO/IEC 9899 Programming languages ― C
6.5.8 Relational operators
6 Each of the operators < (less than), > (greater than), <= (less than or equal to), and >=
(greater than or equal to) shall yield 1 if the specified relation is true and 0 if it is false.90)
The result has type int.

950 :デフォルトの名無しさん:2010/02/28(日) 12:46:39
>>945
実装を分けて書くのになれると、C#は実装を別けられなくて不便だって思うようになるよ。


951 :デフォルトの名無しさん:2010/02/28(日) 12:51:20
>>950
それはないだろ…分けたけりゃinterface使えばいいだけ

952 :デフォルトの名無しさん:2010/02/28(日) 12:57:01
ttp://chadaustin.me/cppinterface.html
これ読むと脱力するなあ
クラスをインタフェース、ファクトリ、実装に分割する
インタフェースではPOD以外の型や例外を使えない
多分不便すぎるから、さらにstaticリンクやヘッダオンリーのラッパーも書くんだろう
手間かかりすぎだ

953 :デフォルトの名無しさん:2010/02/28(日) 12:59:57
>>947,948,950
レスありがとう
とりあえず(学習レベルでは)致命的な問題が生じることを意識せずに
書いても大丈夫そうですね

954 :デフォルトの名無しさん:2010/02/28(日) 14:01:22
>>952
virtualってバイナリ互換性ないんじゃなかったっけ?

955 :デフォルトの名無しさん:2010/02/28(日) 14:06:10
>>954
その文書では、Windows環境でかつ、COMが使える(つまりvtblのレイアウトに
関してはCOMとABI互換性がある)コンパイラに関することが書いてあるから、
完全な一般論ではないはず

956 :デフォルトの名無しさん:2010/02/28(日) 15:11:15
cで

void test(char str1[], char str2[])
{
strcat(str1, str2);
        
      //いろいろ 
return ;
}

int main()
{
char path[]="D:\"
char filename[]= "test";

  printf("%s", path); ←D:\と表示される
   test(path, filename);
  printf("%s", path); ←△D:\test と表示される

return 0;
}

△のとこは普通D:\と表示されるんではないんですか?
しかしD:\testと表示されてしまいます。

D:\にもどすにはどうすればいいんでしょうか。

957 :デフォルトの名無しさん:2010/02/28(日) 15:18:36
その前にリテラルにstrcatするな。

958 :デフォルトの名無しさん:2010/02/28(日) 15:18:40
>>956
「普通」とか言ってないで、どうしてそうなるのかよく考えてみろ。

まず "D:\" では最後のクォートがエスケープされてコンパイルエラーになるはずだ。
そこを直したとしても、そのコードでは strcat() の時点でバッファオーバーランを
起こしてしまっているはず。何が起こっても文句は言えない。

959 :デフォルトの名無しさん:2010/02/28(日) 15:19:22
>>957 リテラルじゃぁない。領域サイズに問題がある。

960 :956:2010/02/28(日) 15:37:16
ちょっとわかりにくかったんで
http://www.dotup.org/uploda/www.dotup.org692367.png

試しに
char path[40] とかでもだめでした

961 :デフォルトの名無しさん:2010/02/28(日) 15:40:41
test()のなかでstr1を変更してるからじゃないの?
str1とstr2を連結した新しい変数を使用してはいかがでしょうか?

962 :デフォルトの名無しさん:2010/02/28(日) 15:47:10
#include <stdio.h>
void test(char str1[], char str2[])
{
  strcat(str1, str2); // ここでpathを変更してるので元には戻せない。変更しなければ良い。
        //いろいろ  
  return ;
}
int main()
{
  char work[20];
  char path[20]="D:\\";
  char filename[20]= "test";
  puts(path); // D:\ と表示される
  strcpy(work, path);
  test(work, filename);
  puts(path); // D:\test と表示される
  return 0;
}
D:\My Documents\Cplus\初心者_956>cl mondai.c
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
mondai.c
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation. All rights reserved.
/out:mondai.exe
mondai.obj
D:\My Documents\Cplus\初心者_956>mondai
D:\
D:\
D:\My Documents\Cplus\初心者_956>

963 :デフォルトの名無しさん:2010/02/28(日) 15:47:18
>>956
根本的に分かってないだろ。

>△のとこは普通D:\と表示されるんではないんですか?
されません。
文字列連結(strcat)してるんだから、path[]のケツにfilename[]がくっ付くに決まってる。
>しかしD:\testと表示されてしまいます。
それで正常です。バッファオーバーランしてるけどな。

ディレクトリ名とファイル名以外に、フルパス用の配列でも作ってろ。
よう分からんならstd::string使ってろ。

964 :デフォルトの名無しさん:2010/02/28(日) 15:48:07
>>961の言うとおり
strcatは最初の引数に与えたものも変更してしまう
ttp://www9.plala.or.jp/sgwr-t/lib/strcat.html

void test(char str2[]){
char temp[MAXPATH];
strcat(temp, str2);
        
      //いろいろ 
return ;
}
こんな風にしたら?

965 :デフォルトの名無しさん:2010/02/28(日) 15:49:27
ああ、微妙に変だけど細かいことは気にしない

966 :デフォルトの名無しさん:2010/02/28(日) 15:50:26
>>956
testの前後でprintf("%p", path);としてみればpath自体の値は変わってないことが確認できると思う
あとは文字列について勉強して、ポインタについて勉強すればおk

967 :デフォルトの名無しさん:2010/02/28(日) 15:56:51
>>957-959,961-966
できました!ありがとうございます

968 :デフォルトの名無しさん:2010/02/28(日) 16:08:49
 板違いかもしれないが、教えてください。
 Windows環境で関数の実行アドレスを取得したいのですよ

 void funcA(void);

main()
{
GetFuncAddress((void*)&func);
}

GetFuncAddress(void* pFunc)
{
//pFuncの中をダンプすると
//0xff,0x25,0x..(4Byteアドレス)
}
 となっており、0xff,0x25がJMP命令の絶対相対nearコール
になっているんだが、ここからなんとか、関数の実行アドレス
を割り出したいのです。
 知っていたら教えてください。


969 :デフォルトの名無しさん:2010/02/28(日) 16:36:33
>>968
なんでダンプしちゃうのw
pFunc で取れてるだろ。 printf("%p", pFunc) とか。

970 :デフォルトの名無しさん:2010/02/28(日) 16:42:25
968です
 pFuncで取れているのは、関数の実行アドレスではないです。
 このときのアドレスの中身は、関数の実体へのジャンプ命令なんです。
 で、ほしいのはセグメント上に展開されているはずの、この
ジャンプ命令の示しているジャンプする先のアドレスがほしいのです。


971 :デフォルトの名無しさん:2010/02/28(日) 16:46:15
>>970
よくわからんが、ジャンプ命令のジャンプ先が欲しいんならジャンプ命令の
仕様どおりに(CPUの動作をなぞって)アドレス計算するんじゃダメなの?

972 :デフォルトの名無しさん:2010/02/28(日) 16:57:08
 えと、JMP命令の後ろに記述されているやつが、
nearポインタのアドレスだと思うのだけど、
nearポインタだからセグメントの先頭アドレス
が必要なのですよ、で、C言語(Win32APIなどを使っても
良いので)が必要。

 知りたいのは、
 1.JMP命令の次の4バイトがnearポインタでよいのか?
  →この4バイトのアドレスが示している場所に、オフセット値が記述されている
   という解釈でよいのか?
 2.そのばあい、オフセットなのでセグメントの先頭アドレスをどうやって取ればよいのか?
という2点なのです


973 :デフォルトの名無しさん:2010/02/28(日) 16:58:39
セグメントなんて使ってねえから
フラットメモリモデルだから
そのまんま解釈すればいいから

974 :デフォルトの名無しさん:2010/02/28(日) 17:01:42
 そうですか、それではもう少し調べてみます。
 解釈が間違っていたようです。
 ありがとうございました。


975 :デフォルトの名無しさん:2010/02/28(日) 21:28:14
コンソールアプリケーションでMessageBoxって使えないんですか?
うまくいかないんですがもし使えるならどうやれば使えるでしょうか?

976 :デフォルトの名無しさん:2010/02/28(日) 21:36:30
使えてるぞ
// cl hello.cpp user32.lib
#include <windows.h>
int main() {
MessageBox(NULL,"aaaaaaa", "bbbbbb", 0);
}


977 :デフォルトの名無しさん:2010/02/28(日) 21:40:09
あ、できました
ありがとうございます

978 :デフォルトの名無しさん:2010/03/01(月) 11:06:21
とりあえず色々と試してみることさね

979 :デフォルトの名無しさん:2010/03/01(月) 11:25:25
>>972
Windowsのdllはstubを介してジャンプする事になっている。
セグメントの先頭アドレスは必要ない。jumpのオペランドは
そのジャンプ命令からの相対アドレス。

980 :デフォルトの名無しさん:2010/03/01(月) 15:41:46
↓これって安全でしょうか?

// dll
extern "C" void _cdecl func(const tr1::shared_ptr<hoge> &p); // c++のための公開関数

// def
EXPORTS
func

// main
pfunc = my::get_dll_function("func");

tr1::shared_ptr<hoge> p(new hoge, my::deleter);

pfunc(p);


dllはC++で使われることが前提ですが、mainをコンパイルするコンパイラは不定です

981 :デフォルトの名無しさん:2010/03/01(月) 15:55:05
今C++でフォームアプリケーションを作ってるのですが、ファイルからテキストを読み取ってラベルに表示したいのですが
while(fgets(data, 1000, fp) != 0){
strcat(temp,data);
}
String^ filetext = gcnew String(temp);
label1->Text = filetext;

とすると文字化けしてしまいます、どうすれば良いのでしょうか?

982 :デフォルトの名無しさん:2010/03/01(月) 16:28:02
ファイルの文字コードはなんなのとか
System::IO::File::ReadAllText使えとかいろいろあるけど
C++/CLIはこっちできこうね
http://pc12.2ch.net/test/read.cgi/tech/1206447234/

983 :デフォルトの名無しさん:2010/03/01(月) 16:32:48
文字コードを指定してStreamReaderを使う

984 :デフォルトの名無しさん:2010/03/01(月) 16:36:21
できたぽ
サンクスだぽ(`・ω・´)

985 :デフォルトの名無しさん:2010/03/01(月) 16:39:08
ちなみにフォームアプリケーションって
C#で作るのと
C++でフォームアプリケーションから作るのと
C++で空のプロジェクトから作るのと
軽さはどれくらい違いますか?

244 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)