スレを勃てるまでもないC/C++の質問はここで 4
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2008/09/17(水) 15:41:48過去ログ
スレを勃てるまでもないC/C++の質問はここで
http://pc11.2ch.net/test/read.cgi/tech/1167476845/
スレを勃てるまでもないC/C++の質問はここで 2
http://pc11.2ch.net/test/read.cgi/tech/1178503366/
スレを勃てるまでもないC/C++の質問はここで 3
http://pc11.2ch.net/test/read.cgi/tech/1187521676/
0596なめ ◆dHe9wXXwgk
2008/12/11(木) 21:44:46ありがとうございます。
fscanf で、delimiterが、'\t'とか扱えるんですか?また、複数の' 'を1つの区切りとして扱えましたっけ?
>>560
ありがとうございます。
[1000]の部分は、可変長(極端な話、65535 とか)にしたいですが、その場合この方法だと難しいですよね
>> 562
>楽なのは stream I/O で >> 演算子。
ありがとうございます。
速度の面でどうなんでしょうか?
あと、delimiterが、TABの場合は可能でしょうか?
0597デフォルトの名無しさん
2008/12/11(木) 21:48:190598デフォルトの名無しさん
2008/12/11(木) 22:12:51スレ違いながらもいい機会だと思ったのになー
vcprojファイル内の順番がぐちゃぐちゃにならない方法でもいいんだけど。
0599デフォルトの名無しさん
2008/12/11(木) 22:36:31double log2(double a,double b){
return log(b)/log(a);
}
とやるしかないんかのぉ。
0600デフォルトの名無しさん
2008/12/11(木) 23:07:08なんでプロジェクトファイルをみんなで弄るんだ?
つーか、Subversionスレに行けって。
>>599
ない。
>>596
1000が65536でも別に構わんと思うが。どっちみち、最大サイズの仮定なんだから。
0601デフォルトの名無しさん
2008/12/12(金) 08:12:13ユーザーが入力するのは52進数か62進数のパスワードです。このとき変数がオーバーフローしないようにすることを考えると、
いちいち52進数ないし62進数の最大値を求めてそれ以上上がらないように設定するしかないでしょうか?
(例えばある桁がAで左の桁がBでさらにその左の桁がCならその桁は上げることができない)
それともif文でif(変数 + 上昇量 > 2147483647)のようにif文の中だけでオーバーフローするようなことができるのでしょうか?
0602デフォルトの名無しさん
2008/12/12(金) 08:27:5752進数は「A〜Z,a〜z」、62進数は「0〜9,A〜Z,a〜z」ってことか?
> if文でif(変数 + 上昇量 > 2147483647)のようにif文の中だけで
> オーバーフローするようなことができるのでしょうか?
可能かどうかと言えばできる。
環境や言語は知らんが、WindowsでVC++(MFC)なら、CEdit派生クラスで
OnCharをオーバーライドかな。
それよりも問題は、入力途中の段階で52進数か62進数かを、どうやって
判断するのかだ?
それと52進数で「A」と入力した時と、62進数で「A」と入力した時では、
数値に変換した際に値が違うのか?
0603デフォルトの名無しさん
2008/12/12(金) 08:32:20解答ありがとうございます。
52進数か62進数と言ったのは単に自分が仕様をまだ決めてないだけです。
環境はSolaris コンパイラはcc or gccです。
0604601
2008/12/12(金) 09:41:27pass[1] * 62 * 62 * 62 * 62 * 62 * 62 * 62 * 62 +
pass[2] * 62 * 62 * 62 * 62 * 62 * 62 * 62 +
pass[3] * 62 * 62 * 62 * 62 * 62 * 62 +
pass[4] * 62 * 62 * 62 * 62 * 62 +
pass[5] * 62 * 62 * 62 * 62 +
pass[6] * 62 * 62 * 62 +
pass[7] * 62 * 62 +
pass[8] * 62 +
pass[9] > 2147483647) pass[now_i]--;
実際にプログラミングしてみたらこのコードがうまく動きませんでしたどうしたらいいでしょうか?
0605デフォルトの名無しさん
2008/12/12(金) 09:44:24お馬鹿さんや、62の9乗を計算してご覧。
高高6桁で桁溢れするわけだが。
0606601
2008/12/12(金) 09:46:03でもオーバーフローするif文も書けるんじゃなかったんですか?
0607601
2008/12/12(金) 09:50:20pass[10] = 60 のときでも if文がなぜか false になってしまいます。
if(pass[10] * 62 * 62 * 62 * 62 +
pass[11] * 62 * 62 * 62 +
pass[12] * 62 * 62 +
pass[13] * 62 +
pass[14] > 99999) pass[now_i]--;
0608デフォルトの名無しさん
2008/12/12(金) 10:08:1162^ 4= 14776336
62^ 9= 13537086546263552
62^ 13= 200028539268669788905472
0609デフォルトの名無しさん
2008/12/12(金) 10:12:39プロジェクトにファイルを追加するのが複数人いるってそんなに珍しいことか?
うちはロックするようにして回避してる。
>>607
うちではtrueになるよ。
0610デフォルトの名無しさん
2008/12/12(金) 10:53:05if((最大値-進数) < 前の桁までの合計値 ) && (新しい桁の数値 > (最大値-前の桁までの合計値))
{
//オーバーフロー処理
}
あってるかどうかは試してないから分からんが方向性はこんなんのはず
オーバーフローする直前のタイミングを捕まえて、本当にオーバーフローするかどうかを「オーバーフローさせないで」判定する
0611デフォルトの名無しさん
2008/12/12(金) 12:01:54なるほど!!!式変形すれば良かっただけでしたか。
その方針でプログラミングしてみます。
0612デフォルトの名無しさん
2008/12/12(金) 12:04:52あと、unsignedなら42億じゃないかと思う。
0613デフォルトの名無しさん
2008/12/12(金) 12:20:51うちの環境では unsigned u; と定義した変数が21億までしか持てませんでした
あとなぜかオーバーフローしたら負の値になりました。
0614613
2008/12/12(金) 12:28:28unsignedの最大値は42億かもしれません。
0615デフォルトの名無しさん
2008/12/12(金) 12:51:040616デフォルトの名無しさん
2008/12/12(金) 13:15:050617デフォルトの名無しさん
2008/12/12(金) 14:26:47約9.6桁。
0618デフォルトの名無しさん
2008/12/12(金) 14:32:32unsignedが負になるわけないだろ
どうみてもsigned longの値
0619デフォルトの名無しさん
2008/12/12(金) 15:01:480620デフォルトの名無しさん
2008/12/12(金) 18:58:41int NUM = 100; グローバル変数
int func(){
NUMを使う
}
とするのと
int func(int NUM){
}
int main(){
int NUM =100;
func(NUM);
}
では実行速度かわりますかね??funcを1000回ぐらい呼び出すんですが・・・
0621デフォルトの名無しさん
2008/12/12(金) 19:06:30って思ってるのであれば全く問題ない最適化の対象だからうまいことやってくれる
つか高々1000回かよwwwwwww
0622デフォルトの名無しさん
2008/12/12(金) 19:30:09余分な命令が実行されるので、実行速度は確実に変わる。
でも1000回なら誤差の範囲。
0623デフォルトの名無しさん
2008/12/12(金) 19:37:18嘘をいうな
ためしてみろよ
0624デフォルトの名無しさん
2008/12/12(金) 19:50:08前者
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
call func
leave
ret
0625デフォルトの名無しさん
2008/12/12(金) 19:50:51後者
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
movl $100, -4(%ebp)
pushl -4(%ebp)
call func
addl $4, %esp
leave
ret
0626デフォルトの名無しさん
2008/12/12(金) 19:52:05>>625
それがわかるんなら話は早いな
最適化かけてから見直せ
0627デフォルトの名無しさん
2008/12/12(金) 20:06:17前者
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
subl $16, %esp
call func
leave
後者
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
subl $28, %esp
pushl $100
call func
leave
ret
0629デフォルトの名無しさん
2008/12/12(金) 20:43:270630デフォルトの名無しさん
2008/12/12(金) 22:23:16おい、こら。自信満々に難癖つけといて、無言で逃亡か?
0631デフォルトの名無しさん
2008/12/12(金) 23:54:45今時のコンパイラなら、func()をインライン展開してしまうからイミディエイトプッシュのコストは消えるだろうね。
つーか、速度気にしてグローバル変数使う前に、func()にstaticつけておけよ。
0632デフォルトの名無しさん
2008/12/13(土) 00:31:14コンパイラが頑張っても、引数をレジスタに乗っけるコードは余計に必要。見苦しいぞ。
「私が未熟でした。ごめんなさい」くらい言えんのか。
static云々は>>620に言え。本当にstaticが不要なのかは>>620じゃなきゃわからん。
0633631
2008/12/13(土) 00:37:07見苦しいも何も、この話題に乗るのは>631が初めてだけど。
レジスタに乗せるコードは要るかなぁ。少なくとも、グローバル変数を取ってくるよりはコスト掛からないよ。
0634デフォルトの名無しさん
2008/12/13(土) 00:47:26グローバル変数だとマルチスレッドとか考慮して都度メモリにアクセスするコードを出すから、
頻繁にグローバル変数へアクセスするコードは遅いって聞いたことがある。
0635デフォルトの名無しさん
2008/12/13(土) 00:49:28グローバルから取ってくるのと同じコストはかかる。
0636デフォルトの名無しさん
2008/12/13(土) 08:19:04それはあるね。global 変数は volatile が付いているのと
同様に最適化されなくなる
>>620には関係ない話だけど
0637デフォルトの名無しさん
2008/12/13(土) 12:00:00volatileついてないグローバル変数の最適化を行わないコンパイラなんて聞いたことないな。
伝聞でなくソースだせ。
ついていない場合、最適化をできるとしている文書(あんたらの主張の逆)
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0205hj/CJAEGDEA.html
一方、変数が volatile として宣言されていない場合、コンパイラはその値を実装の外部で変更できない
ものと見なすことができます。 そのため、コンパイラは変数に対する最適化を実行できます。
0638デフォルトの名無しさん
2008/12/13(土) 14:18:110639デフォルトの名無しさん
2008/12/13(土) 14:46:240640デフォルトの名無しさん
2008/12/13(土) 23:29:00逆にこっちは、グローバル変数ではなくメンバ変数だけど、
いずれにせよ自動変数との差が出るという話。
http://www.emit.jp/prog/prog_opt0.html
0641デフォルトの名無しさん
2008/12/14(日) 00:30:442 for(int j = 0; j < nSize; j++) pBuffer[j] = i;
1はグローバル変数、2は自動変数
0642デフォルトの名無しさん
2008/12/14(日) 15:44:45いわゆる生産者消費者問題(有限バッファ問題)です。
生産者スレッド
do {
pthread_mutex_lock(&lock);
share_buf_num = read(fd, prod_buf, SHARE_BUFSIZE);
strncpy(share_buf, prod_buf, share_buf_num);
pthread_mutex_unlock(&lock);
} while (share_buf_num != 0);
消費者スレッド
do {
pthread_mutex_lock(&lock);
strncpy(cons_buf, share_buf, share_buf_num);
write(fd, cons_buf, SHARE_BUFSIZE);
pthread_mutex_unlock(&lock);
} while (share_buf_num != 0); // do {
share_bufが共有バッファ、SHARE_BUFSIZEがそのサイズ
生産者でデータをリードしている間は消費者は待っており、
そのあと消費者がライトしている間は生産者が待つ
という動作を期待してるんですが、生産者のみがループし続けて
ループを抜けたあとに消費者スレッドが動くという挙動を起こします。
何が原因なのでしょうか。
gcc 4.3.2, Ubuntu8.10(仮想マシン上)です。
0643デフォルトの名無しさん
2008/12/14(日) 16:04:530644デフォルトの名無しさん
2008/12/14(日) 16:16:070645デフォルトの名無しさん
2008/12/14(日) 18:14:40#include <stdio.h>
void main()
{
ULARGE_INTEGER h1;
ULARGE_INTEGER h2;
ULARGE_INTEGER h3;
GetDiskFreeSpaceEx( NULL, &h1, &h2, &h3 );
printf( "h1.QuadPart: %llu\n", h1.QuadPart );
LONGLONG i = h1.QuadPart;
printf( "%llu\n", i );
// h1.QuadPart = 16928739328
// h1.LowPart = 4043837440
// h1.HighPart = 3
}
上記のように空き容量を表示したいのですが
printfを使ってますがその値は h1.QuadPart の値ではなく
h1.LowPart の値が表示されます
これはどういうことでしょうか?
0646645
2008/12/14(日) 18:24:33OSは WindowsXP Home Edition です
0647デフォルトの名無しさん
2008/12/14(日) 19:48:30%lld
0648645
2008/12/14(日) 19:55:58解決しました
0650デフォルトの名無しさん
2008/12/14(日) 20:03:130651デフォルトの名無しさん
2008/12/14(日) 20:36:25main(){
int c,i;
int n[2];
for(i=0; i<2; i++){
printf("%d",i+1);
while((c=getchar()) != '\n'){
if(c >= '0' && c <='9'){
c = c - '0';
n[i] = n[i] * 10 + c;
}else{
/* 終了 */
}
}
}
printf("%d + %d = %d",n[0],n[1],n[0] + n[1]);
return 0;
}
getchar関数を使った足し算を作成したのですが2つの数字を入れてみたところ、
n[1]の値だけ入力した値と異なった値(正の整数が負の整数に、値もめちゃくちゃ)がでてしましました。
どこを改善したらいいか分かりません。アドバイスお願いします。
また、コメントの終了部分に文字が入った場合その場で終了という感じでreturn0を入れたのですが、
1つめを入力したあと終了せずに2つめまで行ってしまいます。これについても終了できる関数かなにかを教えてください。
コンパイラはgccです。
0652デフォルトの名無しさん
2008/12/14(日) 20:44:48getchar()では一桁だけしか入力できないしエラー処理も厄介だから、
fgets()で1行入力してからじっくり解析する方がいいと思う。
が、それ以前に状況をもっと的確に説明できないもんかね。
0653デフォルトの名無しさん
2008/12/14(日) 21:30:31俺は初心者だが、最近fgetsを入力として使うのがリーズナブルだなと思った。
ただ、fgetsをキーボード入力として使うとバッファが残っちゃうのでそれを消す機能を付けた自作関数を使うといいと思う。
ttp://ja.wikipedia.org/wiki/fgets
char *fgetsStdin(char *s, int n){
char *temp = fgets(s, n, stdin);
if(temp == NULL){
/* エラー処理(初心者なのでわかりません) */
}
if(strchr(s,'\n') != NULL){
s[strlen(s)-1] = '\0';
}else{
while(getchar() != '\r');
}
return temp;
}
0654デフォルトの名無しさん
2008/12/15(月) 04:40:37#include<string.h>
typedef struct{
int a;
char name[100];
int b;
int c;
}stringx;
int main(void)
{
int i;
stringx str[5];
for(i = 0;i < 5;i++){
printf("a:");scanf("%d", str[i].a);
printf("name:");fgets(str[i].name, 100, stdin);
printf("b:");scanf("%d", str[i].b);
以下略
これでnameのところに空白も読み込める文字列を入力したいんですが
(実行例)
a:1
name:b:2
と、何故かnameの入力自体がスルーされてしまいます
ちなみにscanfに終了判定を付けたものやgetsでも同じようにスルーされます
何処がいけないのでしょう
コンパイラはgccです
0655デフォルトの名無しさん
2008/12/15(月) 04:46:16'1'、'\n'
初回のscanf()の消費した文字:
'1'
入力に残った文字:
'\n'
fgets()は、この残っている改行文字を拾ってしまう。
結論:
scanf()とfgets()を混ぜるのは難しい。
対策:
・初回のscanf()のフォーマットを"%d "にする。
・初回のscanf()をfgets()とatoi()(或いはstrtol())に置き換える。
0656デフォルトの名無しさん
2008/12/15(月) 12:08:11たぶん2つのスレッドが交互に動くことを期待しているのだろうけど、そのような保証はまったくない
lock〜unlockはその範囲内が同時に実行されないことを保証するだけ
unlockから抜けてもすぐにスレッドが切り替わるわけではないし (通常はそのまま走り続ける)、
もう一方のスレッドがずっとlock待ちをしていたのだといても、次に中に入るのがどっちのスレッドになるかは運任せ
(今まで寝てた方のスレッドよりも走り続けてるスレッドの方が先に入る可能性が高いかもしれない)
2つのスレッドが交互に動いて欲しいなら、交互に動くよう確実にプログラムしなければならない
条件変数の使い方を覚えるといいよ
0657デフォルトの名無しさん
2008/12/15(月) 22:52:00#include<stdio.h>
#include<string.h>
typedef struct{
int a;
char name[100];
int b;
int c;
}stringx;
int main(void)
{
int i;
stringx str[5];
char buff[100];
char *p;
for(i = 0;i < 5;i++){
printf("a:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].a);
printf("name:");fgets(buff, 100, stdin);
if(p = strchr(buff,'\n'))
*p = '\0';
strcpy(str[i].name,buff);
printf("b:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].b);
printf("c:");fgets(buff,100,stdin);sscanf(buff,"%d", &str[i].c);
}
0658デフォルトの名無しさん
2008/12/16(火) 01:06:02char *msg_filename; // メッセージ定義ファイル名
int msg_number; // メッセージ番号
{
int i;
}
2,3行目は何を表しているの?引数の型の定義?
0659デフォルトの名無しさん
2008/12/16(火) 01:14:230660デフォルトの名無しさん
2008/12/16(火) 17:34:15while(x!=0){
y=rand()%100000;
if(array[y]==0) x=0;
}
これだと配列の中身が0の物が1つしかなかったら特定に膨大な時間がかかるよね
何かいい方法ないですか?
0661デフォルトの名無しさん
2008/12/16(火) 17:39:420662デフォルトの名無しさん
2008/12/16(火) 17:40:220663デフォルトの名無しさん
2008/12/16(火) 17:41:34そのコード、ランダムに1つ要素選んで、それが0でないか調べるとなっていて、
文章に書いてあることとやっていることの順番が違うぞ。
0664デフォルトの名無しさん
2008/12/16(火) 17:53:29こんなかんじ?
j=0
for(i=0;i<100000;i++){
if(array[i]==0)array2[j]=array[i];j++;
}
y=rand()% j;
array2[y]=〜〜〜〜;
0665デフォルトの名無しさん
2008/12/17(水) 05:17:050666デフォルトの名無しさん
2008/12/17(水) 05:17:540667デフォルトの名無しさん
2008/12/17(水) 08:20:09array2 は全部0
0668デフォルトの名無しさん
2008/12/17(水) 10:46:13なるほど、ありがとうございました
0669デフォルトの名無しさん
2008/12/18(木) 08:15:06#include "stdafx.h"
#include <windows.h>
#include <locate.h>
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR message[256];
setlocale(LC_ALL, "japanese");
lstrcpy( message, _TEXT("Hello world.\n") );
printf_s( "%s\n", message );
return 0;
}
として実行するのですが、printf_s では H しか表示されないのですが、
どうすれば Hello world. と表示されるのでしょうか?
コンパイラはVC++ 2008 Express です
0670669
2008/12/18(木) 08:27:380671デフォルトの名無しさん
2008/12/18(木) 08:31:03_tprintf_s( _TEXT("%s\n"), message );
0672デフォルトの名無しさん
2008/12/18(木) 14:38:06コピー後のバッファーにNULL文字が入りません。
どのようにしたら、NULL文字を入れることができるでしょうか?
0673デフォルトの名無しさん
2008/12/18(木) 14:53:54普通に書いたら0もコピーされる
お前がよっぽど変なプログラム書いたとしか思えない
0674デフォルトの名無しさん
2008/12/18(木) 14:55:21strcpyのかわりにmemcpy使え。 ちゃんと文字数も渡すんだぞ。
0675デフォルトの名無しさん
2008/12/18(木) 16:41:23簡略化した奴をちょっと書いてみるんだが
ランダムに配列から数字を引っこ抜く関数を二回呼び出してるんだけど、それが必ず同じ値を引っ張ってくる
なんでだ???
int array[50]={1,2,3,…,48,49,50};
int randomNumber(int x){
return array[(int)((rand() / ((double)RAND_MAX+1.0f)) * x)];
}
void main(void){
int a,b;
srand(time(NULL));
a=randomNumber(50);
b=randomNumber(50);
if(a==b){
printf("同じだよ");
}
}
0676デフォルトの名無しさん
2008/12/18(木) 16:46:56time(NULL)は1秒以内なら同じ数値を返すから1秒以内なら同じで当然。
そもそもsrandを毎回呼ぶ必要はない。
0677デフォルトの名無しさん
2008/12/18(木) 16:49:11数字表示させてみて。全部0じゃないのそれ?
0678デフォルトの名無しさん
2008/12/18(木) 16:49:56srand(time(NULL));を消してやってみたけど同じ値がでてくるよ!
0679デフォルトの名無しさん
2008/12/18(木) 16:57:500680デフォルトの名無しさん
2008/12/18(木) 16:58:530681デフォルトの名無しさん
2008/12/18(木) 17:08:4350が返る可能性はないと思うが
0682デフォルトの名無しさん
2008/12/18(木) 17:12:07この部分は 0 〜 1に満たない範囲で値になるので、1にならない以上
50にはならないから大丈夫。
0683デフォルトの名無しさん
2008/12/18(木) 17:54:410684デフォルトの名無しさん
2008/12/18(木) 17:57:340685デフォルトの名無しさん
2008/12/18(木) 18:03:07それに50を掛けても、50に近い値にはなるが、50には満たない。
その値の整数部分をとっているわけだし。
0686デフォルトの名無しさん
2008/12/18(木) 18:08:47↑
int array[50]={1,2,3,…,48,49,50};
0687デフォルトの名無しさん
2008/12/18(木) 18:52:010688デフォルトの名無しさん
2008/12/18(木) 19:00:21クラスをベクタコンテナで宣言してvt.at(i).swap(vt.at(i+1))みたいなアルゴリズムを考えています。
0689デフォルトの名無しさん
2008/12/18(木) 19:03:460690デフォルトの名無しさん
2008/12/18(木) 19:14:560691688
2008/12/18(木) 19:28:45どういう意味ですか?
vt1.swap(vt2)
で
temp=vt1,vt1=vt2,vt2=tempになるのは解るんですが
vt.at(i)とvt.at(k)のスワップ方法が解らないんです。
0692デフォルトの名無しさん
2008/12/18(木) 19:37:20std::swap(vt.at(i), vt.at(k));
0694デフォルトの名無しさん
2008/12/19(金) 00:21:53初心者にお勧めのサイトとか教えてください#
0695デフォルトの名無しさん
2008/12/19(金) 00:24:24ぼうようはどうよう?
0696デフォルトの名無しさん
2008/12/19(金) 00:32:24初心者なら素直に本を一冊買った方がいいと思うなぁ…
■ このスレッドは過去ログ倉庫に格納されています