C言語なら俺に聞け(入門篇) Part 32
■ このスレッドは過去ログ倉庫に格納されています
0001処理系定義の名無しさん
2008/07/09(水) 11:00:48教えて欲しいのではなく宿題を丸投げしたいだけなら宿題スレへ行ってください。
C/C++の宿題を片付けます 110代目
http://pc11.2ch.net/test/read.cgi/tech/1213796455/
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・開発環境や動作環境も晒すと答えが早いかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。
前スレ
C言語なら俺に聞け(入門篇) Part 31
http://pc11.2ch.net/test/read.cgi/tech/1214569903/
過去スレ
http://makimo.to:8000/cgi-bin/search/search.cgi?q=%82b%8C%BE%8C%EA%82%C8%82%E7%89%B4%82%C9%95%B7%82%AF&andor=AND&sf=0&H=&view=table&D=tech&shw=5000
0232デフォルトの名無しさん
2008/07/12(土) 02:00:32ここ
http://pc11.2ch.net/test/read.cgi/tech/1215348804/
0233デフォルトの名無しさん
2008/07/12(土) 02:01:47すみません。ありがとうございます
0234デフォルトの名無しさん
2008/07/12(土) 02:19:41そこちゃうやろ
0235デフォルトの名無しさん
2008/07/12(土) 15:20:44void func(void)
{
int B;
for (10000000回繰り返し) A = 9999;
for (10000000回繰り返し) B = 9999;
}
変数AとBでアクセス速度に違いがあるかどうか教えてください。
0236デフォルトの名無しさん
2008/07/12(土) 15:28:45システムによって違うので、実際に測定しないとわからない。
↑というのが前提で。
最適化がまったくなかったら、グローバル変数のほうが速い場合がおおいような気がするけど、
いまどきローカル変数をレジスタに割り当てるとか当たり前だからBのほうが速いかもしれない。
0237デフォルトの名無しさん
2008/07/12(土) 15:49:15今時の最適化は、ループ自体が無くなる、は置いといて。
グローバルも、最適化ではレジスタ割り当ても有る。
優先順位としてはBの方が高いと思うけどね。
ではレジスター割り当てが出来ない場合は、Aがじか引き
Bはスタックエリアのインデックス引きでBが遅いかもしれない。
プログラムのアセンブルリストを見るのが一番速い
0238デフォルトの名無しさん
2008/07/12(土) 16:09:000239デフォルトの名無しさん
2008/07/12(土) 16:10:020240235
2008/07/12(土) 16:13:02//void msgbox(char *string, char *title = "msgbox") { MessageBox(NULL, string, title, NULL); }
LARGE_INTEGER Frequency;
QueryPerformanceFrequency(&Frequency);
LARGE_INTEGER pcBef, pcAft;
LONGLONG ll1, ll2;
QueryPerformanceCounter(&pcBef);
fori (1000000) A = 9999;
QueryPerformanceCounter(&pcAft);
ll1 = pcAft.QuadPart - pcBef.QuadPart;
QueryPerformanceCounter(&pcBef);
fori (1000000) B = 9999;
QueryPerformanceCounter(&pcAft);
ll2 = pcAft.QuadPart - pcBef.QuadPart;
sprintf(g_, "%f", (double)ll1 / (double)Frequency.QuadPart);
msgbox(g_);
sprintf(g_, "%f", (double)ll2 / (double)Frequency.QuadPart);
msgbox(g_);
測定の仕方ってこれであってます?
両方ともかかる時間は0.0024秒付近でした。
最適化ありだとほとんど変わらないぽいですね。
0241235
2008/07/12(土) 16:43:21代入による負荷は限りなく低くて無視できるようですね…
0242デフォルトの名無しさん
2008/07/12(土) 16:43:29大体の目安にはなるかもしれないけどソース埋め込みだとレジスタに置かれてたのがスタックに置かれたりして厳密な測定値は得られない
デバッガにブレークポイントからブレークポイントまでの時間を測る機能はないの?
0243デフォルトの名無しさん
2008/07/12(土) 16:47:33VC2008だけどあるかなぁ・・・
0244デフォルトの名無しさん
2008/07/12(土) 17:53:09意味のないループは最適化されやすい。
0245デフォルトの名無しさん
2008/07/12(土) 18:02:46命令の並列化とかメモリキャッシュの具合で差が出るかもしれない。
c7 05 00 00 00 00 0f 27 00 00
mov DWORD PTR ?A@@3HA, 9999 ; A, 0000270fH
c7 45 fc 0f 27 00 00
mov DWORD PTR _B$[ebp], 9999 ; 0000270fH
0246デフォルトの名無しさん
2008/07/12(土) 18:05:49; 7 : for (int i = 0; i <10000000; i++) A = 9999;
mov DWORD PTR ?A@@3HA, 9999 ; A, 0000270fH
; 8 : for (int i = 0; i <10000000; i++) B = 9999;
; 9 : }
ret 0
0247デフォルトの名無しさん
2008/07/12(土) 18:20:460248デフォルトの名無しさん
2008/07/12(土) 18:23:400249デフォルトの名無しさん
2008/07/12(土) 18:33:36ごめん、242は組み込みおじさんなんで自分の感覚で書いてしまった
MSDNのヘルプ見たけどVCではコード埋め込むのが一般的なのかな?
プロファイラが別途必要なのか、VCは疎いのでわからない
0250デフォルトの名無しさん
2008/07/12(土) 18:46:150251デフォルトの名無しさん
2008/07/12(土) 18:48:16int width, height;
int depth;
void* pixels;
} ImageData;
という構造体の宣言があってこの後のプログラムで
ImageData が型の名前として使われているようなんですがどういうことですか?
型として使うなら STRUCT_IMAGE だと思うんですが。
0252デフォルトの名無しさん
2008/07/12(土) 18:58:46って書くのめんどくさいじゃん?
0253デフォルトの名無しさん
2008/07/12(土) 18:58:48typedefしてるじゃん。
0255デフォルトの名無しさん
2008/07/12(土) 20:01:40volatileつけてみたら変わるかな?
0256デフォルトの名無しさん
2008/07/12(土) 20:10:37void main(){
int i;
int a[10];
for(i=0;i<10;i++){
scanf("%d",&a[i]);
if(入力側で改行があったら) break;
}
}
scanfで、次の要素に移るときは基本的にスペース、もし改行があったらそこでループを抜けるプログラムを書きたいのですが、
breakの条件文がわかりません・・・。
もし、適当な条件文があるなら教えていただけないでしょうか。
0257デフォルトの名無しさん
2008/07/12(土) 20:15:360258デフォルトの名無しさん
2008/07/12(土) 20:20:300259デフォルトの名無しさん
2008/07/12(土) 20:39:28ん〜今やってみましたが、改行してもscanfが終了しませんでした…
俺がscanfの仕様をよくわかってないのもあるかもしれません。
ちょっと>>256のだと語弊があることを懸念して、
「ループを利用して配列に数字を入力中、改行するとすぐさまそこで文字入力を終了する」
ということです。
…ひょっとするととんだ見当違いなプログラムを書いてしまったかも…
0260デフォルトの名無しさん
2008/07/12(土) 21:22:210261デフォルトの名無しさん
2008/07/12(土) 21:35:570262デフォルトの名無しさん
2008/07/12(土) 21:40:30わかりました。終わるときは何か他の文字を入力してもらうことにします。
ありがとうございました!
0263デフォルトの名無しさん
2008/07/12(土) 22:48:110264デフォルトの名無しさん
2008/07/12(土) 22:50:46オープンした直後なら最初のバイト。
二回目の実行なら二つ目のバイト。
0265デフォルトの名無しさん
2008/07/12(土) 22:51:29一回目は先頭
二回目は2バイト目
三回目は3バイト目
・・・
0266デフォルトの名無しさん
2008/07/12(土) 22:58:250268デフォルトの名無しさん
2008/07/12(土) 23:12:140269デフォルトの名無しさん
2008/07/12(土) 23:20:53分かりました。
ありがとうございました。
0270デフォルトの名無しさん
2008/07/12(土) 23:50:05char initial[15];
char name[15];
printf("苗字を記入\n");
scanf("%s",&initial);
printf("名前を記入\n");
scanf("%s",&name);
で、苗字と名前を記入するプログラムの練習をしてるのですが
このプログラムだと苗字、名前15文字までしか入れることができません。
で、if else をつかって16文字以上入力した場合には
「名前が長すぎる」とprintfで持ってきたいのですが、どうしてもできません。
なにかヒントみたいなものでも良いのでどなたか助言いただけないでしょうか?
0271デフォルトの名無しさん
2008/07/12(土) 23:51:300272デフォルトの名無しさん
2008/07/12(土) 23:52:33scanfのかわりにfgetsを使う
0273デフォルトの名無しさん
2008/07/12(土) 23:55:10char name[100];
while(true)
{
printf("苗字を記入\n");
scanf("%s",&initial);
if(strlen(initial)>0 && strlen(initial)<15) break;
printf("入力が長すぎます\n");
}
while(true)
{
printf("名前を記入\n");
scanf("%s",&name);
if(strlen(name)>0 && strlen(name)<15) break;
printf("入力が長すぎます\n");
}
0274デフォルトの名無しさん
2008/07/12(土) 23:59:09ヒントありがとうです
さっそく違う方法でやってみるです。
0275デフォルトの名無しさん
2008/07/13(日) 00:00:10while(0) {
printf("*");
}
このプログラムを実行したとき*は幾つ表示されるかが分かりません
実行してみたんですがエラーが出てしまいます orz
0276デフォルトの名無しさん
2008/07/13(日) 00:01:25何も表示されないだけかな
0277デフォルトの名無しさん
2008/07/13(日) 00:09:32ありがとうございますm(__)m
エラーが出ないように何回かいろんなところいじってみますorz
0278デフォルトの名無しさん
2008/07/13(日) 00:15:310279デフォルトの名無しさん
2008/07/13(日) 00:16:37○scanf("%s",initial);
0280デフォルトの名無しさん
2008/07/13(日) 00:18:39それはどっちでもいいんじゃね?
0281デフォルトの名無しさん
2008/07/13(日) 00:26:120282デフォルトの名無しさん
2008/07/13(日) 00:27:10今、試行繰り返してますが
どちらでも動くみたいです。
>>273のおかげでなんとかエラーなしで動くようになったので
これからプログラムの流れの解読開始します
0283デフォルトの名無しさん
2008/07/13(日) 00:29:40分かってるのか?って思う
0284デフォルトの名無しさん
2008/07/13(日) 00:34:32あんまりきれいではないよね
0285デフォルトの名無しさん
2008/07/13(日) 00:50:12ならない。
配列に&演算子を作用させたときに得られるポインタは配列へのポインタであって、
配列の先頭要素へのポインタではない。
memset() などでは、配列の先頭要素へのポインタを与えても、配列へのポインタを与えても、正当に動く。
なぜなら memset() の引数が void * と定義されているために、コンパイラが暗黙に適切な型変換を行うからである。
一方、可変個数の引数を取る printf() や scanf() では、そのような暗黙の変換は行われない。
scanf() で %s を指定した場合に与えるポインタは char へのポインタでなければならない。
ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても
(渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
しかしそれは規格が保証した動作ではない。
0286デフォルトの名無しさん
2008/07/13(日) 00:56:11(あるいはつい同一視してしまって)&演算子をつけて printf() や scanf() に渡してしまうことがある。
これはどんなマシンであっても、たぶん動かない。
0287デフォルトの名無しさん
2008/07/13(日) 01:05:39printf("name=0x%x &name=0x%x\n", name, &name);
で、両方とも同じ値なのはなぜ?
0288デフォルトの名無しさん
2008/07/13(日) 01:27:44そのようにしたとき、&nameが配列の参照からポインタに成り下がるため、先頭アドレスが表示される
0289デフォルトの名無しさん
2008/07/13(日) 01:28:54|ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても
|(渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
0290デフォルトの名無しさん
2008/07/13(日) 01:53:30違うw
配列のアドレスと配列の先頭アドレスが一致するからだ。
0291デフォルトの名無しさん
2008/07/13(日) 02:05:01同じ値になるんだな
知らなかった
0292デフォルトの名無しさん
2008/07/13(日) 02:05:540293デフォルトの名無しさん
2008/07/13(日) 02:15:06&nameと配列の参照を取得した時点で、それは先頭要素を指すポインタに変わると思ってたが、違うのかな
0294デフォルトの名無しさん
2008/07/13(日) 02:23:44&nameは配列全体へのポインタになる
&name[0]はまずname[0]が結合し次に&だから先頭要素へのポインタから0番目の要素へのポインタ=先頭要素へのポインタ
たいてーの処理系では値としてはまったく同じものでコンパイラが型チェックすることがあるだけ
でももちろんそうでない処理系もあるかもしれないということになる(C規格の上では)
%pに渡すポインタも、void*にキャストする必要があるかどうかは処理系定義じゃなかったかな
0295デフォルトの名無しさん
2008/07/13(日) 02:24:02というのがあって、aは0x10000とする。
aは当然0x10000なのだが、&aは?
&をアドレスを求める演算子と考えれば、aはもともとアドレスなので&aはaの値をそのまま返す。
ということではないのかな?
0296デフォルトの名無しさん
2008/07/13(日) 02:24:46> ポインタのサイズや内部表現が同じ処理系においては、配列へのポインタを与えても
> (渡される値が、型は異なっても実際には同じバイナリ列であるために)たまたま動く。
> しかしそれは規格が保証した動作ではない。
規格上は指す型によってポインタのサイズや内部表現が違ってもよいのですね
指すのが構造体の場合も、指す構造体によって
やはりサイズや内部表現が異なる可能性がありますでしょうか・・・?
継承っぽい動作の実装で構造体へのポインタを異なる構造体へのポインタに
キャストしてるもので。
0297デフォルトの名無しさん
2008/07/13(日) 02:26:11p が 0x10000とした場合、
&pはpがもともとアドレスにもかかわらず、pと&pは異なる値になるよ
0298デフォルトの名無しさん
2008/07/13(日) 02:28:07ちがいます。
aは&演算子のオペランドでない場合は&aになる。
0299デフォルトの名無しさん
2008/07/13(日) 02:28:09> すべてのCコンパイラで配列への(キャストのない)参照はポインターを産み出す。このポインターはTへのポインターで配列の最初の要素を指す
これについてはどう思いますかね
0300デフォルトの名無しさん
2008/07/13(日) 02:28:51逆じゃね?
&a は配列aのアドレスを返す
aは配列だが添え字とか&がなければ配列のアドレスを返す
0301デフォルトの名無しさん
2008/07/13(日) 02:33:16違うよ
aはもともとはアドレスじゃなくて識別子つまり配列そのもの
いくつかの例外(&aを含む)を除いてアドレスに変換されるけど
あとアドレス演算子とは呼ばれているけど、実際に&演算子が生み出すのはポインタ
Cのポインタは「アドレス」と「型」が一緒になった概念
ほとんどのコンパイラは前者だけを変数に保存してコンパイラだけが後者を管理するから
出力すれば同じものに見えるけどね
0302デフォルトの名無しさん
2008/07/13(日) 02:34:33構造体レベルだとたぶん変わらない
関数ポインタになると変わってくる
0303デフォルトの名無しさん
2008/07/13(日) 02:37:05どう思いますかねって何もおかしくないでしょ
そこには書いてない例外の部分もちゃんと含めてだけど
0304デフォルトの名無しさん
2008/07/13(日) 02:38:13さんくす
そうだよな、構造体は仮宣言でもポインタで取り回せるし
(それも規格に合ってるのか知らんけど)
0305デフォルトの名無しさん
2008/07/13(日) 02:40:58キャストするぶんにはそのへんコンパイラがちゃんとやってくれることになっている
0306デフォルトの名無しさん
2008/07/13(日) 12:25:41じゃあ、
char str[10];
scanf("%s",&str);
って書いた方が本来の意味として正しいってこと?
0307デフォルトの名無しさん
2008/07/13(日) 12:30:290308デフォルトの名無しさん
2008/07/13(日) 12:37:450309デフォルトの名無しさん
2008/07/13(日) 12:39:10int *p = dm;
int (*p2)[10] = &dm;
0310デフォルトの名無しさん
2008/07/13(日) 12:58:24&配列名 は当面使わなくてOK、な。
0311デフォルトの名無しさん
2008/07/13(日) 16:35:43だれかボタンを表示する方法を教えて下さい。
0312デフォルトの名無しさん
2008/07/13(日) 16:37:08TKでいいのか?
0313デフォルトの名無しさん
2008/07/13(日) 16:37:21↓
http://www.kumei.ne.jp/c_lang/sdk/sdk_15.htm
0315デフォルトの名無しさん
2008/07/14(月) 06:08:580316デフォルトの名無しさん
2008/07/14(月) 14:45:26http://www.soi.wide.ad.jp/class/20020008/slides/04/index_23.html
0317デフォルトの名無しさん
2008/07/14(月) 14:46:240318316
2008/07/14(月) 14:47:43C言語のように単なる構造化の場合どうやるんだろ?
古典的なフローだとどうもGOTO使ってるぽくていやなんだが
0319デフォルトの名無しさん
2008/07/14(月) 15:01:15古典的フローチャートにもループ記述子が存在しているからそれを使えばOK。
つーか、そもそも構造をブロック化するだけじゃないかと思うが。
0320デフォルトの名無しさん
2008/07/14(月) 16:30:35右側の構造化チャートならgoto使うイメージ無いだろ。
0321デフォルトの名無しさん
2008/07/14(月) 16:55:33自分としては一つの方法として「標準出力をフックする」というのは思いついたのですが
難しそうなので半ば諦めかけています。
何か方法はありますか
0322デフォルトの名無しさん
2008/07/14(月) 16:58:43popen はどう?
0323デフォルトの名無しさん
2008/07/14(月) 17:06:51凄い、出来ました。
ありがとうございます
#include <stdio.h>
int main()
{
FILE *fp;
char buf[256];
fp = popen("ls", "r");
while(!feof(fp))
printf("%s", fgets(buf, 256, fp));
return 0;
}
0324デフォルトの名無しさん
2008/07/14(月) 17:09:14大抵の環境でpopen()が使えると思う。
0325デフォルトの名無しさん
2008/07/14(月) 17:10:32そうなんですか
windowsでも出来るんですね
cygwinのdllでも同封してun*xコマンドを駆使しつつ
両方で活用できるソフトを作る事も出来そうですね…
ありがとうございます
0326デフォルトの名無しさん
2008/07/14(月) 17:12:52VisualStudioなら_popen()かな。
0327デフォルトの名無しさん
2008/07/14(月) 17:17:04そうなんですか
ありがたいですm(_ _)m
0328デフォルトの名無しさん
2008/07/14(月) 17:35:17pclose 推奨
0329デフォルトの名無しさん
2008/07/14(月) 22:06:1310〜100番の要素を5〜95のように同サイズで重なる領域にコピーしたいんですが
こういう場合は一旦どこかに変数を保存しないと実現できないんでしょうか?
0330デフォルトの名無しさん
2008/07/14(月) 22:08:35memmove
0331デフォルトの名無しさん
2008/07/14(月) 22:09:10■ このスレッドは過去ログ倉庫に格納されています