あー、前スレ誘導リンクはPart 5だが、タイトルがPart 4になったままだorz
前スレの組合せのヤツ kaijoがs<0だと0しか帰ってこないのはおいといても、関数ncmもおかしいな kaijoを使うんなら int ncm(int n, int m){ return kaijo(n)/kaijo(m)/kaijo(n-m); } こうだろ。 書き方見る限り再帰で呼び出したいように見えるんだけど。 int ncm(int n, int m){ return (n==m || m==0) ? 1 : ncm(n-1,m-1) + ncm(n-1, m); } ついでに宿題スレにあった別パターンの再帰 int ncm(int n, int m){ return m==0 ? 1 : ncm(n, m-1) * (n-m+1) / m; }
俺としては間違って、n < m と入力してしまった時には きちんとエラーを吐き出すようにして欲しいものだな。
今更何を言うか
>>6 宿題片付けるのと初心者の質問を答えてやるのでは趣旨が違うだろ?
D:\clang\bintori2>bcc32 bintori2.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
bintori2.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
Error: 外部シンボル '_janken' が未解決(D:\CLANG\BINTORI2\BINTORI2.OBJ が参照)
以前は問題なくコンパイル出来たのですがこんなエラーが出てコンパイル出来ません。
どこがおかしいのでしょうか?
一応ソースとobjファイルとtdsファイルです。
http://eggrice.no.land.to/up/src/tohoh0090.zip
何かテジャブな気がする… 今月の頭か先月見たような… そのjankenとやらを
>>9 つ bcc32 bintori2.c janken.c
ソースの中身までは見てないので、ちゃんと動くかどうかは知らん。
アッー
久しぶりだったのですっかり忘れてました(;´д`)
>>11 ありがとうございました。
>>10 参考書のソース改変しただけなので・・・
>アッー どう発音するんだ?
レス、声に出して読んでるの
あついち
16 :
デフォルトの名無しさん :2006/12/29(金) 14:40:17
struct hoge { int i,j,k; hoge(){} hoge(int _i, int _j, int _k){ i = _i;j = _j;k = _k; } }; void func() { int a,b,c; hoge* ph = 0; 〜略 for(〜){ ph[〜] = hoge(a,b,c); } } 上のようなプログラムを見たのですが、 構造体をnewもせずに突然hoge(a,b,c)とか書いていいのですか? 特にエラーも出ずにコンパイルできました。 これはどういうことでしょうか?
>>16 引数付きのコンストラクタを呼び出して 一時オブジェクトを作っている。
が、ここは 「C」スレ。 上記のやっていることは「C++」の範疇であり C では文法違反。
さまざまな整数が入った配列があるんですが そのなかで一番多く入ってる整数が何か知るというようなものを 書きたいのですがどうすれば? 一番多いというのは、たとえば13という整数が10個、9が5個入ってたら 13を取り出したいという意味です
>>17 C++の話しですか。すいませんでした。
一時オブジェクトというんですね。
ありがとうございました。
int i;
int ary1[NUM]={0};
int ary2[NUM]={0};
while(i=0;ary[i];i++){
if(ary1[i]==target){
ary2[i]++;
break;
}
}
if(ary2[i]==0){
ary1[i]=target;
ary2[i]++;
}
/*あとなんか総当りで比較*/
>>18 こんな感じじゃね?
ソートしてから比較したほうがよさそうな気がしてきたが、こういう方法もあるということで
typedef struct numcnt_tag { int num, cnt; struct numcnt_tag *next ,prev*; }numcnt; こういうのあったよね。 これでどうだ
>>19 C, C++ 両方をコンパイルできる環境だと、どっちでコンパイルされているかを意識する必要があるよ。
コンパイルできたからといって Cに適合しているとは限らないから。
#
>>16 で 「new もせずに」と書いているけど、C には new 演算子無いw
>>18 やり方はいろいろあると思うけど、とりあえず一例。
元の配列と同じサイズの領域を確保し、内容をコピー。
コピーした配列のほうをソート。
(元の配列の内容を更新可能なら、コピーせずそれを使ってよい。
ソートについてはqsort関数を使うか、ぐぐる。)
ソート済み配列を先頭から見ると、同じ数値は連続して固まって並んでいる。
最初に現れた数値がa, その個数をNaとすると、
val=a, num=Na
つぎに表れた数値bの個数を数え、それがNbとする。
Nb>numなら val=b, num=Nb
これを配列の最後まで繰り返す。
最終的にvalが求める値。
>>23 ビットマップの輝度のような(たかだか 0〜255) 整数でかつ値のとりえる範囲が極めて小さいときは
個数カウンタを値域分用意する って手段もありだね
>>前948さん 有難うございます。 マイナスが付いてたのが意味が分からなくて困ってました。。 (左詰ってことなんですね。。
なんか上に似てる質問でてる。。 配列の中身の数がもっとも大きい配列番号をしるには どうすればいいですか?
>>26 もっと具体的に。
単に最大値が欲しいのなら、単純なループで探すかソートして端を採るか。
>>27 単純なループより高速にソート完了できるアルゴリズムなんてあるか?
非難したり馬鹿にしたりしてるわけじゃなくて、興味本位なんだが
29 :
26 :2006/12/29(金) 16:57:41
array[0]→2,array[1]→13,array[0]→5だとしたら 中身の一番大きいarray[1]の配列番号1がほしいいんですが
30 :
27 :2006/12/29(金) 17:06:30
>>28 処理速度の問題ではなく、コーディング量の問題。
例えば最大値とその次も欲しいなんてことになったらどのみちソートする羽目になるしね。
31 :
デフォルトの名無しさん :2006/12/29(金) 18:43:05
"プログラミング作法"という Kernighan & Pike の本を買ったのですが、 その中の問題の答えがわからないのです。どなたかベストな方法を教えてください。 P.44 問題1-10 「潜在的な間違いを最小限に食い止めるには、次の定義をどのように書き直したらいいだろうか」 #define FT2METER 0.3048 #define METER2FT 3.28084 #define MI2FT 5280.0 #define MI2KM 1.609344 #define SQMI2SQKM 2.589988 整数型のマクロは enum にしたほうがよい、との記述がありました。 問題の主旨は、どうにかしてマクロを避けなさい、ということだと思うのですが。
>>31 一箇所だけ書くとこんな感じ
#define FT2METER (0.3048)
#define METER2FT (1/FT2METER)
>>31 #define FT2METER (0.3048)
#define MI2FT (5280.0)
#define METER2FT (1/FT2METER)
#define MI2KM (MI2FT*FT2METER/1000)
#define SQMI2SQKM (MI2KM*MI2KM)
違った orz この場合はこっちのほうが正解 #define METER2FT (3.28084) #define MI2FT (5280.0) #define FT2METER (1.0/METER2FT) #define MI2KM (MI2FT*FT2METER/1000.0) #define SQMI2SQKM (MI2KM*MI2KM)
しつこい
37 :
35 :2006/12/29(金) 20:07:59
自分でも答えられる数少ない質問だったから、うれしくてついやってしもた。スマソ
英文の書いたファイルを読み取って、英文に使われているアルファベットを それぞれ何回使われたか集計するプログラムを作りたいです。 txtファイルの入出力はできてるんですが アルファベットの数を分けるプログラムはどうすればいいですか? ちなみに問題文は fgets で文字列にデータを一行づつ読み込み, 文字列中の文字を一文字づつ 調べて出現回数を配列に記録することにより数えよ. 例えば, 配列を int count[26] とすると, 'a' の個数を count[0] で, 'b' の個数を count[1] で, …, 'z' の個数を count[25] で数えるようにすればよい. とのこと
>>39 >例えば, 配列を int count[26] とすると, 'a' の個数を count[0] で,
まれに見るクソ問題だ。学校名と担当教官を晒したら教えてやる。
ASCII前提。書き捨てだから必要なincludeとかは適当に。 main() { int count[26], i; char buf[128], c; for (i = 0; i < 26; i++) { count[i] = 0; } while(fgets(buf, sizeof(buf), STDIN)) { for (i = 0; c = buf[i]; i++) { if (isalpha(c)) { count[tolower(c) - 'a']++; } } } for (i = 0; i < 26; i++) { printf("%c: %d", i + 'a', count[i]); } return 0; }
31です。 やっぱり #define は使うのですね。 小数の場合でも文字列置換を使わない工夫があるのかと思ってました。
>>40 あなたにとってこの程度の問題すら難しくて解けない、と解釈します
これは痛い
>>41 count[26]={0}でおk
あとint main(void)にしとこうよ。
47 :
デフォルトの名無しさん :2006/12/30(土) 09:55:52
画像の走査がしたくて、 →X ↓一二三十・・ Y 四五六・・・ 七八九・・・ ・・・・・・ の順番で一から走査させたいのですが、アルゴリズムが思いつきません。 図がわかりにくくてすみません。 要は、3×3の配列ごとに画像の左上Xを増加させて、 右端までいったら、Yを1増加させて・・・と言う具合です。 ヒントだけでもいいので教えていただけたらと思います。 よろしくお願いします。
main(){ for(;;i++) for(;;j++) function(3i,3j); } function(int y,int x){ for(i=0;i<3;i++) for(j=0;j<3;j++) /* ary[y+i][x+j]が必要な要素 */ }
49 :
47 :2006/12/30(土) 10:02:23
3×3の走査をしたら、右へずれて十からまた3×3という具合です。 Yを1増加でなくて、3増加でした、すみません。
50 :
47 :2006/12/30(土) 10:07:39
<<48 ありがとうございます 早速試してみます。
>>50 レスアンカーのつけかたぐらい覚えれや
<<じゃなくて>>だ
右シフトか
53 :
デフォルトの名無しさん :2006/12/30(土) 13:42:13
昨日の26です。 なかなかうまい方法が見つからないので教えてもらえないでしょうか? array[0]→2,array[1]→13,array[0]→5だとしたら 中身の一番大きいarray[1]の配列番号1がほしいです こんな問題なんですが
>>53 技巧を凝らさないなら
max確保用に変数maxをセット、初期値をa[0]にしとく
添字確保用に変数max_numを用意、初期値を0にしとく
配列の数-1までループを回す。中身は→条件:a[i]とmaxを比較 a[i]の方が大きかった時 操作1:maxにa[i]を代入 操作2:max_numにiを代入
これじゃ駄目?
55 :
41 :2006/12/30(土) 15:03:02
56 :
デフォルトの名無しさん :2006/12/30(土) 15:32:44
>>53 #include <stdio.h>
int getmaxsuffix(int *a, int len);
int main(void){
int a[10] = {1, 2, 13, 4, 25, 6, 7, 8, 9, 10};
int i = getmaxsuffix(a, 10);
printf("%d\n",i);
}
int getmaxsuffix(int *a,int len){
int i;
int max = 0;
for (i = 1;i < len;i++){
if (a[max] < a[i]){
max = i;
}
}
return max;
}
58 :
39 :2006/12/31(日) 02:57:45
>>41 頑張って解読しようとしたけど、知らない関数多すぎで降参です。
fopenとか全く使ってないけど省略しただけなんでしょうか?
もっと簡単で理解できる範囲でアドバイスが欲しいんですが、
自分が何処までやっているのかをどう言えば分かってもらえるのか分からない。
59 :
39 :2006/12/31(日) 03:09:20
とりあえずスース貼ればいいか int main(void) { FILE *fpin,*fpout; char s[128]; if((fpin=fopen("aaa.txt","r"))==NULL) { printf("ファイルが見つかりません。---aaa.txt\n"); exit(EXIT_FAILURE); } while(fgets(string,STRING_SIZE,fpin)) { } if((fpout=fopen("aaaaa.txt","a"))==NULL) { printf("ファイルが作成できません。---aaaaa.txt\n"); exit(EXIT_FAILURE); } fclose(fpin); fclose(fpout); return EXIT_SUCCESS; } 自分で考えた分なんですがwhileの中身が全く分からないのと 他に間違い等あればお願いします。
>>59 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
FILE *fp = fopen("alpha.txt", "r");
if(fp == NULL){ return -1; }
int count[26], i;
char buf[128];
memset(count, 0, sizeof(count));
while(fgets(buf, sizeof(buf) - 1, fp)){
for(i = 0; i < strlen(buf); ++i){
if(isalpha(buf[i])){
++count[tolower(buf[i]) - 'a'];
}
}
}
fclose(fp);
for(i = 0; i < 26; ++i){
printf("%c: %d\n", i + 'a', count[i]);
}
return 0;
}
63 :
デフォルトの名無しさん :2006/12/31(日) 10:13:18
任意の数字をn乗する。 #include <stdio.h> long int nx;int ny = 1; int shisuu;int kaisuu; intmain(void){ printf("任意の数字(整数nx)をn乗します。\n整数を入力してください。\n"); printf("整数nx:"); scanf("%d",&nx); printf("整数shisuu:"); scanf("%d",&shisuu); for (kaisuu = 0; shisuu > kaisuu; kaisuu++) ny = ny * nx; if (shisuu > 0) printf("nx^%d = %d\n",shisuu,ny); else if (shisuu = 0) printf("nx^%d = 1\n",shisuu); else printf("nx^%d = 1 / %d\n",shisuu,ny); return (0); } ↑がソースファイル。 2番目のif文で”おそらく不正な代入”とされ、コンパイルできません。 どうすればいいでしょうか?あと、まだポインタは勉強してません。
shisuu = 0 → shisuu == 0
65 :
63 :2006/12/31(日) 10:25:08
>>61 配列の0クリアは初期化で済ませろ。
memset()は極力使うな。
fgets()の第2パラメータは配列サイズで充分。
ループの継続条件で毎回strlen()を呼ぶな。
main()から-1を戻すな。汎用性が失われる。
C99スタイルで書くならループ制御変数をループ外で宣言するな。
C++ならインクルードファイルの名前が違う。
C89ならエラーになる。
>>59 whileの継続条件がよくわからんってことだよな?
まずひとつ、C言語では偽を0、真をそれ以外の全ての数と定義している
で、whileは継続条件が偽でないときにループを続けるんだが、これは論理式でなくても構わない
つまり継続条件にある式の値が0でない限りループを続けることになる
今回の場合、継続条件となる値が関数fgets()の戻り値であることはいいと思う
だからfgets()が0を返さない限りループする
fgets()が0を返すタイミングを調べてみると、対象の文字列を全て読みきった時だ
よって、fpinから文字列を全部読み込むまでループする、といった感じだ
いくつか正しくない表現もあるけど、説明が長くなりそうだからとあえてそうしてるつもり
中身っていったら条件部じゃなくて、コードブロック内のことだろ。
おま、
while(fgets(string,STRING_SIZE,fpin))
{
}
これのどこを説明せよと
・・・こうかな?
>>59 while(1==1){
if(fgets(string,STRING_SIZE,fpin)==NULL)break;
}
これと同じ事を簡単に済ませています
NULLは、この場合0と等価と考えてもらって構いません
>69 お前アホだろ? 全くわからないから空欄なんじゃねーか。
穴があったら入りたい コードの解説を求めてるのかと思った
∧_∧ (・ω・`) コイッ! (⊃⌒*⌒⊂) /__ノωヽ__)
アッー!
74 :
39 :2006/12/31(日) 16:08:17
>>68 そうです。{ }の中身なんですが、ここが分かれば
他はあれで動くんですかね?
>>74 fpoutへは何もしないでクローズしてるようだが・・・
#define N 10 int array[N]; int MaxNum = 0; int MapPoint = 0; temp = array[0]; for(i = 0; i < N; i++){ if(temp<=aray[i]){ temp = aray[i]: MaxNum = temp; MaxPoint = i; } }
77 :
61 :2007/01/01(月) 07:25:29
>>66 色々ダメ出しされてるな…
そこで今後の為にちょっと質問いいでしょうか?
・memset()は極力使うなというのは何故?
・strlen()は処理コストの問題という事ですか?
・main()から-1を戻すと汎用性が失われるというのは何故?
>>66 じゃないけど、
> memset
int count[26] = {0};
のほうが読みやすい
> strlen
計った事無いから分からないけど(最適化されそうだし)
C99かC++なら
for (int i = 0, length = strlen(buf); i < length;...
のほうがいいかと
79 :
61 :2007/01/01(月) 08:36:31
>>78 レスどうもです。
>int count[26] = {0};
しかし、それだと「count[0]」しか初期化されないのでは?
>strlen
う〜ん、とりあえず26回程度のループだったので
for文中で使ったんですけどね…
やっぱCプログラマの人って、ほかの言語のプログラマの人に比べて
みんな処理効率に拘りますねやっぱ。
>79 >しかし、それだと「count[0]」しか初期化されないのでは? 教科書読み直したほうがいい。 人の質問に答えるのはまだ早いな
VBから来てCはそこそこってところかな もうちょっと場数踏んだ方がいいね
>>77 > ・main()から-1を戻すと汎用性が失われるというのは何故?
Unix系のシステムで実質的に終了ステータスとして使える値は
0〜127なんだわ。
なので、普通は終了ステータスとしては、0, 1, 2などの小さい整数を使う。
0が正常終了で他が異常終了ね。
成功か失敗かだけでいいんなら、stdlibで定義されている
EXIT_SUCCESS, EXIT_FAILUREマクロを使うのもいい。
多分その定義は0, 1になってるはずだ。
長ったらしいし、俺はあまり好かんがな。
84 :
61 :2007/01/01(月) 10:24:32
>>80 うぉーーーー
c[3]={0} これで 配列全部0で初期化出来たのか
今まで気づかなかったよ…
同様に、char s[3]={'\0'} 等の場合も同じなんだね…
いや、本当に今まで気づかなかった… ありがと。
>>83 うぉーーーー
これも全然知らなかったよ。
そうなのか、という事はLinuxサーバにアップしてるスクリプトとかの
終了ステータスも全部-1にしてるが、それは間違いだったって訳なのか…
自分の無知さ加減に情けなくなるよ。色々勉強になったありがと。
うぉーーーー
うぉーーーー
魚ーーーー
魚ーーーー
さぁ輪になっておどろう〜♪
魚ーーーー
いいのかそれで
char *string = "AAAA" char *p stop = string + strlen( string ); この式を実行したら、stopは一体何を表してるんですか? %s で呼び出すと 何も表示されないし、 %d は 4万なんたらって数字がでるんだけど。
ごめんなさい *p は char *stop; の間違いです
string は "AAAA" が格納されている最初のAのアドレスが入ってる そこに"AAAA"の文字の長さ4を足すんだから stopには"AAAA"の4文字目の次のアドレスが入る "AAAA" は A A A A \0 なので、"" と同じ。%s では0文字出力 %dでは、アドレスが出力される
つまり、この式で、stopにはstringの終端のアドレスが 入れられているという事になる、でいいんですね。 なるほど、ありがとうございました。
ソフトウェアの設計法のついて学びたいんですが 今月号の日経ソフトウェアに書いてあることのもっと深いことが 書いてあるようなソフトウェア設計について学べる本を教えてくださいお願いします
98 :
デフォルトの名無しさん :2007/01/03(水) 01:54:12
あけましておめでとうございます。 1000本ぐらいのフラグを作りたいのですが どうやるのか分かりません。 今のところnumOfFlags本のフラグの用意は↓ int *flags = (int *)calloc(sizeof(int), numOfFlags / sizeof(int) + 1); のようにして、flagNum番目のフラグをオン↓ *flags |= 1 << flagNum; flagNum番目のフラグをチェック↓ if(*flags & 1 << flagNum) foo; のようにしているのですが、 これで正しいのか分かりません。 たぶん、intは32ビットなので フラグの本数numOfFlagsが1000本ぐらいになったら どういう動作になるのかよく分かっていません。 こういうことするのに最適な方法を教えてください。 お願いします。
>98 ビットじゃなくてバイトを確保してたり、確保した領域の先頭しか使ってなかったりわけわからんが、 int *flags = (int *)calloc(numOfFlags/(sizeof(int)*8)+1, sizeof(int)); flags[flagNum/(sizeof(int)*8)] |= 1 << flagNum % (sizeof(int)*8); if(flags[flagNum/(sizeof(int)*8)] & 1 << flagNum % (sizeof(int)*8)) foo; こんな感じのことがしたいのか?
100 :
98 :2007/01/03(水) 02:44:38
>>99 ありがとうございます。
こういう感じのことがしたかったんです。
IA32のEFLAGSレジスタの任意ビットバージョンみたいなのです。
ただ、このコードについて一点質問してもいいですか?
sizeof(int)*8
ではなぜ8を掛けているんでしょうか?
1バイト8ビットだからだろ intで何ビットなのかてこと
なんか、基本的な事を教えないで中途半端に小難しい事を教えてるんだな 最近の学校は
103 :
98 :2007/01/03(水) 12:40:11
>>101 なるほど。よく分かりました。
>>99 のコードは非常に参考になりました。
こういうのは自分で思いつきそうにも無いです。
本当にありがとうございました。
>>102 いや、別に学校で習ったわけじゃなくて
ほとんど独学でやってます。
フリーのコンパイラ教えてエロい人
gcc
bcc
DMC
LSI-C試食版
Microsoft
110 :
cygwinで :2007/01/05(金) 00:14:06
:(.text+0x3c4):undefined reference to '_scnaf' collect2:ld returned 1 exit status という文がgcc a.c -o a.x で出ました。 直訳?だとldの未定義の参照は1つの出口 状態を返しましたですか?? この文で、何がダメか分かりますか?? 変な文章ですみません。もし分かれば、教えてください。
>undefined reference to '_scnaf' ↑に注目せいや
>>110 > ld returned 1 exit status
コマンド "ld" はステータスコード 1 を返して終了しました。
つまりコンパイル後のリンクでエラーが発生。
> undefined reference to '_scnaf'
_scanf というシンボルが定義されてないぞゴラァ。
libc とかを一緒にリンクしてあげましょう。
113 :
cygwinで :2007/01/05(金) 00:24:34
ありがとうございます。 scanfをscnafと入力ミスしている所がありました。 でも、scnafでもgccできるんですね。初めて知りました。 すみません。
>>113 そのケースは、コンパイルはできるがリンクできないのでldの段階でエラーが発生した、ということ。
(どういう意味で使っているのか知らんが)「gccできる」わけじゃない。
115 :
cygwinで :2007/01/05(金) 00:32:02
そうなんですか! 入力ミスもコンパイルできないと思っていました。 ありがとうございます。
文法はあってるからな
size_t って何? strlenとか使う時は、size_tでしたほうがいいよとか聞いたけど
>>117 hoge_t の _t は type のことで、size_t はサイズを格納する型ってこと。
実体は unsigned int なことが多い。
が、unsigned intでないこともあり得る。 サイズを格納するときは素直にsize_tを使っておけということだ。
ありがとうございます
121 :
デフォルトの名無しさん :2007/01/05(金) 01:36:49
そのtime_tを使用して、現在の日付から年齢を出したいのですが、 構造体から西暦で入力されたデータを取り出して、年齢算出関数を呼び出すには、 どうしたらいいですか?
>>121 localtimeでstruct tmに変換して、その年数やら月やらを使え。
年齢算出関数なんて都合のいいもんは用意されてない。
123 :
デフォルトの名無しさん :2007/01/05(金) 03:08:00
エクセルやワードが全然使えないのに、Cの分厚い入門書を終わらした僕は 順番的におかしいでしょうか?因みに、Cのイメージなどは使えました。
人それぞれ 理解にも色々あるし 実用的な理解力、 また業務的な理解力、 そうでない理論的な理解力もある 実用的なソフト作る為にも 実用的な思考を育てとこう
エクセルやワードを全然使わないので、Cの分厚い入門書を先に終わらした僕は 順番的におかしくないですね?因みに、Cのイメージなどは使えました。
>>118 最近は 8 バイトの型のこともあるね。
size_t を使うときの注意は、通常 unsigned だから、
for 文で int のカウンタとの比較してしまうと鬱陶しい警告が出る・・・というか、
size_t が 8 バイトの場合は int をカウンタとして使う事自体が危ない。
そういうわけでカウンタにも size_t を使うべき。
さらに、unsigned だから
for(i = length - 1; i >= 0; i--) { ... } /* i, length は size_t 型の変数 */
のようにカウントダウンしようとしても、
i は常に >= 0 だから無限ループになる。
この場合は for(i = length; i > 0; ) { i--; ... } とすればいい。
なんだそりゃw そもそもfor文のカウンタをsize_tにすんな
>そもそもfor文のカウンタをsize_tにすんな なんだそりゃw 根拠を書けよ
回数はサイズじゃないから
つーか、 >この場合は for(i = length; i > 0; ) { i--; ... } とすればいい。 こんなアホなことやってるやつがいるんだな
131 :
377 :2007/01/05(金) 09:48:28
SendMessage(*, WM_USER, *, *); して case WM_USE: SendMessage(*, WM_USER, *, *); しても無限にSendMessageされないのなんで?
SendMessage(*, WM_USER, *, *); して case WM_USER: SendMessage(*, WM_USER, *, *); しても無限にSendMessageされないのなんで?
SendMessage(*, WM_USER, *, *); して case WM_USER: SendMessage(*, WM_USER, *, *); しても無限にSendMessageされないのなんで?
>>129 実際のアルゴリズムに関係のないループ変数は分かりにくい
>>131 ここの住人には回答は無理ぽ
Win32 API専用スレに行こう
WM_USEってWM_USERのtypoか?
>>129 for(i = 0; i < length; i++) で i と length の型は揃えるべきだろ?
値域や符号付き符号無しが違うとバグの温床になる可能性があるじゃん。
length がどうしても size_t になるのなら、i は size_t にすべき。一番安全。
>>137 lengthの最大値がUNSIGNED_MAXより小さい保証があるならfor (unsigned i = 0; i < length; ++i)でいいじゃん。
>>138 > lengthの最大値がUNSIGNED_MAXより小さい保証があるなら
こういう「仮定」を置けるなら、それこそ別にintだって構わないだろう。
仮定を置きたくない、robustなコードを書きたいならsize_tにすべきって
話じゃね?
>>138 等号含んでないから length は UNSIGNED_MAX 含んでもセーフじゃね?
141 :
デフォルトの名無しさん :2007/01/05(金) 17:56:42
xとyをそれぞれ0から10まで1きざみで変え、 そのすべてを組み合わせた平面上の11x11個の点(x,y)を考える. これらの点のうちで、 y = 2 ( x -7 ) * ( x -7 ) y = 8 の2つの線に囲まれた領域内(線上は除く)に含まれる点の数を出力するプログラムを作成せよ。 1日ぐらい考えてるが、どう解いてよいのかさっぱり分からない。どなたかおしえて下さい。
>>141 点自体は 11x11 の 121 個しかないから、それ一個ずつ調べればよさそう。
で、2つの関数がどちらも y= の式になってるから、x を一致させたときに
点の y 座標が2つの関数の間にあればいいだろう。
問題はどっちの関数を天井にして床にするかだが…
一次関数と下に凸な二次関数だから、二次関数が床で一次関数が天井になるのかな。
質問です。 void click(HWND,int*); void click(HWND hWnd,int *scene) { *scene++; return; } : static int scene; //シーン番号 : case WM_LBUTTONUP: { click(hWnd,&scene); scene++; timOn = TRUE; InvalidateRect(hWnd , NULL , FALSE); break; } : //出力方法 //互換性のあるhBufからhdcへ wsprintf(str , "%d %d" , scene, tzkX); TextOut(hBuf , 0 , 10 , str , 5); BitBlt(hdc , 0 , 0 , 640 , 480 , hBuf , 0 , 0 , SRCCOPY); 関数内で変数sceneを加算してるのに 全然加算されません。外では加算しても認識されるのに・・・ なんででしょうか。教えてください。 お願いします。
>>143 ポインタを進めているだけで中の値はかわっていない。
(*scene)++; /* 分かり難いなら scene[0]++ でも等価か */
すれば?
>>144 ありがとうございます。
初めて知りました。
ポインタ薦めてただけなのか・・・
>>145 文字列複写なんかの例で良く見る
while(p) *p++ = *q++;
は、中身をインクリメントせずに pなりqなりのポインタをインクリメントしてるし。
評価順がややこしいのは慣れるしかないな。
>>146 while( *p++ = *q++ );
じゃないかのう。
少なくとも while の中がポインタじゃマズイと思われ。
148 :
146 :2007/01/05(金) 19:24:40
149 :
ただ :2007/01/05(金) 21:05:39
Visual C++6.0 でアクセスに接続する方法が載っているサイトを教えてください。お願いします。
>>142 >どっちの関数を天井にして床にするか
そのくらい、比較すればわかることジャン。
xの範囲を先に求めれば、比較する必要もないがな。
なんかそれを求めちまったらプログラムの意味がないというか 紙と鉛筆で計算して、求めた答えを出力するだけのプログラム書いてもいいことになるし
当選プログラム的に直線と放物線の交点を求めるんだが。
当選→当然な そうすりゃ、141の例だけじゃなく、全ての放物線と直線に一般化できる。 もちろん接するときや交わらない場合なんかも判定してな。
156 :
デフォルトの名無しさん :2007/01/06(土) 11:43:42
なんか「WinMainが未解決」とか出てくるんだけどなんで? 今までは普通にプログラムできてたのに、いきなりコンパイルできなくなった…。なにを しでかしたのか自分でもあんま覚えてない。 ターゲットは「Windowsアプリケーション」にしてるし、「14歳からはじめるC言語〜」という 本の通り完全に設定してるはずなんだけど、どこか設定ファイルがおかしいのかな。 Borlandのサイトとか色々見て回ったけど、解決しない…。
コンパイル時に-w忘れてるとか
>>157 今まではできてたんだけど-wとか付けた覚えないなぁ。
なんか「WinMainが未解決(C:\BORLAND\BCC55\LIB\C0W32.OBJ が参照)」とか表示されてる
んだけど、このC0W32.OBJって関係あるのかな…。
14歳から始めるC言語なんて本があるのか。
160 :
156 :2007/01/06(土) 12:21:11
なんか新しくプロジェクトを作ったら普通にコンパイルできた。 プログラム自体はコンパイルできなかったプロジェクトのコピペだし、 設定も全く一緒なのになんでだろ…。 つか今日昼から仕事だっつーのにしょーもないことで時間食わされて かなりイライラして、軽く発狂気味だったことが悔やまれるorz 死ねぼけええええええ!とかWindowsSATUGAIするぞ!とかイロイロ 喚いて怖かったでしょう、お隣さん。ごめん。
161 :
142 :2007/01/06(土) 12:36:05
>>151 残念ながら比較するだけじゃ「囲まれた領域」にはならないんですよ。
>161 「囲まれた領域」であるならどっちが底でどっちが天井かはどうでもいいと思うが。
同じプロジェクト内に複数個main()があると言われるんじゃなかったっけ? >WinMainが未解決
「プロジェクトの作成」って時点でIDE 環境をまとめて提出しない win32apiということでもスレ違い エスパータイプかよ
165 :
デフォルトの名無しさん :2007/01/06(土) 17:12:40
>>163 それだとWinMainが重複して定義されてるとか言われるだろ
>WinMainが未解決
プロトタイプ宣言があるのに実体が無い場合
>>165 プロトタイプ宣言があって実体がない関数でそんなメッセージは出ないよ。
Cだったらありえない。
リンカが吐いているエラーでしょ。ライブラリとかスタートアップコードとかが
WinMainを参照しているのに、オブジェクト中どこを探してもそれがない、
とリンカが言ってるんだよ。
たとえばこんなコードで同様のエラーを起こせるよ。
int ahoaho(void);
main() {
bakabaka();
}
これをコンパイル・リンクしたらbakabakaが未解決とか出るよ。
ahoahoについてはなんの言及もない。
>>160 単にWinMain()入りのソースをプロジェクトに入れ忘れとか、そんな悪寒
168 :
デフォルトの名無しさん :2007/01/06(土) 22:08:46
#include <stdio.h> void store(int *arg){ *arg = 1; } int main(void){ int *p; store(p); return 0; } こんな風に関数にポインタ変数渡すことって出来ないんだっけ? Segumentation faultがでるんだが
170 :
168 :2007/01/06(土) 22:16:56
実はとあるプログラムであらかじめ定義されたポインタ変数がすでにあって(上記コードでいえば*p)、 そいつに対して値を代入する関数を書こうと思ったんだが・・・ やっぱ168に書いたみたいにはできんのな・・・
int* p; だけじゃ、実体が無い。 家をたててないのに住所だけ作って、そこに手紙を届けようとしてるようなもんだ 届くわけが無い。
うまいことを言う
>>170 int a;
int *p = &a;
store(p);
174 :
デフォルトの名無しさん :2007/01/06(土) 22:42:48
なるほど、その説明で合点がいった。 つまり #include <stdio.h> void store(int *arg){ *arg = 1; } int main(void){ int *p,a; p = &a; store(p); printf("%d", *p); return 0; } ならばいいわけですね。ってかこれだけ実行してみたら上手くいきました。 上手く理解できました。直面している問題の解決にも役立ちそうです。ありがとう。
aに0以外を入力すると 5回分kazuに乱数(10の整数まで)を足していって 最後にkazuの値が偶数か奇数かを表示するプログラムを練習で作ってみたのですが、 なぜか答えが627556で固定されてしまいます 1時間半ほど睨めっこしてみたのですが解決することが出来なかったので どうかお助けください・・・ #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int i,a,kazu=0,ransu; printf("aを入力:"); scanf("%d",&a); while(a!=0){ srand((int)time(NULL)); for(i=0;i<=5;i++){ kazu=kazu+rand()%11; printf("%d\n",&kazu); } { if(kazu%2) printf("奇数\n"); else printf("偶数\n"); } scanf("%d",&a); } return 0; }
>printf("%d\n",&kazu); 計算結果ではなくポインタを表示しようとしている。
>>176 printf("%d\n",&kazu);
は
}
{
の↓でいいんでしょうか・・・?
読みにくい・・・
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int i,a,kazu=0; srand((int)time(NULL)); do { printf("aを入力:"); scanf("%d",&a); if(a!=0){ for(i=0;i<5;i++){ kazu+=rand()%11; printf("%d\n",kazu); } } if(kazu%2) printf("奇数\n"); else printf("偶数\n"); } while(kazu%2 != 0); return 0; } これでどうだろうか
ミスッタ(´ω`)・・トホー 最後のwhileはwhile(kazu%2==0);だった
>>171 メモリ"番地"なんだから言われてみれば至極当然な説明だが
素晴らしいと思った
182 :
デフォルトの名無しさん :2007/01/07(日) 04:28:17
>>174 の
int *p,a;
っておかしくない?
int* p,a
って事にならないの?
おいおい。 int* p,a; って書いても a はポインタにはならないってのは超基本だろ?
184 :
デフォルトの名無しさん :2007/01/07(日) 04:42:32
185 :
デフォルトの名無しさん :2007/01/07(日) 04:44:42
でも、ややこしいから、2行の分けて欲しい
186 :
デフォルトの名無しさん :2007/01/07(日) 08:06:02
質問です。scanfの引数で (%f*c%f ,&a,&b) がboland5.5で通るのですが、このc%fのcってなんなんでしょうか?
%fで完結しているから、*cは単に読み飛ばす文字と認識されるはず。 勿論コンパイル・リンクは問題なく行なわれるが、入力に*cがないと次の数値入力が行なわれないはず。
%*cの間違いだったりして。もしそうなら、*は入力抑制子。つまり読み飛ばし。 あと、最初の引数は""で括らないとコンパイル通らないんじゃまいか。
入力抑制子→代入抑制子
190 :
186 :2007/01/07(日) 09:15:17
>>187-189 ご回答ありがとうございます。読み飛ばす文字でしたね。複数の文字列も
読み飛ばし(というか入力区切り)に使える事を知らなくて *c はコンパイラ特有のマクロかと
思っちゃいました。*cを区切りとして入れると標準入力バッファから変数にちゃんと格納されました(爆
ありがとうございました。
191 :
爆 :2007/01/07(日) 10:03:23
γ´`ヽ
_ゝ -''` ー- _
/ \
/ ヽ 、′ 、 ’、 ′ ’ ; 、
,':.. ', . ’ ’、 ′ ’ . ・
!:::::. , -────── 、 | 、′・. ’ ; ’、 ’、′‘ .・”
|:::::::. | `ィェァ `ィェァ| | ’、′・ ’、.・”; ” ’、
|::::::::.. `───────' | ’、′ ’、 (;;ノ;; (′‘ ・. ’、′”;
.|:::::::::::.. | ’、′・ ( (´;^`⌒)∴⌒`.・ ” ; ’、′・
|::::::::::::::.. l 、 ’、 ’・ 、´⌒,;y'⌒((´;;;;;ノ、"'人 ヽ
l:::::::::::::::::.... / 、(⌒ ;;;:;´'从 ;' ;:;;) ;⌒ ;; :) )、 ヽ
|:::::..ヽ:::::::::::.... / ( ´;`ヾ,;⌒)´ 从⌒ ;) `⌒ )⌒:`.・ ヽ ,[]
|:::::::....` 、:::::::::.. / ′‘: ;゜+° ′、:::::. :::
>>000 ´⌒(,ゞ、⌒) ;;:::)::ノ ヽ/´
}::::::::::::::::...`ヽ_人,ノ{ `:::、 ノ ...;:;_) ...::ノ ソ ...::ノ
 ̄:::::::::::::::.:::::::::::::::::::..  ̄ ー- _
::::::::::::::::::::::::::::::::::::::::::::::::.... \
192 :
物乞い :2007/01/07(日) 16:49:56
やりたいこと メールを読み込んで 添付ファイルを保存したい。 欲しいもの Cソース ギブミーチョコレート!!!
試してないけど #include <strdio.h> #include <mail.h> int main(void){ FILE *fp; MAIL *mail; CONTENT *con; fp=fopen("hogehoge.mail", "r"); mail=getmail(fp); fclose(fp); printf("Mail: %d\n", getmailsbj(mail)); printf("MIME: %s\n", getmailmime(mail)); con=getmailcontents(0); ... } みたいに
>>192-193 前提条件がなさ過ぎる上にどのみちなんかのコンポーネントでも
利用しない限り、数十行程度のコードでは収まらん。
前提条件(※)を明示して宿題スレかどっかに逝け。
※↓最低でもこれぐらいは書け。
・OSはなんなのか。
・サーバから読むのか、メーラのデータを読むのか。
・サーバから読むのなら、プロトコルはなんなのか?
・メーラのデータを読むのなら、どのメーラなのか?
fopen()で読んでるからにはファイルを読む気なんだろうけど メールの保存形式って色々あるからねぇ
196 :
物乞い :2007/01/07(日) 18:05:16
>>193 やりたいことは193のやってることです。
#include <mail.h>
OS:FreeBSD
サーバーのファイルから読み込み。
で、欲しいのはそのコンポーネントが欲しいです。
#include <mail.h> //<--コレ
#include <stdio.h> char buf[MAX_LINE]; int getline(FILE *fp) { int i; for (i=0; (buf[i++]=fgetc(fp)) != '\n';) if(feof(fp)) return 0; buf[i]='\0'; return i-1; } こんな感じでファイルから一行だけ読み込む関数書いてます 毎回ループの中(もしくは条件式)でファイルの終端かどうか調べるのが 納得いかないのですがどうするのが妥当でしょうか?
>>196 サーバから読むのなら、プロトコルがなんなのか書けって言ってるだろが!
てか、ここじゃなくて宿題スレあたりに逝け!
199 :
物乞い :2007/01/07(日) 19:00:33
>>198 ごめん言い方が悪かったな。
サーバーから読むといっても
ローカルのファイルから読み込むんだ。
いまSSHで接続してるのでサーバーっていったけど。
>>197 ・なんで素直にfgets()を使わないのか。
・MAX_LINEを越える行長だった場合はバッファオーバーフローを引き起こすぞ。
こんな用途でいちいちグローバル変数を用いるのもよろしくない。
・fgetc()の戻り値をチェックせずにbufに突っ込むのはよろしくない。
EOFが返された時、多分0xffのような値がbuf末尾に入る。
・このままだとファイル末尾に改行が無いようなケースでは、その行は
破棄されることになる。
どうしてもそういうデザインでやりたいのなら、せめて以下のように
書いたほうが良い。
int getline(FILE *fp)
{
int i, c;
for (i = 0; i < MAX_LINE-1 && (c = fgetc(fp)) != EOF && c != '\n'; ++i)
buff[i] = c;
buff[i] = '\0';
return i;
}
201 :
物乞い :2007/01/07(日) 19:06:27
たしかにスレ違いだな。 宿題スレのほうにいくよ。
>>199 それならそれで、どんな形式のファイルか明示(※)しないと誰も答えようがない。
ちなみにおまいが言ってるファイルがPOPサーバなんかが一時保管しているメールデータの
ことであれば、違うアプローチを採用することを強く推奨する。
それと、ここじゃなくて他所のスレに逝けって言ってるだろが。
※
いい例:hogeメーラのhigeディレクトリにあるhageファイル
悪い例:メールのファイル
ま、Unixのメールボックス形式のファイルを読みたいのだろうけどな。 1ファイル1メッセージの。 RFC822なりMIMEなりのキーワードでぐぐるのが早いんじゃね? google code searchを利用してもいいし オープンソースのメーラからコードパクるのもいいわな。 mnewsとかmuttとか。 ライブラリもあるだろ。
204 :
物乞い :2007/01/07(日) 19:17:15
>>203 律儀に答えてくれてすまんね。
俺が聞きたかったのはそれだよ。
メールデータ(POP3のパケットをダンプしたのを結合したファイル)
を読み込ませるつもりなんだ。
で、Cで書かれたMIMEデコーダがどっかにあるだろうと
思ったので聞いてみたんだ。
>>204 >メールデータ(POP3のパケットをダンプしたのを結合したファイル)
>を読み込ませるつもりなんだ。
>で、Cで書かれたMIMEデコーダがどっかにあるだろうと
>思ったので聞いてみたんだ。
奇遇だな。俺らが聞きたかったのはそれだよ。最初から言ってくれよ。
207 :
物乞い :2007/01/07(日) 19:30:48
いや。すまんね。 たしかに読み返すとわからないな。
208 :
197 :2007/01/07(日) 19:48:37
>>200 ご指摘&参考コードありがとうございます
fgets使わないのもint型変数に代入してからbufに代入し直さないのも
どうにも無駄なことをしているって感触が気持ち悪くて…
最近のコンパイラはめちゃくちゃ優秀なのも
そもそも自分が読ませようとしてるファイルの容量(精々数百KB)くらいなら
体感で大差ないのも良く分かってるんですが…
最後のreturn分でfp->_flagを返すようにすればいいかなと思ったんですが、これでも駄目みたいですね
>>208 何で「無駄」と考えるのか全く理解できないな。
速いが正しく動作しないコードには全く意味が無いし、
本当に速くなるかどうかすら疑問ときている。
一体なぜfgetc()で手書きする方がfgets()より速いと思うんだ?
マルチスレッド環境下では、一般にfgetc()は一文字単位での排他制御を引き起こす。
むしろ遅くなるんだぞ。
シングルスレッドかつ、マクロで実装されている可能性の高いgetc()を
使うなら、fgetc()よりはマシだが、それでも行読みしたいのなら、
fgets()のほうがより最適化されている可能性が高い。
想像だけでモノを語っても無駄だ。せめて実測しろ。
プログラムは遅くなる、わざわざ手書きして標準より劣る仕様で
車輪の再発明をするのはプログラマの時間の無駄。
何もいいことなどありはしない。
210 :
197 :2007/01/07(日) 20:34:22
>>209 すいません、理由を省いてました
fgets()でMAX_LINE分文字を読み込む場合だと余分に読み込む場合がほとんどになりそうで
そういうのがむしろfgetsの方が速いと知らされても気に掛かるんです
お金じゃないんだから気にせずジャンジャン行った方がいいんですかね
趣味でやっているだけなので、効率より自分が納得いくこと優先させたいなと…
>fgets()でMAX_LINE分文字を読み込む場合だと余分に読み込む場合がほとんどになりそうで いいえ。 >効率より自分が納得いくこと優先させたい 理解できていないのに勝手な憶測するだけ無駄です。
>>210 余分に読み込むって何が何を余分に読み込むんだ?
どうしても気になるならプロファイルとって自分で書いたほうが本当に速いのを確認してから最適化したら?
現状だと100%君が書いたコードのほうが遅いと俺は思うがな。
余計に読み込むとかいう話をするならば、 stdio系の関数は特に対処しないとBUFSIZ単位で読むので、 1行読むなんて場合だとfgetsを使おうがfgetc使おうが 関係なしに余分に読み込むと思うよ。
>>211-213 一定量データ読み込んだ中からさらに第二引数の分だけ返すんですね
内部でfgetc()何度も呼んでると思ってた自分が馬鹿でした、素直にfgets()使います
お騒がせしてすみませんでした、助言ありがとうございます
>>213 なんかBUFSIZを勘違いしてないか?
216 :
ぽぽ :2007/01/08(月) 00:21:44
誰かこの問題を解いてもらえませんか? お願いします。 以下のプログラムは、入力された10個の数値を引き算し、その結果を表示するプログラムです 9〜11行目を別の関数(関数名はFuncDev)とし、修正しなさい。ただし、グローバル変数は使わないこと。 また、FuncDev内のローカル変数名は任意とする。 FuncDev関数は、以下の定義とする。 int FuncDev(void); FuncDev関数の戻り値は、画面入力されたint型データとする。 #include<stdio.h> void main (void); void main (void) { int n1,n2; int nt; nt=0; for(n1=0;n1<10;n1++){ printf("0-9の数値を入力"); scanf("%d",&n2); nt-=n2; } printf("結果は%dです",nt); }
問題の意図は、 for(n1=0;n1<10;n1++){ printf("0-9の数値を入力"); scanf("%d",&n2); nt-=n2; } ↓ for(n1=0;n1<10;n1++){ nt-=FuncDev(); } かな...
ただ引くだけじゃなくて、多少なりとも意味のあるコードで 問題出せばいいのに。。。
219 :
ぽぽ :2007/01/08(月) 01:04:48
ありがとうございます。この問題もお願いできますか? このプログラムで本来なら入れるべき処理は何か。それを指摘しなさい。 1:char*pstr; 2: 3:pstr=malloc(100); 4:sprintf(pstr,"123"); 5:pstr=malloc(10); 6:sprintf(pstr,"456"); 7:free(pstr);
>>216 の問題は、まだ、正解がでてないと思う。。。
221 :
ぽぽ :2007/01/08(月) 01:13:20
すいません。さっきの問題はできました。
222 :
デフォルトの名無しさん :2007/01/08(月) 01:14:34
mainをヴォイドすんな
>>219 4行めと5行目の間に、7行目と同じのを入れればいいと思う。
(しかし出題者がすごいレベル低そう)
きっと出題者は 2: をゴニョゴニョしてほしかったんだよ
4. と 5. の間に /* 5. と 6. の間に */ でもいいかもw
227 :
デフォルトの名無しさん :2007/01/08(月) 03:02:03
現在の地域時間から15時間後の日時を表示するプログラムを作っていただけませんか? 表示形式は日付と時間が表示されればいいんですが。 お願いします。
>>227 #include <stdio.h>
#include <time.h>
int main(void)
{
time_t t = time(NULL);
struct tm *tim = NULL;
t+=15*60*60;
tim = localtime(&t);
if(tim) printf("%s",asctime(tim));
return 0;
}
恐ろしくやっつけ仕事
229 :
デフォルトの名無しさん :2007/01/08(月) 04:04:32
ありがとうございます。最後にもうひとつお願いします。 次のプログラムにおいてFunc_read関数はstrcmpを使用しています。 これをmemcmpを利用したロジックに作り直しなさい。 int Func_read(void) { char *prtn1; char *prtn2; char szdat1[81]; char szdat2[81]; int nrtn; prtn1=fgets(szdat1,81,Fp1); prtn2=fgets(szdat2,81,Fp2); if(prtn1==NULL||prtn2==NULL) return(9); nrtn=strcmp(szdat1,szdat2); if(nrtn!=0) return(-1); return(0); }
nrtn=memcmp(szdat1,szdat2,sizeof(szdat1)); sizeof(szdat1)はもはや81でいいのかも...
nrtn=strcmp(szdat1,szdat2); ↓ nrtn=memcmp(szdat1,szdat2,81); memcmpとstrcmpは実装がほぼ一緒。 strcmpはnull終端文字列を扱う事を想定して実装されてるから nullで処理が止まるけど、memcmpはそれがないだけ。 後は引数の型がちょっと違うけど、ポインタ同士だし それはどうでもいいよね(´・ω・`)気になるならキャストすればいい
キャストオフ
233 :
デフォルトの名無しさん :2007/01/08(月) 04:25:40
ありがとうございます。 nrtn=strcmp(szdat1,szdat2); ↓ nrtn=memcmp(szdat1,szdat2,81); にするだけでいいんですか?
組込の世界のヒトが > printf("0-9の数値を入力"); > scanf("%d",&n2); なんてやるわけねーw
236 :
デフォルトの名無しさん :2007/01/08(月) 04:45:25
ほんまや〜 void main(void)は組み込み系ということでわかるが scanf()って。 でも最近「C勉強しだしました」って人でたまにvoid main(void)を見る なんでだろ。 いくらなんでも最近の本でvoid main(void)が主流みたいな書き方 してる本て無いと思うんだけど。 大学とかではそういう風におしえんのかな。電気電子学科卒の俺には 情報系の学科の履修によっての教え方はわかんねぇ。
情報学科でも別にそういう教え方はしてないよ。 というか情報学科でも最初っから全員C知ってるわけじゃないから 基本的に1から教える事になる。だからそういう細かい事は全部省略される。 言語の細かい仕様を教えるんじゃなくて「C言語の一般的な扱い方」だけ教える感じ。 授業のレベルは上がっても講義は全部基本的な事に留まる。 細かい事は全部教授に質問にいかないといけない。
238 :
デフォルトの名無しさん :2007/01/08(月) 13:27:24
配列要素をデータの小さい順番に並び替える関数を 挿入法とクイックソートではどうやるんでしょうか? 交換法のやり方では作れたんですが、サンプルをください
>>238 googleさんに聞いてみたりとかWikipediaで調べてみたりとか
240 :
デフォルトの名無しさん :2007/01/08(月) 14:09:15
>>239 挿入法が即効で解決しました。
クイックソートも粘ってみます。どうも
やらしいひびき
242 :
デフォルトの名無しさん :2007/01/08(月) 14:51:36
クイックソートなんですが、変数2つでもできますか? void quick_sort(int n,int a[])に合わせないと不都合があるのですが
ム板には宿題スレというものがあってだな
void quick_sort(int n,int a[]) から ライブラリの qsort() 呼べばええやんか
245 :
デフォルトの名無しさん :2007/01/08(月) 14:59:33
知ってるんですが宿題の残りごく一部だけなので あっちのテンプレ通り問題文を貼ったりする意味がないと判断してこっちにしました。 要は関数の中身だけなんですよ。 乱数とかエラーチェックの関数とか全部nとa[]で作っているので 合わせないと不都合なのですが変数2つのクイックソートが見つからないです。
>244 ライブラリの qsort() って本当にクイックソートなのかどうかわからないのでは?
247 :
デフォルトの名無しさん :2007/01/08(月) 15:02:13
>>244 それはまだ調べてなかったです。そういえば問題文に禁止って書いてないし
使っていいのかな・・・
変数3つのやつは多分配列の最初と最後とポインタで3つなんですが
配列の個数とポインタだけで作れないかで悩んでました。
クイックソート作れって宿題なら、常識的には qsort 使っちゃダメだろ。 変数2つのやつは、単に変数3つのやつを、その中から呼べば良いじゃん?
クイックソートを行う関数で必須な情報は先頭要素と最終要素。配列の個数と 配列のアドレスでは先頭要素を知ることができない。というわけで>248
まあ、配列のアドレスを変えていけば良いんだけどね。 あんま見ない実装だけど。
251 :
デフォルトの名無しさん :2007/01/08(月) 15:35:17
>>248 変数3つでクイックソートの関数を作って
変数2つでそれを呼び出すだけの関数を作るという意味?
オーバーロードだなw
再帰関数用の余計な引数が必要だけど、 普通に使う時には必要ない、ってな時によく使う手じゃん?
>251 引数さえあわせこめば「変数2つでそれを呼び出すだけの関数」はいらないじゃん。
>255 呼び出す側の都合を考えろよw
257 :
デフォルトの名無しさん :2007/01/08(月) 15:55:41
全然分からなくなって参りました。
わかったから宿題スレ行け 丸投げはあそこが一番むいとる
259 :
デフォルトの名無しさん :2007/01/08(月) 16:07:59
呼び出す関数にだけ問題があるようで、ソース貼ります。 void 関数の名前(int n,int a[]){ int left,right,i; quick_sort(a,left,right); printf("結果\n"); for(i=0;i<n;i++){ printf("%d\n",a[i]);} } 何がまずいんでしょう。 コンパイルエラーは出ませんが実行したらエラーが出ます。
left, right って何だよおい。
261 :
デフォルトの名無しさん :2007/01/08(月) 16:09:54
クイックソートの関数の時に使った配列の最初と最後の変数です。
いや、そうじゃなくて、
>>259 の中で、
left と right を宣言して、何も代入せずに、
そのまま quick_sort につっこんでるじゃん?
263 :
デフォルトの名無しさん :2007/01/08(月) 16:11:48
全然宿題の残りごく一部だけじゃないじゃん。 宿題スレにいきな。
265 :
デフォルトの名無しさん :2007/01/08(月) 16:17:20
left=a[0]; right=a[n]; を宣言した直後に入れてみると一応エラーが出なくなったかわりに クイックソートが機能しなくなりました><
left と right はインデックスだよ。
あと、ソート関数はソート関数として独立させて、 表示機能は完全に分離する。 これ、基本。 デバッグ用の一時的な出力はまあ別だけど。
left=0; は想像がつくが、 right=n; か right=n-1; かで迷いそうではある。
269 :
デフォルトの名無しさん :2007/01/08(月) 16:24:37
>>266 void quick_sort(int n,int a[])
{
int i;
int left=0;
int right=n-1;
quick_sort2(a,left,right);
printf("結果です\n");
for(i=0;i<n;i++)
{
printf("%d\n",a[i]);
}
}
できました。最初nでやって無理だったんでn-1で
宿題スレで丸投げしたら後で余計分からなくなるんでこっちに寄生させてもらいました。
ありがとうございました。
直接 0, n-1 を引数に入れりゃ良いのに。まあいいけど。
271 :
デフォルトの名無しさん :2007/01/08(月) 16:26:49
>>267 そうだったんですか。
デバッグの関数もあるしややこしいから中に入れちゃったんだけど。
覚えておく
色んなとこからソート関数呼ぶたびに出力されたら困るだろ?
273 :
デフォルトの名無しさん :2007/01/08(月) 17:15:40
スペースを空けたい場合は、バックスペースを使い空白にすればいいのでしょうか? 或いは、%数字で空ければいいのでしょうか?
日本語でおk
バックスペースってさ、Enterの上についてるこれだよな? 俺なんか変なこと言ってる?
指定した数だけスペース入れたい場合は printf("%*s", n, ""); でおk。n が入れるスペースの数。
こういうスレに質問してくるやつって傾向が似てるねw
質問の仕方を質問するスレを作る必要がありそうだ。
279 :
デフォルトの名無しさん :2007/01/08(月) 17:34:58
サンクスです
>>278 大丈夫、それを読むくらいならまともに質問できるから。
>>246 確かに。Metroworks CodeWarriorではqsortはヒープソートで実装されている。
282 :
デフォルトの名無しさん :2007/01/08(月) 18:46:57
#include <stdio.h> int main() { double a = 0.5, b = 10.5; int c = 215, d; char e = 'A'; printf("%f + %f = %f\n", a, b, a + b); d = c + 11; printf("cの値は%dでこれに11を加えると%dとなります\n", c, d); printf("eには\"%c\"が代入されています\n", e); return 0; } これのdの意味がわからない。 ためしにd = c + 11抜いてみたら4235448とかいう値になったんだが。
俺もdを抜いてみたら1628865734とかいう値になった。 こりゃ間違いなくコンパイラのバグだな。
あるプログラム(Real Time Linux関連)で exit -1; という表記があったんですが、 makeすると `exit' undeclared と怒られます。 これはexit(-1)と書き換えてしまえばいいだけのことですか? それとも、何か環境依存のせいでerrorを吐いてるんでしょうか。 これだけ直せば全体のmakeが完了するプログラムなのですが、 ここの対処をexit(-1)とするだけでよいのか判断できないので、 どうするべきか分かれば教えてください。 もちろん書き直してよいかはプログラムによりけりなのですが、 exit -1; と書いて通らないのはうちの環境だけかも知れないので、 ぜひ教えてください。 Scientific Linux上でgcc 3.4.6です。
exitという変数があるのを期待して、 その数に演算をするような文脈ではありません。
long double型で表現しきれないような大きい値は、どうやって保持したらいいのでしょうか?
>>284 exit(-1); でいいんじゃね?
>>286 多倍長演算ライブラリがどっかにあると思うのでそれを使う。
288 :
284 :2007/01/08(月) 19:55:25
>>289 じゃぁ乱数関数の実装ってこんな感じ
int rand() {
int a;
return a;
}
>290 ソレダ!!!1!!11!
まあランダム(正規分布してる)っつーよりは、予測不能な値って言ったほうがいいな
キミダ!!!1!!11!
>>292 予測不能ってことなら、セキュリティ用途でもバッチリじゃん! スッゲー!!1!!1!
#include<stdio.h> int fake_rand(void){ int a; return a; } int hoge(void){ int a=1234; return a; } int hoga(void){ int a=5678; return a; } int main(void){ hoge(); printf("%d\n", fake_rand()); hoga(); printf("%d\n", fake_rand()); return 0; }
>>294 あんまり揚げ足とっていじめてやるなよw
確保したメモリ上にもともとあった情報が値として入るっていうだけで
無作為性も予測不可能性も再現不可能性も無い。
297 :
デフォルトの名無しさん :2007/01/09(火) 00:37:29
#include <stdio.h> #defineKAMOKU5 main() { intten[KAMOKU]={73,59,92,83,75};/*得点*/ intgoukei = 0;/*合計点*/ doubleheikin;/*平均点*/ charshimei[20]="太郎";/*氏名*/ charkamokuName[KAMOKU][10] = {"国語","数学","英語","社会","理科"}; charhyouka = '_';/*評価*/ inti;/*科目数*/ /*合計点と平均点の算出*/ for(i = 0;i < KAMOKU;i++) { goukei += ten[i]; } heikin = (double)goukei / i; /*評価を求める*/ if(heikin >= 60) { hyouka = '+'; } else { hyouka = '-'; }
298 :
デフォルトの名無しさん :2007/01/09(火) 00:39:19
/*画面に表示*/ printf("氏名:%s\n",shimei); for(i = 0;i < KAMOKU;i++) { printf("%-6s:%3d点\n",kamokuName[i],ten[i]); } printf("\n"); printf("%sさんの合計:%3d点 平均:%5.1f点",shimei,goukei,heikin); printf(" 評価:%c\n",hyouka); } これで、最初にintten[KAMOKU]={73,59,92,83,75};/*得点*/ とありますが 要素数の所に、[KAMOKU] と入っています、これは数字が本来入るべきではないのでしょうか? もし、入って良いとしたら、何故でしょうか?ご教授お願い致します。
#define KAMOKU 5 これ以降は KAMOKU と書かれている箇所は 5 と書いたとみなされるd(^^)
> ご教授 "教示"だろ
302 :
教授 :2007/01/09(火) 00:50:15
>>300 いえ、私はとある大学の教授です
どこの学校かは言えませんが
先月、パンツ盗んで捕まりましたが、ハッハッハ
今は塀の中ですよ、、ハッハッハ
>303 そんな何度も念押ししなくてもw
306 :
sage :2007/01/09(火) 01:47:56
おいらはc言語怒素人なんだけど、いつかはプログラマーになりたいと思ってる。 それでこのスレに来たんだけど宇宙語が飛び交ってる・・・。 プログラマーって皆これくらいの知識持っていないと駄目なんですか? それともレスをつけてる人達はめちゃくちゃハイレベルな人なんですか?
kwsk
エクセルファイルをCで読み込みたいのですがやり方がわかりません。 友人には、csvを使えば楽といわれたのですが結局わかりません。 やり方を教えて頂けないですか?
kwsk
310 :
デフォルトの名無しさん :2007/01/09(火) 03:00:57
311 :
デフォルトの名無しさん :2007/01/09(火) 03:33:10
C言語の構造体の値の書き換えでつまづいてます。 struct celldata{ int color; }; 上の様な構造体を定義して、main関数で以下のように 構造体を宣言しています。 struct celldata *cell[DEPTH][HEIGHT][WIDTH]; ここで、cell[0][i][j]に数値を入れていきます。(0<i<HEIGHT, 0<j<WIDTH) 次にcell[1][i][j]にcell[0][i][j]の数値をコピーします。 その後cell[1][2][2]->colorの数値を直接変えるのですが、 同時にcell[0][2][2]->colorの数値も同じ値に変わってしまいます。 cell[1][2][2]の数値だけを変えたいのですが、どのようにすればいいのでしょうか?
> struct celldata * ^^^^^^^^^^^^^^^^^^↑これがあるのに... > cell[1][i][j]=cell[0][i][j]; って、同じアドレスにしたいのかなw
313 :
311 :2007/01/09(火) 03:36:40
ちなみに値の書き換え部分はこんな感じで行ってます。 //セルのコピー for(i=0; i<HEIGHT; i++){ for(j=0; j<WIDTH; j++){ cell[1][i][j] = cell[0][i][j]; } } //値を書き換える cell[1][2][2]->color = 2; ここでcell[1][2][2]->colorは2に書き換えられるのですが、 同時にcell[0][2][2]->colorも同様に2に書き換えられてしまいます。 助けてください・・・。
314 :
311 :2007/01/09(火) 03:43:47
>>312 わざわざこちらにまで・・・;;
ありがとうございました。
正常に動作しました!
わろす
316 :
デフォルトの名無しさん :2007/01/09(火) 03:52:34
int i,j; int x[3][4]; for(j = 0; j<4; i++){ for(i = 0; i<3; i++){ x[j][i] = 0; } } この反復構造の二重ループで、わからない事があります 参考書の解説に依れば、 for(i = 0; i<3; i++){ x[j][i] = 0; } これは、内側のループでiをカウント、3*4回繰り返すと 書かれていますが、合計12回なんでしょうか? それと、二重ループの解説を簡単にでいいので 解説お願いします。
128bit整数は扱えませんか できるだけポータブルな方法で・・・・ってのは無理な相談ぽいですよね
318 :
316 :2007/01/09(火) 03:55:22
それと、これは 内側で繰り返す事を外側で、4回繰り返すと言う事でしょうか?
>>318 その通りです。すなわち
x[j][i] = 0;
を合計12回実行する事になります。
320 :
316 :2007/01/09(火) 04:05:24
>>319 ありがとうごいます。
しゃかし、二重ループの意味が掴めません・・・・
>>318 で書いた通りなのでしょうか?
となると、計48回になるのでしょうか?
>>317 ポータブルな方法で扱いたいなら多倍長整数を自分でポータブルな実装をするとか。
>>320 難しく考えず
for(j = 0; j<4; i++){
...
}
は、中身を4回繰り返し、
中身である
for(i = 0; i<3; i++){
...
}
は、その4回の繰り返しの1回ごとに、3回中身を繰り返す、と考えればいい。
だから、内側のループの中身である
x[j][i] = 0;
は全部で12回繰り返して実行されることになる。
323 :
316 :2007/01/09(火) 04:16:40
グハッ難しいと言うか混乱しますORZ 違うものや比喩にして、考えたいのですが、何か良い比喩表現はないでしょうか? 頭が爆発しそうです。
x[j][i] = 0; の代わりに printf("i=%d, j=%d\n", i, j); にして実行してみると、何が行われているか理解しやすくなる…かも。 表示が12回行われることも含めて。
325 :
316 :2007/01/09(火) 04:26:33
自分なりに遊園地のコーヒーカップを思い浮べて整理してみます。 あの回転円盤の上に更に回転カップがあると連想しますが微妙です。 皆さんの助言を改めて整理して考えました では、その12回は中と外を合わせて(3×4)と考えて宜しいでしょうか?
326 :
デフォルトの名無しさん :2007/01/09(火) 04:27:27
現在ポインタを勉強しています。 そこで以下の文について教えてください。 char *mnthp[4] = { "January", "February", "March", "April" }; int i; for (i = 0; i < 4; i++) { printf("%s\n", mnthp[i]); } これを実行すると結果は January February March April になります。 ですが printf("%s\n", mnthp[i]); が printf("%s\n", *mnthp[i]); では無いのが理解できません。 なぜ最後に*が要らないのかを教えてください。
327 :
316 :2007/01/09(火) 04:27:59
あれ?
>>316 のソース間違っていない?
添字の範囲をオーバーしちゃうような。
x[j][i] = 0;
は
x[i][j] = 0;
だよね。
もしくは、
int x[3][4];
が
int x[4][3];
の間違い。
330 :
デフォルトの名無しさん :2007/01/09(火) 04:36:44
>>316 さんへ
たぶん参考書の説明がおかしいと思います。
(著者の言いたいことは正しいのだろうが、日本語がおかしいって事)
つまり
iのループを3周したら、jのカウントが一つ増える。
そのjのカウントが増えるループは4周するのだから
3周×4周で12週(12回)と言うことでしょ
331 :
316 :2007/01/09(火) 04:37:33
>>328 ご指摘、ありがとうごいます。
>>329 何となくは理解?できました・・・
もう一つ疑問なのがあります
for(j = 0; j<NINZUU; j++)
{
/*合計点と平均点の算出*/
for(i = 0;i < KAMOKU;i++)
{
goukei[j] += ten[j][i];
}
heikin[j] = (double)goukei[j] / i;
/*評価を求める*/
if(heikin[j] >= 80)
{
hyouka[j] = 'A';
}
else if(heikin[j] >= 60)
{
hyouka[j] = 'B';
}
else
{
hyouka[j] = 'C';
}
}
これは反復に中に反復と多分岐が混ざっているのでしょうか?
>>326 文字列は先頭の文字へのポインタってのは理解してる?
で、変数の型は、
*mnthp[] is char // これが宣言
mnthp[] is pointer to char
mnthp is an array of pointer to char
333 :
330 :2007/01/09(火) 04:39:19
>>316 さんへ
再度すみません。
ひょっとしてc言語スタートブック(高田美樹著)をやっているのではありませんか?
334 :
316 :2007/01/09(火) 04:40:19
>>333 はい、そうですが・・・何故おわかりに・・・・
これは入門に不向きでしょうか?
>>326 printfで%sに対応する引数は\0終端な文字配列へのポインタ。
mnthp[i]がまさにそれに当たる。
*mnthp[i]はmnthp[i]の最初の文字を意味する。
確かめるなら、
printf("%s\n", mnthp[i]);
でなく、
printf("%c\n", *mnthp[i]);
とすれば、
J
F
M
A
となるはず。
336 :
330 :2007/01/09(火) 04:42:07
現在私もそれを使って勉強しているからです。(笑) 一緒に頑張りましょう!! ただ私のは初版なので誤字脱字が多いのが大変です。
337 :
316 :2007/01/09(火) 04:45:29
>>336 おーそうなんですかW
是非、がんばりましょう!
もう少し詳細な解説が欲しいです。
>>336 さんは、穴埋めを敢えて自分で全てソースを書き直して
やってます?自分はそうしてます。時間はかかるけど。
338 :
311 :2007/01/09(火) 04:46:07
int d_max; で宣言したd_maxという変数をmovement();という関数の引数として 渡しているのですが、movement();の関数の前と後で何故か値が変化しています。 printf("movementに入る前のd_max=%d\n", d_max); movement(cell, x, y, 0, d_max); printf("movementに入った後のd_max=%d\n", d_max); ↑を実行すると、 movementに入る前のd_max=4 movementに入った後のd_max=4561248 のような出力になっちゃいます。d_maxはポインタで 渡してるわけではないのですが、なぜこのような現象が起きるのでしょうか?
339 :
330 :2007/01/09(火) 04:49:02
316さんへ 私も全部書いています。 やはり書かないと覚えないですね。
340 :
デフォルトの名無しさん :2007/01/09(火) 04:49:34
C言語初心者です。 参考書を元に構造体でのソートを勉強中ですがとある例題がどうしても解けません。 お手数ですがどなたか教えてください。 #include <stdio.h> #define MAX 5 typedef struct student { charname[20]; intkoku; intsuu; } mem; int sort_student(struct student * const seito, int max) { return 0; } int main(void) { mem sankumi[]={ {"田中",56,72},{"佐藤",89,94},{"鈴木",35,80},{"山田",68,79},{"山本",23,31} }; int i; sort_student(sankumi,MAX); printf("国語\n\n"); for(i=0;i<MAX;i++) { printf("氏名 %-6s 点数 %2d\n" ,sankumi[i].name,sankumi[i].koku); } }
341 :
316 :2007/01/09(火) 04:52:29
>>330 での解説ありがとうごいます。
自分は一日、一章ごとにやっていますが
>>339 さんは、どのくらいのペースでやっていますか?
因みに自分は一章終わるのに、4時間はかかります。
342 :
340 :2007/01/09(火) 04:52:32
すいません・・ コピペしたらタブのスペースが消えちゃいました。 わからない所はsort_studentの関数です。 よろしくお願いします。
343 :
330 :2007/01/09(火) 04:55:16
私も一日一章ペースでしたが、もうすぐポインタが出てきます。 その後には関数があります。 そのあたりからかなりペースダウンしました。
344 :
316 :2007/01/09(火) 04:57:37
>>343 自分は、今4章ですが苦戦中でペ−スダウンに・・・
イメージは掴みつつ十日以内には終わらせたい。
>>340 何の値をもとにソートすればいいのでしょうか?
国語と数学の合計点ですか?
>>338 (1)実はd_maxはグローバル変数として宣言している。
(2)movementの実引数または何かのグローバル変数にd_maxへのポインタが含まれている。
で、movementがd_maxを書き換えている。
(3)確保した配列の範囲を超えてアクセスしてd_maxの領域を侵犯している。
ありそうなのは、cellの前後でd_maxを宣言してて、cellの添字限界を超えて書き換えているため、d_maxが変になってる。
347 :
340 :2007/01/09(火) 05:03:42
>>345 すいません説明不足でした。
国語の点数です。
348 :
330 :2007/01/09(火) 05:13:28
>>335 さんへ
Januaryの“アドレス”がmonthp[0]に入っていると考えてしまうのです。
だから「January」と表示したいときには*monthp[i]じゃなかろうかと思うのです。
当然これは間違っているのですが、どうしても上手く理解できないのです。
申し訳ないのですが、もう少し教えていただけないでしょうか?
349 :
338 :2007/01/09(火) 05:13:53
>>346 >(1)
再確認したところ、ちゃんとd_maxはmain()関数内で
int d_max;で宣言しています。
>(2)
movement()の引数は↓のようになってます。
void movement(struct celldata *cell[DEPTH_MAX][HEIGHT][WIDTH], int x, int y, int depth, int d_max);
また、グローバル変数は
#define HEIGHT 3
#define WIDTH 9
#define DEPTH_MAX 4
の3つのみです。movementの引数またはグローバル変数にd_maxへの
ポインタが含まれてる事はないと思います。また、movement内では
d_maxは一切書き換えていません;;
>(3)
main()関数で
int d_max;
struct celldata *cell[DEPTH_MAX][HEIGHT][WIDTH];
のような感じで宣言をしています。確保した配列の範囲を
超えてアクセスするというのはよく分からないのですが、
どういった場合にそういうことが起こるのでしょうか?
printfの仕様
>>347 国語の点数をもとにバブルソート
int sort_student(struct student * const seito, int max)
{
mem temp;
int i, j;
for (i = 0; i < max - 1; i++){
for (j = 0; j < max - i - 1; j++){
if (seito[j].koku > seito[j + 1].koku){
temp = seito[j];
seito[j] = seito[j + 1];
seito[j + 1] = temp;
}}}
return 0;
}
352 :
330 :2007/01/09(火) 05:20:22
ああ、分かりました!! 私の考え違いでした!!(当たり前ですね) 有難う御座いました!! さてこんな私ですが、今日プログラマーの仕事の面接に行ってきます。(wr みなさん応援してください。
353 :
340 :2007/01/09(火) 05:20:26
>>351 さん
ありがとうございます!!
早速やってみます!!
>>349 movement()の中でcellなり、他にポインタで渡された変数の中身を書き換えていない?
そのとき、ポインタで指していたデータ本来の領域を超えてアクセスしている可能性がある。
すると、別領域として確保していたd_maxまで間違えて書き換えてしまう恐れが。
よくあるパターンは配列のインデックスの範囲を超える(0より小さいとか最大値以上とか)とか、
ポインタに間違った値を加減算するとか。
355 :
338 :2007/01/09(火) 05:23:26
>>350 >>338 に対する回答でしょうか?
あまり関係ないと思ったので書いてないのですが、for文で
for(d_max=0; d_max<DEPTH_MAX; d_max++){
for(x=0; x<HEIGHT; x++){
for(y=0; y<WIDTH; y++){
printf("movementに入る前のd_max=%d\n", d_max);
movement(cell, x, y, 0, d_max);
printf("movementに入った後のd_max=%d\n", d_max);
}
}
}
のように書いているので、printfの仕様ではないかと思います。
意図しない場所でd_maxがDEPTH_MAXを超えてしまいループから
出てしまうので、表示だけの問題でなく実際の数値も変になってると思います。
>>348 monthp[0]に入っているのは先頭の'J'のアドレス。
printfの立場として、欲しいのは'J'の位置であって、'J'の値そのものじゃない。
printfは与えられたアドレスからヌル文字が出てくるまで一文字ずつ手繰っていくからね。
メモリの中身はこんな具合:
J a n u a r y \0 F e b r u a r y \0 M a...
^monthp[0] ^monthp[1] ^monthp[2]
357 :
340 :2007/01/09(火) 05:30:18
>>351 さん
できました!!!
これで丸2日悩んでました・・・
こんな時間に本当にありがとうございました!!!
>>349 問題点とは関係ないが、#define HEIGHT 3 のHEIGHTはグローバル変数ではない。
コンパイル前にソース内のHEIGHTという文字列を3に置換することをプリプロセッサに指示しているだけ。
ある意味グローバルな存在ではあるけれどね。
359 :
338 :2007/01/09(火) 05:49:15
>>354 movement()の中ではcellの値を書き換えまくってます・・・。
理論はなんとなく分かるのですが、どこでそうなってるのかが分からないです;;
mallocを使って動的にメモリを確保しているのですが、
本来の領域を超えてアクセスしたら、エラーがでますよね?
プログラム自体は正常に最後まで実行されています。
もしかして根本的に俺が理解してないのかも知れないです・・・
cell[4][3][9]で宣言してるのにcell[4][3][10]にアクセスしてるとか
そういうのとはまた別次元の話ですか?
360 :
338 :2007/01/09(火) 05:51:31
>>358 確かに・・・ちょっとグローバル変数の意味を勘違いしてました。
このプログラムでグローバル変数は一切使用してませんm(_ _)m
>>359 まさに最後の文の通り。
本来の領域を超えてアクセスしてもエラーにならない場合もある。
d_maxの領域を書き換えただけで終ってるなら、
それは書き換えてもいい領域だから、エラーにはならない。
とりあえず、デバッガかprintfデバッグでmovement()内のcellのインデックスを追ってみては?
範囲を超えたインデックスを検出したら表示する、とかの方針で。
>>359 cellの各要素が指す構造体そのものはヒープに確保しているから、
cell[][][]->colorとかの構造体の中身の書き換えではなく、
cell[][][]そのものの値を書き換えているところで、
インデックス範囲外アクセスがないか探してみて。
たとえば、main()中で、
int d_max = 2;
struct celldata *cell[4][3][9];
.
.
.
printf("%d\n", d_max);
movement(cell, 1, 2, 0, d_max);
printf("%d\n", d_max);
で、
void movement(struct celldata *cell[4][3][9], int x, int y, int depth, int d_max)
{
cell[3][2][9] = 0xffffff;
}
ってすると、
2
16777215
になる。ちなみに、gcc。
363 :
338 :2007/01/09(火) 06:23:13
>>361 一応一通り見たのですが、本来の領域を超えるような
記述は見当たりませんでした。今日ずっと悩みっぱなしの頭で
探したので確実にないとは言い切れないのですが。。。
>>362 cell[][][]そのものの値を書き換えているところもないはずです。
直接ポインタのアドレスを指定したところに変えるって事ですよね?(汗
とりあえずソースをここに全部載せるにはちょっと長いので、
適当なうpろだにあげてみようかと思います。。。っ-_-)っ
364 :
デフォルトの名無しさん :2007/01/09(火) 06:27:58
#include<stdio.h> void astrcpy(char a[2], char b[2]){ int i; for( ;*b != '\0'; a++, b++){ *a = *b; } *a = '\0'; } int main(void){ char b[6]; char a[6]; astrcpy(b,"a[4]"); astrcpy(a,b); printf("a=%s\n", a); return 0; }
365 :
338 :2007/01/09(火) 06:29:43
>>365 実行していないけど、ざっとソースを見た感じ、
swap()の所と、
movement()の各階層での構造体確保の所で、cellの要素の値そのものを書き換えているよね。
movement()の領域確保のところは問題無さそうだから、
movement()から直接、間接に使ってるswap()の中でdepth,i,jの値がインデックスの範囲外になっていないかチェックしてみて。
swapの先頭にif文入れて範囲外ならprintfするようにすればいいと思う。
さすがに人様のソースをデバッグするには徹夜で根が尽きたよ。
というか、そろそろ朝ごはん食べて、出掛ける準備をしないと。
もちろん、今までの指摘が見当外れの可能性もないわけではないが……
あー depth,i,jというか、depth,x1,y1,x2,y2だな。集中力が切れてきたw
368 :
338 :2007/01/09(火) 07:00:11
朝まで付き合ってくれてありがとうございます。 movement()だけみててswap()は結構無視してましたw 今から調べてみます
if (depth < 0 || depth >= DEPTH_MAX || x1 < 0 || x1 >= HEIGHT || y1 < 0 || y1 >= WIDTH || x1 < 0 || x1 >= HEIGHT || y1 < 0 || y1 >= WIDTH) { printf("DEBUG:%d,%d,%d,%d,%d\n", depth, x1, y1, x2, y2); } をswapの先頭に入れて実行してみたらdepthが5になってたりで、 大量に出てきたなり。 movement()やdown()等で与える引数を確認してみるべし。
わかった! main()の for(d_max=1; d_max<=DEPTH_MAX; d_max++){ だ! for(d_max=1; d_max<DEPTH_MAX; d_max++){ でないとダメじゃよ。そこまで配列が確保されてない。
371 :
338 :2007/01/09(火) 07:21:51
おおおおおおおおおお;;
そんなところに落とし穴が・・・
>>369 をswap()の先頭に入れたら謎のエラーが出てきて
変なところで悪戦苦闘してたんですが、
>>370 で解決しました!
たかが条件式の=の有無でここまで手こずらされるとは。。。
というか、こんなことで朝まで付き合わせてごめんなさいm(_ _)m
そしてありがとうございました!あと少しでこのプログラムも完成しそうです;;
また何か分からない事があったらその時はよろしくお願いします。
今日はもう寝ます・・・っ-_-)っ
今日から学校始まるというのに、初日から寝過ごしそうです。
ごはん食べた。出掛けるよ。
>>371 パズルを解くプログラミングは面白そうだ。がんばって完成させて。
境界にはバグが潜み易いから気をつけないと。助けてゆかりん
ゆあきん(;´Д`)ハァハァ
374 :
デフォルトの名無しさん :2007/01/09(火) 20:40:46
関数表とか見てるとよく *foramat_string と書かれているものを見るんですが、どういう意味ですか?
typo恥ずかしい
376 :
デフォルトの名無しさん :2007/01/10(水) 17:31:06
>>374 printf()とかのフォーマット指定文字列じゃね?"%d"とか
int *p; int y[5]; p = y; はおkで int a[5]; int y[5]; a = y; はダメな理由が分かりません。 後者はa[0]にy[0]のアドレスが入れるますと思います。
aは[0]から[4]の要素を持っているintの配列型であり、ポインタ型ではないからとしか言いようがない。
379 :
デフォルトの名無しさん :2007/01/10(水) 23:39:22
p = y; のpは「変数」、yは「値」 a = y; のaは「値」、yは「値」。 値に値を代入するわけにはいかんべ?
ポインタを入れるためにあるpにはyという配列の先頭要素を指すポインタの値を入れることができる。
しかし、aは配列aの先頭要素を指すポインタとしてyのように右辺値に使うことはできても、
動的に変更できない実行前に決定される一種の定数だからa自体に代入することはできない。
>>378 の言うようにポインタ変数と配列名は似て非なるものだ。
Linuxでパラレルポート動かしたいんだけど、 あるプロセスにしかそのポートを触れない様にするのはどうすればよい? 同じコマンドを2回走らせると、 両方ともそのポートを弄れちゃうんだけど。
mutexとかでリソースを排他的に扱えばいいんじゃない?
mutexってプロセス越えられたっけ?
385 :
デフォルトの名無しさん :2007/01/11(木) 00:39:29
ゲーム改造パッチの作り方は?
387 :
デフォルトの名無しさん :2007/01/11(木) 00:43:53
いや DS
389 :
デフォルトの名無しさん :2007/01/11(木) 00:45:56
ぱわぽけ9
ねぇねぇ CreateMutexとかってさ CreateMutexの処理が完了するまで他のプロセスにCPU渡さないよね?
391 :
デフォルトの名無しさん :2007/01/11(木) 03:01:25
質問です。 スケジュール帳みたいなプログラムを作りたいのですが、全然分かりません。 西暦〜年〜月のカレンダーを表示。 スケジュールを追加しますか?→1 スケジュールを確認しますか?→2 [1の場合] 何日かを入力し、そのスケジュールを記入し、書き出す [2の場合] 何日かを入力し、そのスケジュールを表示 カレンダーの作成は分かるのですが、スケジュールの表示や書き出しが分かりません。 どなたかご教授お願いします。
>>390 CreateMutexってWinAPI?
WinAPIはよく知らないんだが、普通はアトミックな処理になっているんじゃないかな。
394 :
381 :2007/01/11(木) 05:38:58
>>382 ありがとう。調べてみる。
そのコマンド以外には全く触れなくも出来る?
そのコマンドが一回終了してパラレルからビット立てて外部装置をONにして、
もう一回そのコマンド打つとOFFになるようにしたい。
ONとOFFの間でコマンドは一旦終了するんだけど、
その間で他の人がパラレルポートを弄ったりすると困る。
>>394 コマンドが終ったらコマンドのプロセスは無くなるからそれはたぶん無理。
そういうことなら、パラレルポートのドライバか外部装置そのものにロック機構を組み入れるしかない。
そこまでできない場合、ポートが使用中かどうかを管理するデーモンを作って走らせて、
ポートを使うときには必ずそのデーモンにお伺いを立てるルールを全員に守らせられれば少し簡単になるかもしれんが。
ルール破りされれば終わりだ。
>>394 ふと気になったけど、コマンドってmutexのことをコマンドと勘違いしてたら、それは間違い。
395ではポートを使用しているプロセスに関連したコマンドのことだと勘違いしてた。
mutexはOSがサポートする一種の排他機構の名称。
>>393 そか
つかアトミックな処理・・・って?
まぁレスありがと
398 :
デフォルトの名無しさん :2007/01/11(木) 11:08:48
アトミックキトゥン
教授じゃなくて教示
400 :
デフォルトの名無しさん :2007/01/11(木) 15:10:41
boland 5.5コンパイラについての質問です。 文字列を逆順からコピーする関数のプログラミングの作業中に疑問が発生しました。 下記のNGソースはコンパイラはNGを出しませんが結果がNGです。 具体的にどのような理由で結果が正しく出ないのでしょうか。当方の実力では分かりかねますので 解説の程よろしくお願い致します。 引数1はコピー元となる文字列の先頭アドレスを渡しており引数2は逆順コピー先 となる配列の先頭アドレスを渡しております。 // NG void strrev ( char *c_array , char *c_carray ) { int i = 0 ; while ( *c_array++ ) i++ ; while ( i ) *c_carray = c_array[--i] ; *c_carray = 0x00 ; } //OK void strrev ( char *c_array , char *c_carray ) { int i=0; while ( c_array[++i] ) ; while ( i ) *c_carray++ = c_array[--i] ; *c_carray = 0x00 ; }
unix(Linuxとか)で、標準入力からバイナリデータを読み込みたいんですが FILE *fp; fp = stdin; てやると、fpはバイナリモードでopenされてますか?テキストモードでopenさ れてますか?バイナリモードでは無い場合、バイナリモードにするにはどうす れば良いでしょうか?
402 :
400 :2007/01/11(木) 15:24:37
すいません、修正です //NG void strcopy ( char *c_array , char *c_carray ) { int i=0 ; while ( c_array[i++] ) ; while ( i ) *c_carray++ = c_array[--i] ; *c_carray = 0x00 ; } //ok void strcopy ( char *c_array , char *c_carray ) { int i=0 ; while ( c_array[++i] ) ; while ( i ) *c_carray++ = c_array[--i] ; *c_carray = 0x00 ; }
>>397 それ以上分割不可能ってことで、
390の推測のように処理が途中で分割されない=割り込まれない。
unix畑なんでCreateMutexについてはよくは知らないんだが。
>>401 linuxも含めPOSIX準拠のシステムだったら、
バイナリモードとテキストモードの区別はないよ。
二つを区別するシステムでは、
例えばDOSとかならsetmodeとかの非標準関数で変更できた気がする。
406 :
400 :2007/01/11(木) 15:45:04
すいません、自己解決しました
>>400 NGは文字数をカウントしようとしているwhile(c_array[i++]);が、
0を検出した後にiをインクリメントしているので1文字多くカウントしてしまう。
逆順に文字をコピーしようとすると、0をコピー先の先頭にコピーしてしまうので、
コピー先の文字配列を0終端文字列として表示しようとすると、いきなり終ってしまう。
って自己解決したんかいw
409 :
400 :2007/01/11(木) 15:59:53
すいません、ありがとうございました。0x00を検出した時点でbreakeするものだと思っていたので。。 0x00を検出した後でもインクリメントするんですね。orz
410 :
400 :2007/01/11(木) 16:00:45
すいません、ありがとうございました。0x00を検出した時点でbreakeするものだと思っていたので。。 0x00を検出した後でもインクリメントするんですね。orz
>>403 いや以前にあるサイトで安全な排他処理について議論(てほどでもないが)あってね
でも確かこの関数が実行中は他のプロセスから再入されないことが保証されていると思ったんだけど否定されてね
ありがとん
>>405 確かに、fopenのmanだと "modeの'b'はPOSIX準拠システムだと無視される" と
ありますね。
てことは、質問からそれるんですが、バイナリデータを扱う際でもfgetc使って
いいってことでしょうか?今まではバイナリデータならfread、テキストデータ
ならfgetcと使い分けていたのですが、、、
>>410 後置インクリメントは式を評価した後に値をインクリメントする。
414 :
391 :2007/01/11(木) 17:04:36
>>405 ではないが。
>>412 fgetc()をバイナリデータに使うことには何の問題も無い。
fgetc()よりはgetc()を薦めるが(機能は同じだが、より効率が良い
可能性が高い)。
>>411 気になったのでちょっと調べてみた。
ttp://msdn.microsoft.com/library/ja/jpdllpro/html/_win32_createmutex.asp?frame=true CreateMutexの処理がアトミックであるとは書いていないね。
よく考えたら、CreateMutex自体はmutexオブジェクトのハンドルを返すだけだから、
処理の途中で割り込まれても実は問題ない。
もちろん、CreateMutex内でオブジェクトを中途半端に作成している状態で、
他が二重にオブジェクトを作成するようなことはできないようにはしているはずだけど、
CreateMutex全体で一つのクリティカルセクションになっている必要はないと思う。
CreateMutexの第2引数でTRUEを指定しても、所有権を即座に要求できるだけで、
実際に即座に所有できることは保証されていないから、
オブジェクトが作られてから所有権を得るまでに割り込まれることは織り込み済みのようだし。
CreateMutexの中で他のプロセスから再入されないことが保証されているわけではないが、
悪いようにはしないって感じかね。
MSDNなんて久しぶりに覘いたよ。
418 :
デフォルトの名無しさん :2007/01/11(木) 17:19:00
>>418 simpleXは知らないが
円の中心から点まで距離と円の半径を比べるのではだめ?
>>417 わざわざどうも・・・・
>よく考えたら、CreateMutex自体はmutexオブジェクトのハンドルを返すだけだから
そうそう、そこで WaitForSingleObjectなんだった.前のことだったから忘れていた.
mutexによって”完全な”排他処理は出来るかというやり取りだったか・・・
CreateMutexの段階では所有権を要求せずにWaitForSingleObject系に処理渡す…
最初にオブジェクトを所有してしまえば次に入ったプロセスはオブジェクトを所有できない
オブジェクトを所有できなければプロセスは待機するってわけだけど…
もしこれが再入可能だとすると最初に呼び出したプロセス=オブジェクトの所有プロセスとはならない
その人いわく「両プロセスがもし(ほぼ)同時に入った場合は”完全な”排他処理が出来ない可能性がある」と言われたわけだが…
でもいかに再入可能でもオブジェクトを所有しないプロセスが戻り値 WAIT_OBJECT_0 を返すとは思えないわけだが…
って確かこういう議論だった
んで、そのときMSサイトとかいくつか見て回ったけどその点に触れてるサイトがなくてね
んで、俺自身確証もなく否定できる明確な要素もなかったので事実上俺の負け(?)で終了したと…
まあ書いて無いってことはやっぱ保証はされないってことなのかな
実際↑こんな状況に直面することなど無いだろうからあくまでちょっとした疑問だったんだがmutexの話でたからつい便乗してしまった
と・・・・スレタイと違うこんな話に付き合ってくれてありがとね
今日からC言語を勉強しようと思い本屋に行って入門書を買おうとしたのですが、冊数が多く、 立ち読みしても何を基準に選べばいいのか分からないので、結局何も買えませんでした。 プログラム板ではどの入門書の評価が一番高いのでしょうか? スレ違いだったらごめんなさい。
422 :
418 :2007/01/11(木) 18:36:28
>>419 それで完璧です!ありがとうございました。
424 :
421 :2007/01/11(木) 19:26:08
425 :
423 :2007/01/11(木) 20:11:35
426 :
421 :2007/01/11(木) 20:16:57
>>423 専用スレあったんですね、すみませんでした。
あと
>>424 は俺じゃないです。
俺も貧乏学生なんでネットの入門サイトで十分というのはありがたいです。
本代くらいケチるなよ。
Cの基本は代替理解して何か作ってみようと思ってるんですが具体的に何か作りたいものがないのですが何をプログラムすればいいですか
タダで修得できる知識ならタダで修得した方がいいと思う。 ウンコしても見れるから俺は本も買うけどね。
>>428 それが自分で探せないなら、素質ないし、もう諦めるしかないよ
作るものが無い時期ってのは ・一つの言語の学習を完了した(つもり) ・しかし高度なモノを作るには言語以外の知識が要求される ・(自分の今のスキルでは)作るものが無いとぼやき始める ←いまここ
>>432 なるほど!
それでは私はこれから当面興味のある分野の専門知識を得ることを
考えればよいのですね!
新たな道が開けてきそうな気がしてきました。サンクス。
とでも言うと思ったかwwwww
434 :
FLAST :2007/01/11(木) 23:59:22
つ「アルゴリズム本」 本来はFORTRAN(スペル合ってるか知らん)でやるべきだが円周率でも計算させたら?
435 :
デフォルトの名無しさん :2007/01/12(金) 01:20:27
#include <stdio.h> main(){ int tanaka [4] = {}100,200,100,300}; int i; for(i = 0; i < 4;i++) tanaka[i] = tanaka[i]*1.05; return 0; } これを、繰り返し文を使わずに書くと、どのようになるんでしょうか? 何処がどうなると、ご指摘お願い致します。 その改訂ソースを書いて戴けたら幸いです。
gotoになるかなぁ…
main{ int tanaka[4] = {100, 200, 100, 300}; iter(tanaka, 4); return 0; } void iter(int *tanaka, int i) { if (!i) return; *tanaka *= *tanaka; iter(tanaka + 1, i - 1); }
438 :
437 :2007/01/12(金) 02:12:18
う。 *tanaka *= *tanaka; は以下のように訂正 *tanaka *= 1.05; だけどこれ、intにfloatをかけてintに代入しているわけで、 意味のない計算のような気もしないではないけどそれはいいのかな。
カウンタを全く使わないなら単純に tanaka[1] = tanaka[1]*1.05; : tanaka[4] = tanaka[4]*1.05; 繰り返し文さえ使わなきゃ何でもアリなら再起で #include<stdio.h> void arr_mult(int, int *); /* 再起関数の宣言 */ int main(void) { int tanaka[4] = { 100, 200, 100, 300}; /* 処理する配列 */ arr_mult(4, tanaka); /* 処理 */ return 0; } void arr_mult(int cnt, int *pMul) { /* cnt:配列の要素数 pMul:配列の先頭アドレス */ if(0 < cnt) { /* 1コ目(0番目)までは以下処理 */ cnt--; /* 今回処理する配列の添え字に */ *(pMul + cnt) = *(pMul + cnt) * 1.05; /* 添え字位置の要素を乗算処理 */ arr_mult(cnt, pMul); /* 1コ前の要素を処理 */ } } みたいのでどうでしょ。
'A` 時間差で再起既出でした吊ってきます。
441 :
435 :2007/01/12(金) 03:59:24
>>437 >>439 丁寧にありがとうございます
めちゃめちゃ、難しいですね
自分が学習してる範囲を超えていて理解し難いです。
442 :
デフォルトの名無しさん :2007/01/12(金) 04:20:03
#include <stdio.h> #defineKAMOKU5 #define NINZUU4 main() { intten[NINZUU][KAMOKU]={/*得点*/ { 73,59,92,83,75}, { 52,95,70,69,80}, { 22,19,31,41,55}, {100,99,96,85,82} }; intgoukei[NINZUU] ={0,0,0,0};/*合計点*/ doubleheikin[NINZUU];/*平均点*/ charshimei[NINZUU][20]={"太郎","次郎","三郎","四郎"};/*氏名*/ charkamokuName[KAMOKU][10] = {"国語","数学","英語","社会","理科"}; charhyouka[NINZUU];/*評価*/ intmax[NINZUU];/*最高点*/ intmin[NINZUU];/*最低点*/ intkamokuMax[KAMOKU+1];/*科目ごとの最高点*/ intkamokuMin[KAMOKU+1];/*科目ごとの最低点*/ inti,j;/*添え字*/ for(j=0;j<NINZUU;j++) { /*合計点と平均点の算出*/ for(i = 0;i < KAMOKU;i++) { goukei[j] += ten[j][i]; } heikin[j] = (double)goukei[j] / i;
443 :
デフォルトの名無しさん :2007/01/12(金) 04:21:01
/*評価を求める*/ if(heikin[j] >= 80) { hyouka[j] = 'A'; } else if(heikin[j] >= 60) { hyouka[j] = 'B'; } else { hyouka[j] = 'C'; } /*最高点・最低点を求める*/ max[j] = ten[j][0];/*この生徒の先頭のデータで初期化*/ min[j] = ten[j][0];/*この生徒の先頭のデータで初期化*/ for(i = 1;i < KAMOKU ;i++) { if(max[j] < ten[j][i]) /*データがそれまでの最高点より大きかったら*/ { max [j] = ten[j][i];/*最高点を入れ替える*/ } if(min[j] > ten[j][i])/*データがそれまでの最低点より小さかったら*/ { min [j] = ten[j][i]; /*最低点を入れ替える*/ } } }
444 :
デフォルトの名無しさん :2007/01/12(金) 04:23:22
/*科目ごとの最高点・最低点を求める*/ for(i=0;i<KAMOKU;i++) { kamokuMax[i] = ten[0][i];/*先頭の人のデータを初期値とする*/ kamokuMin[i] = ten[0][i];/*先頭の人のデータを初期値とする*/ for(j=1;j<NINZUU;j++) { if(kamokuMax[i] < ten[j][i]) { kamokuMax[i] = ten[j][i]; } if(kamokuMin[i] > ten[j][i]) { kamokuMin[i] = ten[j][i]; } } } /*合計点の最高点・最低点を求める*/ kamokuMax[i] = goukei[0];/*先頭の人のデータを初期値とする*/ kamokuMin[i] = goukei[0];/*先頭の人のデータを初期値とする*/ for(j=1;j<NINZUU;j++) { if(kamokuMax[i] < goukei[j]) { kamokuMax[i] = goukei[j]; } if(kamokuMin[i] > goukei[j]) { kamokuMin[i] = goukei[j]; } }
445 :
デフォルトの名無しさん :2007/01/12(金) 04:24:00
/*画面に表示*/ printf(" 氏名 "); for(i = 0;i<KAMOKU;i++) { printf("%-6s",kamokuName[i]); } printf("合計 平均 評価 最高点 最低点\n"); for(j=0;j<NINZUU;j++) { printf(" %-10s",shimei[j]); for(i = 0;i<KAMOKU;i++) printf("%5d ",ten[j][i]); printf("%5d%6.1f %c %5d %5d\n", goukei[j],heikin[j],hyouka[j],max[j],min[j]); } printf("最高点 "); for(j=0;j<KAMOKU+1;j++) { printf("%5d ",kamokuMax[j]); } printf("\n"); printf("最低点 "); for(j=0;j<KAMOKU+1;j++) { printf("%5d ",kamokuMin[j]); } printf("\n");
長文はソースをあぷろだにうまして
447 :
デフォルトの名無しさん :2007/01/12(金) 04:29:17
ここで、幾つか疑問があります。
一つ目は
>>intkamokuMax[KAMOKU+1];/*科目ごとの最高点*/
intkamokuMin[KAMOKU+1];/*科目ごとの最低点*/
これの +1 です。何故 +1 なのかです。
二つ目は
>>444 の
>>/*科目ごとの最高点・最低点を求める*/ と
>>/*合計点の最高点・最低点を求める*/で
i,jが途中で入れ替わっています、これが何故で何なのかが疑問です。
入門書には詳しく書かれていません。
自分で考えても混乱するばかりで、ご助言をお願いします。
448 :
デフォルトの名無しさん :2007/01/12(金) 05:15:45
構造体のメンバの1つに、別の構造体を指し示すポインタ配列を作るのは、 struct node{ struct node **link; }; でいいんでしょうか? また、これで struct node *a,*b; a=NULL; b=(struct node*)malloc(sizeof(struct node)); として、aとbを線形につなぎたいのですが、 b->link[0]=a; とすると、エラーが出てうまくいきません。 どうすればよいでしょうか? 解りにくい説明ですみません。
>>448 ポインタ配列の領域は用意してる?たとえば、
b->link = (struct node **)malloc(n_link * sizeof(struct node *));
「エラーが出た」だけでは何も報告していないのと同じなので、
コンパイル時or実行時のエラーメッセージくらいは晒さないと。
450 :
448 :2007/01/12(金) 05:39:15
>>448 コンパイルはできましたが、実行時にエラーがでて終了するだけでメッセージは出ないようでした。
ポインタ配列の領域は用意してなかったです。
ただ、配列数が未知なので、448のn_linkの値が決定できないのです。
そういう場合、どうすれば良いんでしょうか。
n_linkに大きな値を設定しておくしかないですか?
n_linkみたいなポインタ配列の大きさもnode構造体の中に入れておいて管理する。 もし、実行中にその大きさを超える数のポインタを格納する時には、 reallocで配列数を増やしたポインタ配列を再取得して元の配列をコピーする。
何にせよ無いものを使っちゃあかんよ
453 :
448 :2007/01/12(金) 05:47:53
>>451 なるほど、やってみます。
ありがとうございます。
要素数が可変になる可能性のある配列を扱うときは、 配列領域へのポインタと確保している配列サイズとのペアで常に扱うと分かりやすいと思う。
fopen( )で、 fp = fopen("/a/b/c/d/e/f/g/2ch_close.dat", "w") とした場合 に /a/b/c/d/e/f/g/ までのフォルダが無ければ自動的に作成、という機能はな いのでしょうか? また、そのような機能が無い場合は代替関数はありませんでしょうか?
>>455 C標準関数ではディレクトリの概念がない環境を考慮して、ディレクトリ操作関連の関数は一切ありません。
デファクトスタンダードであるPOSIXにはmkdir()がありますが、途中のディレクトリがなければエラーになります。
>>455 Windows限定でいいならMakeSureDirectoryPathExists
>>457 区切り文字が \ じゃなくて / であることから、多分非Windowsな人だと思われ。
>>455 system("mkdir -P /aa/bb/cc");
460 :
330 :2007/01/13(土) 04:29:55
皆さんにお聞きしたいことがあります。 C言語の勉強中にint、long int、doubleのビット数を調べることになりまして実行したところ int 32ビット long int 32ビット double 64ビット だったんです。 どうしてintとlong intが同じなんでしょうか? そういうパソコンもあるのですか? それとも壊れた?
461 :
330 :2007/01/13(土) 04:31:26
ついでに言えばノートパソなんですが、バッテリーの消費がめちゃくちゃ早くなっているんですが この32ビットのせい?
>>460 CPUが32ビットの場合、16ビットに分割するとかえって実行速度が落ちる。
んでかつてのlong型と同じ長さになった訳。
10年後にはintは64ビットになってるだろう。
>>461 全然関係ない
>>462 >CPUが32ビットの場合、16ビットに分割するとかえって実行速度が落ちる。
根拠は?
今のIntelCPUならレジスタ数も豊富だから32ビットレジスタを16ビットで使用するコストを
メモリアクセス数の削減が上回って実行速度にも貢献しそうな気がするんだけど。
>10年後にはintは64ビットになってるだろう。
これもなんだかなぁ。
longが64bitになればそれで充分な気がするんだが。
>>460 という訳で、16bitでも32bitでも処理速度的に大きく変わらないなら
元々Unix系ではintが32bitだし16bitでは何かと不便だから、という方が未だ真相に近いと思う。
ちなみに、C言語規約としてはshort, int, longが全て同じビット数でも構わない。
>>463 なんていうかなぁ・・・・
ちょっとコンピュータの基礎から勉強しなおせば?
ちなみにintが何bitかなんてどこにも決まってない。
「16bit以上で、かつそのCPUにおいて処理に最も適したbit幅」とされてるだけ。
もっとも、64bit版Winは移植性優先でint/longは32bit据え置きだが。
コンパイラによってintはlongかshortのどちらかの値とるようなことを記憶してるけど・・
どう見ても>464がミスリードしている件について。
まぁまて、どれにしろ根拠がないじゃないか
途中の議論すっとばして結論だけ書いときますね。 > どうしてintとlong intが同じなんでしょうか? たまたまコンパイラ側でそう定義されていたから > そういうパソコンもあるのですか? パソコンじゃなくてコンパイラ依存 > それとも壊れた? 壊れてない 全く正常
>>463 > 実行速度にも貢献しそうな気がするんだけど。
shortを不用意につかうと、あちこちで、short -> int の変換がはいって
遅くなりそうな気がするなあ。
ためしたことはないけど。
VC++でもgccでもint・longは32ビットですた
>>470 ばーか。
相変わらず回答になってないな
次スレでスレタイ↓に変えたら?
【馬鹿】C言語なら入門者の俺に聞け Part 7【でーす♥】
>>432 なるほど、そーだったのか。
なら俺はjava言語習得したつもりになってるのか
で、次はc++でもしてみるかって思ってんのか
よーくわかった、お前天才だわ
漏れのgccのlongは64bitだ。
intに32bitも使っちゃってメモリの無駄なんじゃないの
>>474 発想が逆。
「無駄にならないような時に int を使え」って事だよ。
どうでもいい つまらんことでもりあがる このスレは
moji.txtにはいっているアルファベットを読み込んで表示しようとしているのですが このプログラムではぜんぜんだめでした。指導してください .txtのなかみ a t r v s a #include<stdio.h> main(){ char src[8]; FILE* fp; fp=fopen("moji.txt","r"); if(fp!=NULL){ strcpy(fp,"%c",&src[8]); fclose(fp); } for(i=0;i<8;i++)printf("%c ",src[i]); }
snみませんsccpyはfscanfの間違いです
これは新しい!
1文字しか読まん上に、 str[8]のアドレス送っても仕方あるまい
for(i=0;i<n;i++) fscanf(fp,"%c",&src[i]); のまちがいです
いろいろ変えながらやってたもので・・ すみません
先週始めたばっかりでよくわかんないんだけど、 intが8bitなら-2^7〜2^7 16bitなら-2^15〜2^15まで表示出来るってこと?
>>485 とりあえず、その「表示出来る」という言葉の意味は何だ?
画面に「表示出来る」ってことか?
>>485 意味わかんないけど
これだけは言えます・・・・・違いますと
>>485 >intが8bitなら-2^7〜2^7
int は最低でも16bit以上ってC言語の規格で定めらているからそれはない。
489 :
485 :2007/01/13(土) 21:11:26
完全に意味を取り違えてるね俺・・・ もっと勉強してきます
490 :
455 :2007/01/13(土) 21:57:10
とりあえず以下のようなコードで拡張fopenを実現しようと思ったんですが、 core吐いて落ちます。(バスエラー)特に問題は無いように思うのですが… #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> FILE *_fopen(char *file, char *mode) { char delimiter[] = "/"; char *token[100]; int i, j, ret; token[0] = strtok( file, delimiter ); i = 1; while( token[i-1] != NULL ){ token[i] = strtok( NULL, delimiter ); i++; } for( j=0 ; j<i-2 ; j++ ){ ret = mkdir( token[j], 0777 ); ret = chdir( token[j] ); } return fopen( token[i-2], mode ); }
491 :
455 :2007/01/13(土) 21:57:51
int main() { FILE *fp; fp = _fopen("a/b/c/d/e/f/g/test.dat", "w"); fclose(fp); }
>490 1."_"および"__"で始まる名前はイクナイ。 2.パラメータはchar *ではなくconst char *のほうがイイ。 3.んでこの関数、"r"のときも勝手にディレクトリ作るわけ? 4.strtokとか無理して使うより再帰的にディレクトリを掘る関数を作るほうがいいんじゃね?
>>491 追加で。
strtokは与えられた文字列をいじくる。
んで、_fopenには文字列リテラルを与えてるよね。
"a/b/c/d/e/f/g/test.dat" ← これね。
このような文字列は規格上書き換えてはいけないことになっている。
が、strtokがこの文字列を書き換えてしまう。
バスエラーはひょっとしてこのせいかもしらんぞ。
494 :
455 :2007/01/14(日) 03:21:15
>>439 ほ、ほーっ、ホアアーッ!! ホアーッ!!
_fopen( ) 内で一旦バッファを確保し、strcpy(buf, file) とした上で
strtokにはbufを使う様にしたところ、buserrorが出なくなりました。
的確なご指摘まことにありがとうございました m(_ _)m
普通そういうのはSEGVになると思うんだがな なんでバスエラーなんだろう
>>494 そもそもstrtok()を使うのは如何なものかと思うわけだが。
#どうせ自分でループを回すならstrchr()で事が足りるだろ。
ていうか勝手にchdir()しちゃうのが一番よくない
任意の行数の文章をキーボードから入力して、 入力された文章をそのままディスプレイに 出力するようにしたいのですが、 どのようにすればいいでしょうか。 任意なので、1行でも10000行でもいいようにしたいのです。
>>498 // for Unix
system("cat");
// for MS-DOS/Windows
system("type con");
500 :
498 :2007/01/14(日) 22:21:27
>>499 やってみましたが、期待していた動作とは違いました。
質問の内容が間違っていたようです・・・。
書き直してみました。
任意の複数行の文章をキーボードから読み込みます。
入力はEOFが入力されるまで続けます。
任意なので、1行でも1万行でもいいのです。
EOFが入力されたら、入力された文章をそのまま出力します。
例えばどのように動作するのかというと、
Hello! How are you?(改行)
(改行)
I'm fine, thank you.(EOF)
と入力された場合、そのまま
Hello! How are you?
I'm fine, thank you.
と、出力するようにしたいのです。
>>500 #include<stdlib.h>
int main(void){
system("type con > input.txt");
system("type input.txt");
return 0;
}
502 :
498 :2007/01/14(日) 22:42:47
>>501 できました!すごいですね。
ありがとうございました。
ところで、これ以外にも方法があったりしますか?
もしあるなら、それも教えていただけると非常に勉強になります。
>>500 #include<stdio.h>
#include<stdlib.h>
#define ALLOC_UNIT (1024)
int main(void){
char *buf=NULL, *new_buf;
long buf_size=0L, input_size=0L;
int moji;
while((moji=getchar())!=EOF){
if(input_size>=buf_size){
buf_size+=ALLOC_UNIT;
new_buf=realloc(buf, buf_size);
if(new_buf==NULL){
fprintf(stderr, "\nError: Memory allocation failed.\n");
free(buf);
exit(1);
}
buf=new_buf;
}
buf[input_size++]=moji;
}
buf[input_size]='\0';
printf("%s", buf);
free(buf);
return 0;
}
504 :
503 :2007/01/14(日) 23:05:16
修正 if(input_size>=buf_size){ ↓ if(input_size+1>=buf_size){ 最後に '\0' 代入する領域が足りなかった orz
>>503 いきなり EOF を入力されたら NULL に書き込みで segv だよ
506 :
498 :2007/01/14(日) 23:58:51
>>503 ははあ。こんな方法もあるのですね。
今の自分の知識では、残念ながらよく理解できませんが・・・。
難しいことをやろうとしていたのですね・・・。
理解できるよう、これから勉強に励もうと思います。
答えていただいた方々、ありがとうございました。
これでいいかな? #include<stdio.h> #include<stdlib.h> #define ALLOC_UNIT (1024) int main(void){ char *buf=NULL, *new_buf; long buf_size=0L, input_size=0L; int moji; while(1){ if(input_size+1>=buf_size){ buf_size+=ALLOC_UNIT; new_buf=realloc(buf, buf_size); if(new_buf==NULL){ fprintf(stderr, "\nError: Memory allocation failed.\n"); free(buf); exit(1); } buf=new_buf; } moji=getchar(); if(moji==EOF) break; buf[input_size++]=moji; } buf[input_size]='\0'; printf("%s", buf); free(buf); return 0; }
遅かったか orz
早かったか orz
メモリに書くよりテンポラリファイルに書いた方が楽じゃねえか?
511 :
498 :2007/01/15(月) 00:20:11
>>506 間違えました・・・orz
訂正します
×答えていただいた方々
○答えてくださった方々
>>508 大丈夫です。ありがとうございました。
512 :
508 :2007/01/15(月) 00:23:33
誤爆しただけです
>>498 もっと簡単な例
#include <stdio.h>
int main(void)
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
return 0;
}
もっと高速にしたければ非標準のread()やwrite()のような
システムコールを使うか、
さらにシステム依存性の高いmmap()などを検討しましょう。
>>513 いや、それだと仕様を満たしていない。
EOFがくるまで黙っていなければならないが、
そのコードだとそれを保証できない。
メモリ割り当てとファイル書き込みとポインタ変数を使わない場合って考えようとしたけど そもそもスタックの容量決まってるからナンセンスか…
516 :
デフォルトの名無しさん :2007/01/16(火) 00:22:10
質問です、宜しくお願いします。 文字コードで、'A'は65、'B'は66・・・。ですから、'A'+1は'B'となり 小文字を大文字に変換するには、変換したい小文字が'a'から数えて 何番目かを調べ、'A'から数えたコードが大文字になります。 変換したい小文字のコードをcとすると、大文字のコードccは cc = c - 'a' + 'A' で求められますと、入門書に書いてありますが >>小文字を大文字に変換するには ここから以下の文が何を言っているのか 解りません・・・特にccと cc = c - 'a' + 'A' の公式みたいな奴です。
英字の大文字と小文字はそれぞれ、AからZまで連続したコードが割り当てられれている。 だから、たとえば'b'は'a' + 1、'D'は'A' + 3と同じ値になる。 そこで、'c' == 'a' + 2だから、'A'に2を加えれば'C'の値が得られるぞという話。 cの例で言う2を求めるのがc - 'a'の部分、それと'A'を足しているのでccは'C'の値になるというわけ。 という理屈を知ったら、今後は<ctype.h>のisupperを使えばいい。 楽だし、一応Cでは英字のコードがこのように順に並んでいることを要求していないので、このことがどこでも通じるとは限らない。
518 :
デフォルトの名無しさん :2007/01/16(火) 00:53:16
>>517 ご返答、ありがとうございます。
>>cの例で言う2を求めるのがc - 'a'の部分、それと'A'を足しているのでccは'C'の値になるというわけ。
すみませんが、此処の部分が、どうしても理解できませんので
何故、c - 'a'で -a なのか?そして、>>A'を足しているのでccは'C'の値になると
ccとは何処から出てくるのでしょうか?
再度優しくご助言、お願いします。
>>518 kwsk説明してあげよう。ASCIIコード表を何処かで手に入れて眺めてみると理解が早まると思う。
文字はそれぞれコードがついているのは知っていると思う。
以下のようになっている。文字(16進のコード)のように表している。
A(41) B(42) C(43) 〜 Z(5a)
a(61) b(62) c(63) 〜 z(7a)
C言語では'a'という表記と0x41という表記は同じ意味を持つ。
さてここで、'c' - 'a'を考える。この値は43-41=2だ。
で、’A'+2はどうかというと、61+2=63='c'になる。
というわけなんだがわかったかな。
520 :
デフォルトの名無しさん :2007/01/16(火) 01:12:22
>>519 丁寧な説明ありがとうございます。
今、手元のコードと照らし合わせてみています。
3分之2?程は、理解できましたが、とても難しく思います。
>>C言語では'a'という表記と0x41という表記は同じ意味を持つ。
と言う事は、'a' = 'A'なのでしょうか?
'a'は0x61でっすよね?何故、 'A'0x41なのに同じと仮定したら
同じ意味になるのでしょうか?
521 :
デフォルトの名無しさん :2007/01/16(火) 01:15:04
連続で申し訳ないのですが、 ccの意味が考えても、わかkりません・・・ Cでもcでもないし、本を見ても載っていないし・・・
キャラクタコード ぢゃねの?
>>518 数学的な式変形で
'c' == 'a' + 2
'c' - 'a' == 2
これを元に
'C' == 2 + 'A'
'C' == ('c' - 'a') + 'A'
'c'をc、'C'をccに置き換えれば、516のcc = c - 'a' + 'A'という式になる(=と==が違うのは気にするな)。
517のccも516のcc = c - 'a' + 'A'の式に出てくるccのこと、cも同じ。
>>520 それは519の勘違いだと思う。
本知らないからなんとも言えないけど cc = c - 'a' + 'A' これの右辺の c は 'c' の間違いか、あるいはcという変数に'c'の値を代入してあるんじゃない?
525 :
デフォルトの名無しさん :2007/01/16(火) 01:28:52
>>523 何から何まで、ありがとうございます。
ほぼ理解はできました。
それと、勘違いといいますと・・・?
>>520 ごめん、説明で大文字の文字コードと小文字の文字コードを丸ごと入れ替えて書いてしまったorz
通常の訂正だとわけがわからなくなるので519は丸ごと破棄して以下の説明で置き換えて欲しい。
'a'と0x61が同じ意味ってのも説明し直してみた。
---
文字はそれぞれコードがついているのは知っていると思う。
以下のようになっている。文字(16進のコード)のように表している。
A(41) B(42) C(43) 〜 Z(5a)
a(61) b(62) c(63) 〜 z(7a)
C言語では'a'という表記は文字aを表す文字コードの整数値と同じ意味を持つ。
だから、intの変数xに、「x = 'a';」と代入しても「x = 0x61;」と代入しても、
同じ値が入る。
さてここで、'c' - 'a'を考える。この値は63-61=2だ。
で、’A'+2はどうかというと、41+2=43='C'になる。
即ち 'c' - 'a' + 'A' = 'C' になる。
>>524 cはchar型の変数ということでcという名前にしただけだろ。
そこへ517がたまたま'C'と'c'を例にしたもんだから、516の頭の中でごっちゃごちゃにかき混ぜられただけに見える。
>>525 「C言語では'a'という表記と0x41という表記は同じ意味を持つ」はどう見ても誤り。
0x41では無く、0x61と書くのが正しかった、ということだろう
>>526 せっかくだから十六進文字定数'\x61'
529 :
デフォルトの名無しさん :2007/01/16(火) 01:42:02
頭が火吹きそうなので、一旦散歩でもして冷やしてきます ありがとうございましたm(__)m
昔文字定数で8進数表記使うなら'\ooo'で、16進数なら'\xhh'ってのが そうなるとしか説明無くてわけ分からなかったが、charが256通りなら 8進数なら3桁までで、16進数なら2桁で表現できるって言う極当たり前のことだったんだよなー懐かしい
ASCIIを仮定しないと根本から説明が破綻してしまう罠。
533 :
529 :2007/01/16(火) 03:37:46
理解できました! サンkすです
534 :
デフォルトの名無しさん :2007/01/16(火) 10:21:43
unsigned int array[] = { 0x31, 0x35, 0x38, 0x32, 0x30 } 例えば上記のような配列があるとき(isdigit()で真になる値が入ってる) double d に 上の例だと 15820 を入れたいのですが、 char tmp[6]; sprintf(tmp, "%c%c%c%c%c", array[0], array[1], array[2], array[3], array[4]); d = strtod(tmp, (char **)NULL); こんな書き方しか思いつかないのですが、 もっと、効率スピード最優先で良い方法があれば教えてください。
536 :
535 :2007/01/16(火) 10:27:35
すまない、呆けてました
537 :
デフォルトの名無しさん :2007/01/16(火) 11:00:21
摂氏温度(C)と華氏温度(F)は、次の式で変換できる。摂氏温度30度から、5度みに、105 度まで、それに対応する華氏温度を計算し, 下記のような対応表を作成しなさい。 F=5/9C+32.0 出力は、左右に2列に摂氏温度と華氏温度が{表}になるようにしなさい。 この問題が分からないのですが、誰か教えてくださいorz
>>534 >>534 double d;
unsigned val = 0;
unsigned *begin = array:
unsigned *end = array + (sizeof(array)/sizeof(array[0]));
for (; begin != end; ++begin)
val = val * 10 + *begin - 0x30;
d = val;
>>534 >534の方法でも、>538のように整数変換のほうが速いよ。
#どっちにしても微々たるもんだと思うのだけど。
配列を使って、10進数を16進数に変換したいのですが、 何度やっても出来ません。どなたか教えてやって下さい。
int n=743; //任意の10進数 char s[256]; //結果を保存する配列 sprintf(s, "%08X", n);
544 :
デフォルトの名無しさん :2007/01/16(火) 14:57:28
とあるプログラムのアルゴリズムを説明しなければならないのですが、 while(blank!=0){ for(i=0;i<4;i++) for(j=0;j<4;j++) if(initial[i][j]==0){ for(m=0;m<5;m++) hint[m]=0; for(n=0;n<4;n++){ if(initial[i][n]!=0) hint[initial[i][n]]=1; } for(n=0;n<4;n++){ if(initial[n][j]!=0) hint[initial[n][j]]=1; } k1=i/2; k1*=2; k2=j/2; k2*=2; for(m=k1;m<k1+2;m++) for(n=k2;n<k2+2;n++){ if(initial[m][n]!=0) hint[initial[m][n]]=1; } total=(hint[1]+hint[2]+hint[3]+hint[4]); for(m=1;m<5;m++) if(total==3&&hint[m]==0){ initial[i][j]=m; blank--; } の部分が理解できずにいます。 2*2マスの数独を解くプログラムなのですが、宜しくお願い致します。
>>542 #include <stdio.h>
main()
{
int bt[256];
int i, x, b;
scanf("%d", &x);
b=0;
while(x > 0) {
bt[b] = x % 16;
x = x / 16;
b++;
}
switch(d) {
case 10:printf("A"); break;
case 11:printf("B"); break;
case 12:printf("C"); break;
case 13:printf("D"); break;
case 14:printf("E"); break;
case 15:printf("F"); break;
}
for(i=b-1; i>=0; i--) {
printf("%d", bt[i]);
}
return 0;
}
宜しくお願いします。
そのロジックはあれだ、数毒を解いているね。
for(i=b-1; i>=0; i--) { switch(bt[i]) { case 10:printf("A"); break; case 11:printf("B"); break; case 12:printf("C"); break; case 13:printf("D"); break; case 14:printf("E"); break; case 15:printf("F"); break; default: printf("%d", bt[i]); } }
548 :
デフォルトの名無しさん :2007/01/16(火) 16:20:13
[1] 授業単元:情報 [2] 問題文(含コード&リンク): ・25個の値をrand関数(乱数)によって発生させ、一旦5×5の2次元配列に格納する(値は1から100の範囲) ・入力された値が配列内に存在するか探索する。 *存在する場合その値が格納されている配列の添え字を表示すること *存在しない場合は、その旨を表示する ・値の一覧もあわせて表示し、これらの結果をすべてファイルに出力する。 ・レポートの実行結果には、出力したテキストファイルの内容も記載すること。 ・必ず自作関数を使ったプログラムにすること ・繰り返しは何度でも探索できるようにする。その際、必ず終了する場合の入力値を示せ。 [3] 環境 [3.1] OS: (Windows等々) [3.2] コンパイラ名とバージョン: ( VC ++6.0) [3.3] 言語: C++ [4] 期限: ([2007年1月16日23:30まで] [5] その他の制限: C言語の初歩は習いました。 自分ではできません・・・ヒントでもいいのでください。。。
549 :
デフォルトの名無しさん :2007/01/16(火) 16:24:34
>>544 えーっと4x4の配列の1マスで
まず横1列をチェックして使用している数字をhint[数字]で保存
次に縦1列を同上
次に2x2のブロックを同上
未使用の数字が1個だけの場合その1マスにその数字を割り当てる
>>548 マルチかよ
こういう所は住人が被ってるから、そういう行為は悪影響
乱数はrand()で作れるよ、といったレベルのヒントでいいのか?
どこまでわかってるのかしっかり示せ
552 :
デフォルトの名無しさん :2007/01/17(水) 00:27:03
2つの値を入力してunsigned char型の変数xとyに代入してください。 また、a = x + yと b = x * yの計算を実施して表示してください。 ※printf関数を使い、下のように表示してください。 x = 1,y = 10,x + y = 11,x * y = 10 魔人でわからん…orz誰か助けてください<(_ _)>
ポインタとキャストについて (int *)とかはint型のポインタという意味だけど例えば (int *)10とするとどうなるんですか? もう一つ void *の場合 void *lpVoid; char chStr; lpVoid = &chStr; だけでキャストは必要ないのだろうか? もしくは lpVoid = (char *)chStr; するべきなのだろうか? lpVoid = (char *)&chStr; なのかわからないです。
やってみれば
>>553 (int *)10
は、よくわからんけど10番地を指すintへのポインタ値を生成する。
が、OSによってそれがどんな意味を持つのかはまちまちだし、
たいていの場合は無効なポインタ値であろう。
void *型の変数はどんなポインタ値でも保持できる。なので、
lpVoid = &chStr; // (1)
でok。キャストするならば、
lpVoid = (char *)chStr;
は(1)と意味が違っているぞ。chStrの値をcharのポインタ値と見なしている。
これは無効なポインタ値であろう。
lpVoid = (char *)&chStr;
このようにキャストするならば
lpVoid = (void *)&chStr;
とすべきだろうね。でもキャストは要らないと思う。
ちなみに組み込みなんかでは10番地に存在する関数を呼ぶなんて時に、 ((void (*)())10)(); なんてやることはままある。あるいは10番地にある何らかのシステムグローバルに、 *((int *)10) = 1; なんて代入することもある。 なんにせよ、入門の段階ではこういうコードを書くことはあるまいて。
MinGW GCC 3.4.2で #ifcdef _STDIO_H_ #define _STDIO_H_ #include <stdio.h> #endif とするとstdio.hがインクルードされないけど #ifndef _STDIO_H_ #include <stdio.h> #endif とするとインクルードされるのはなぜ?
>>557 ifcdefはifndefでいいんだよな?
両方ともインクルードはされてるよ。
上の場合はdefineがstdio.hのインクルードガードと被ってるから、
既にインクルードされたたものと判断されて読み飛ばされてるだけ。
つか、_で始まるとか__を含むのって実装系のために予約されてるから使っちゃいけないとおもた。
559 :
557 :2007/01/17(水) 06:04:36
あーすまん 順番が逆だわ #ifndef _STDIO_H_ #include <stdio.h> #define _STDIO_H_ #endif stdio.hの中に #ifndef _STDIO_H_ なんちゃらかんちゃら #endif になってるのね 今まで_STDIO_H_INCLUDED_を使ってたけど 文字数多いから変えてみたんだけど ちと吊ってくるわorz
>>559 何がしたいの?
自分のソースからstdio.hをインクルードするかしないか切り分けたいなら、ナンセンスなんだけど。
>>559 こういうときに名前が被ることがあるからユーザは _ で始まる名前や
__ を含む名前を識別子に使ってはいけない(と規格で決められている)。
564 :
デフォルトの名無しさん :2007/01/17(水) 11:14:25
#include <iostream> using namespace std; int main(void) { unsigned char x,y; cout << "2つの値を入力してください。\n"; cin >> x >> y; int a = x + y; int b = x * y; printf("x = %d, y = %d, x + y = %d, x * y = %d",x,y,a,b); return 0; } どうすればunsigned charの文字をそのまま整数として吐き出せるんでしょうか?
565 :
デフォルトの名無しさん :2007/01/17(水) 11:26:18
C言語なら俺に聞け(入門篇) Part 6
>>564 はCとC++の区別もつかないほど知能に障害があるのか?
他のC言語スレにもマルチしてるし
>>557 はヘッダファイルの多重インクルードを防止するために、
ヘッダファイル自身の中で使うイディオムだよな。
557は一体何をやりたいんだ
(・3・)エェー でも宿題じゃないのは無視だYO 難しいのも勘弁してほしいYO
571 :
529 :2007/01/17(水) 21:39:57
/********************************************************** 小文字を大文字に変換する関数 **********************************************************/ charto_upper(char c) /* c :変換する小文字*/ { charcc;/*結果*/ if ((c >= 'a' )&&( c <= 'z')) { cc = c - 'a' + 'A'; } else { cc = c; } return cc; } 以前、cc = c - 'a' + 'A';について質問したのですが それでも上のソースの解釈ができないのでので 解説しては戴けないでしょうか? 一日かけてもわかりませんでした・・・。 特に >>if ((c >= 'a' )&&( c <= 'z'))です。
if ((c >= 'a' )&&( c <= 'z')) 「cが英小文字(の範囲の文字コード)だったら」ということ
573 :
571 :2007/01/17(水) 21:45:59
>>572 レス、ありがとうごいます。
((c >= 'a' )&&( c <= 'z')) cはa以上とcはz以下なら真ですよね・・・?
何故、それが>>「cが英小文字(の範囲の文字コード)だったら」と
なりのでしょうか?
自分の解釈が違っているのでしょうか?
ご指摘戴けると、幸いです。
>cはa以上とcはz以下なら真 つまりcはa以上z以下 なんか解り難い表現だけど、このcは変数cであって文字cじゃない cをhogeだのpiyoだのと考えたらわかると思う for(moji=0;moji<26;moji++)printf("%c:%d\n",moji,moji); これ実行したらわかるんでないかな? 何がわからんのかわからんから手当たり次第に
aからzまでの文字コードの値は連続していると仮定されている。
>>573 >>cはa以上とcはz以下なら真
>>cが英小文字(の範囲の文字コード)だったら
これのどこが違うと思うのかを示せるといいと思う。
直訳と意訳の違いみたいなものなんだがなぁ・・・
>>573 aからzまでの文字コードは順番に並んでいる。
仮にaが97番とすればbは98番、ずっと進んでzは122番というわけだよ。
(c >= 'a')は『cが97番以上』を示し、
(c <= 'z')は『cが122番以下』を示す。
つまりif((c >= 'a' )&&( c <= 'z'))は『97≦c≦122であるならば』となる。
for(moji='a'; moji<'z'; moji++) printf("%c:%d\n", moji, moji);
579 :
574 :2007/01/17(水) 22:01:51
おっと訂正 for(moji=0;moji<26;moji++)printf("%c:%d\n",moji+'a',moji+'a'); こうしないと何が言いたいのかよくわからんな
580 :
571 :2007/01/17(水) 22:10:37
>>576 >>577 皆さんありがとうごいます。
意訳とか数字に(JISコード)で置き換えると
解りやすいですね。
>>579 実行するとエラーがでてしまいます。
すみません、要素数の要素[要素]はカウントする時等につかうのでしょうか?
だから、ASCIIを仮定しないと>571は破綻するんだってば。
>>583 これならどうでしょうか?
char to_upper(char c)
{
static const char cl[] = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z'};
static const char cu[] = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int i;
for (i = 0; i < sizeof(cl) / sizeof(char); i++) if (c == cl[i]) return cu[i];
return c;
}
0x 0x 0x 0x 0x 0x
586 :
585 :2007/01/18(木) 00:23:38
単純に0x20を+すればいけたんじゃなかったっけ 文字コード表見てみればいいよ
587 :
585 :2007/01/18(木) 00:25:30
おお、すごい0x20までは合ってた。 減算のほうだね
それもASCII(そしてそれを基にした文字コード)での話だな。
589 :
585 :2007/01/18(木) 00:29:33
590 :
585 :2007/01/18(木) 00:38:29
if ((c >= 'a' )&&( c <= 'z')) { cc = c - 'a' + 'A'; } else { cc = c; } ASCIIの'a'は0x61だろ charto_upper('a')という感じに実引数に'a'を入れて呼び出すと 仮引数のchar cには'a'が入るわけだ。 つまりcには0x61が入ってるという事になる。 if(c >= 'a' && c <= 'z')を文字コードに置き換えると if(c >= 0x61 && c <= 0x7A)という感じになる。 0x61〜0x7Aは小文字の英字が入ってるからつまり if(c >= 'a' && c <= 'z')を日本語に約すと 「もしcが0x61以上かつcが0x7A以下の場合」という約になるはず。 因みにcc = c - 'a' + 'A';は cc = 0x61 - 0x61 + 0x41となってるようなそうでないようなそうであるような気がする
591 :
585 :2007/01/18(木) 00:39:28
592 :
585 :2007/01/18(木) 00:44:58
if ((c >= 'a' )&&( c <= 'z')) { cc = c - 'a' + 'A'; } else { cc = c; } もしcが0x61以上かつcが0x7A以下の場合cc = c - 'a' + 'A'; そうじゃない場合(つまりelse)cc = c; という気がするかもしれないでもないかもしれない。 因みにその関数俺が書くなら char charto_upper(char c) { if (c >= 'a' && c <= 'z') { c = c - 0x20'; } return c; } こう書くよ。
まだやってたのか…
>>589-591 >>588 が言いたいのはASCIIかそれを基にしたJISやS−JISとかなら良いが
それ以外のキャラセットだと保証されねぇーぞってことよ
まぁそこまでシビアになる必要も無いと思うけどさ
594 :
585 :2007/01/18(木) 00:50:31
>>593 そんな事百も承知だが質問者はソースの解釈を求めてるんだぜ?
入門でそんな細かいキャラセットの事なんて普通やら無いと思うんだがなw
595 :
デフォルトの名無しさん :2007/01/18(木) 01:15:36
2枚の同サイズのBMP画像を照合して、相関を取る(パターン認識)プログラムを作っています。 原画像を固定して、100枚用意した画像と順番に連続して照合するには どうすればいいのか教えていただけないでしょうか! 今は原画像も入力画像も指定して開いています。 以下が作りかけのプログラムです。
596 :
デフォルトの名無しさん :2007/01/18(木) 01:18:11
/*原画像データ*/ fp=fopen("m.bmp","rb"); // mono画像ファイルを開く for(j=0; j<54; j++)h[j]=fgetc(fp);// ヘッダの読み込み wide=h[18]+h[19]*256; // 画像の幅の計算 hite=h[22]+h[23]*256;// 画像の高さの計算 cm=h[28]; if(cm=8)for(j=0; j<1024; j++)palette[j]=fgetc(fp); //mono画像データ読み込み for(y=0; y<hite; y++)for(x=0; x<wide; x++){ v=fgetc(fp); //v=濃度値 sum+=v; } ave=sum/(hite*wide);
597 :
デフォルトの名無しさん :2007/01/18(木) 01:18:52
/*入力画像データ*/ fp=fopen("p.bmp","rb"); // mono画像ファイルを開く for(j=0; j<54; j++)h[j]=fgetc(fp);// ヘッダの読み込み wd=h[18]+h[19]*256; // 画像の幅の計算 ht=h[22]+h[23]*256;// 画像の高さの計算 cm=h[28]; if(cm=8)for(j=0; j<1024; j++)palette[j]=fgetc(fp); //mono画像データ読み込み for(e=0; e<ht; e++)for(g=0; g<wd; g++){ v2=fgetc(fp); sum2+=v2; } ave2=sum2/(ht*wd);
598 :
593 :2007/01/18(木) 01:19:15
>>594 思うというかやらないし、普通アスキーコードで考える
あっ、俺は
>>588 じゃねーからなっ
勘違いすんじゃねーぞ
599 :
助けて・・・ :2007/01/18(木) 01:59:30
大学の宿題で西暦入れて十二支を出すプログラムをc言語で作れって・・ 私バカすぎて理解できない・・・if,とかforあたりまでしか授業でやってない!! 心の優しい天才様お助けください。。。
600 :
デフォルトの名無しさん :2007/01/18(木) 02:39:26
main(){ int year; char *eto[]={"ne","ushi","tora"・・・}; scanf("%d",year); printf("%s",eto[year % 12]); }
scanf("%d",year); こらこら…
子年である2008年が12の倍数+4になるから、 西暦を入力するなら[year % 12]ではなく[(year - 4) % 12]とする必要があるな。
603 :
デフォルトの名無しさん :2007/01/18(木) 03:34:19
#include <stdio.h> void printIntData(int *p, int n); void sort(int *p,int n); #defineN 6/*データ個数*/ #defineON 1/*sw:交換しました*/ #defineOFF 0/*sw:交換していません*/ main() { /*データの宣言*/ intdata[N] = {5,3,9,1,8,4}; /*最初の状態を表示*/ printIntData(data,N); /*並べ替え*/ sort(data,N); /*結果を表示*/ printf("\nソートしました\n\n"); printIntData(data,N); }
604 :
デフォルトの名無しさん :2007/01/18(木) 03:35:05
void printIntData(int *p, int n) /* p : 配列へのポインタ*/ /* n : 配列の要素数 */ { inti;/*添え字*/ for(i=0;i<n;i++) { printf("%d ",*(p+i)); } printf("\n"); }
605 :
デフォルトの名無しさん :2007/01/18(木) 03:39:59
void sort(int *p,int n) /* p : ポインタ配列へのポインタ*/ /* n : ポインタ配列の要素数 */ { inttemp;/*交換用一時保存*/ intsw;/*交換したか*/ inti,j;/*添え字*/ sw = ON; for(i = n-1; i>= 1&& sw == ON; i--) { sw = OFF; for(j = 0; j< i; j++) { /*data[j] <= data[j+1]となるようにする*/ if(*(p+j)> *(p+j+1) ) { temp = *(p+j); *(p+j) = *(p+j+1); *(p+j+1) = temp; sw = ON; } } } このソースで質問があります 一つ目は、添え字に出てくる j これは何の為の j で何処から出てきて どう使うのでしょうか? 二個目は、if(*(p+j)> *(p+j+1) ) のポインタの意味解釈ができません *(p+j)> *(p+j+1)で、(p+j)とは何なんでしょうか? 助言、宜しくお願い致します。
*(p+j)は素直にp[j]と解釈すればいいと思うよ。 #*(p+j+1)も同様に。
607 :
デフォルトの名無しさん :2007/01/18(木) 04:17:05
ありがとうございます。 同じものと思えば宜しいのですね。
608 :
330 :2007/01/18(木) 05:25:12
構造体について質問があります。 通常ポインタが指すデータは*pや*(p+i)のように「*」で指定します。 しかしポインタが指すものが構造体のメンバの場合は p->name や (p+i)->name のように「*」を使わずにアロー演算子を使います。 これはどうしてでしょうか? C言語の仕様?
609 :
330 :2007/01/18(木) 05:26:57
書き忘れです。 *p->name や *(p+i)->name みたいにならないのが分からないのです。 どうかレスよろしくお願いします。
a->nameは (*a).nameと同じだから ->演算子が気に食わないなら(*a).nameとやればいい
->ってまさにポインタって感じの使い方で好き
>>608 >606にも書いた「*(ポインタ+整数) は ポインタ[整数] と等価」と同様、
「*(構造体へのポインタ).メンバ は 構造体へのポインタ->メンバ と等価」という理屈から、
(p+i)->nameはp[i].nameと書いた方が読みやすい場合もある。
ちなみに
>>612 みたいなプログラムする上で分かりやすくするための
別な書き方をシンタックスシュガーと言う
614 :
デフォルトの名無しさん :2007/01/18(木) 12:58:08
すいません質問です。追加書き込み用でオープンしたテキストファイルをシークする方法をご教示ください。 char str[]="abcdefg", filename[]="test.dat"; FILE *fp; fp=fopen(filename,"a"); fseek(fp,-3,SEEK_END); //これが効かない!! fputs(str,fp);
>>614 fopen() の引数に "r+" 指定すればいいんじゃなくね?
以下 MSDN より
> ファイルを "a" または "a+" のアクセス種別で開くと、すべての書き込み操作が
> ファイルの終端から行われます。ファイル ポインタは fseek 関数または rewind
> 関数で移動できますが、書き込み操作を実行する前に必ずファイルの終端に戻
> されます。したがって、既存のデータに上書きされません。
617 :
614 :2007/01/18(木) 14:34:37
618 :
デフォルトの名無しさん :2007/01/18(木) 17:21:45
質問というか、間違いが無いかを教えて下さい。 double aaa(double a){ return a/(b+1.0); } 受け取ったaをbで割った数にして返す関数はこれだけでちゃんと機能していますか? bは外部変数で定義されています。 このプログラムはただの例ですが同じようなものを動かすと計算結果が出ないで空白で出力されます。
619 :
デフォルトの名無しさん :2007/01/18(木) 17:24:35
すいません自己解決しました。 実行するときの%のあとに数字だけかいててfがありませんでした。
せめて演算と出力のどちらに問題があるかくらい切り分けてから聞きに来い。
>>605 素直にp[j]]と書いて正解。
[]はシンタックスシュガーといって*(p + j)を簡易表現したもの
*(p + j)と*(j + p)は同じなわけだから極端な話j[p]でも動作するよ
最後の1行は要らないと思うぞw
a[n]は*(a+n)の「シンタックスシュガー」ではありません。
K&Rがいっていることが正しければシンタクスシュガーだね。 手元にないが「p[i]は直ちに *(p+i)に読み替えられる」 というくだりがあったと記憶している。
>>623 でもなんで自信満々に「シンタックスシュガーではありません」なんて
言えたんだろう。信憑性のある根拠を説明してほしいな。
またつまらないネタで盛り上がるw 相変わらずだなあw 所詮ここの回答者は素人から抜け出せないお馬鹿さんばかりと言うことか
,-―--、 |:::::::::::::;;;ノ |::::::::::( 」 < 自分でレベルの高い話題を振ったら? ノノノ ヽ_l ,,-┴―┴- 、 ∩_ /,|┌-[]─┐| \ ( ノ / ヽ| | バ | '、/\ / / / `./| | カ | |\ / \ ヽ| lゝ | | \__/ \ |  ̄ ̄ ̄ | ⊂|______| |l_l i l_l | | ┬ |
,-―--、 |:::::::::::::;;;ノ |::::::::::( 」 < 自分でレベルの高い話題を振ったら? ノノノ ヽ_l ,,-┴―┴- 、 ∩_ /,|┌-[]─┐| \ ( ノ / ヽ| | バ | '、/\ / / / `./| | カ | |\ / \ ヽ| lゝ | | \__/ \ |  ̄ ̄ ̄ | ⊂|______| |l_l i l_l | | ┬ |
,-―--、 |:::::::::::::;;;ノ |::::::::::( 」 < 自分でレベルの高い話題を振ったら? ノノノ ヽ_l ,,-┴―┴- 、 ∩_ /,|┌-[]─┐| \ ( ノ / ヽ| | バ | '、/\ / / / `./| | カ | |\ / \ ヽ| lゝ | | \__/ \ |  ̄ ̄ ̄ | ⊂|______| |l_l i l_l | | ┬ |
バロスw
a[n]は*(a+n)の「シンタックスシュガー」ではあるけれども a[n]と書く事によって、配列として扱いたいという意味を明示していると言える
634 :
628 :2007/01/19(金) 04:31:59
なんかウケたみたいで光栄です(涙)
>>625 まったく「シンタックスシュガー」である根拠になっていません。
636 :
デフォルトの名無しさん :2007/01/19(金) 11:39:48
初歩的な質問なんですが、 *= はどういう意味ですか?
>>636 a*=b;
は
a = a * b;
と同じ。
aに入ってた値とbを掛けて、その答えをaに代入する。
>>636 それが例えば 変数 *= 数値; のことなら 変数 = 変数 * 数値; のことです。
*=は=のポインタこれマジ
640 :
デフォルトの名無しさん :2007/01/19(金) 12:12:52
授業単位:C言語 問題文 端末から端末へと、音声を発信したさいに秒読みを開始 相手側の端末から音が送信されてきたら秒読み停止のプログラム作成 音声遅延を計る OS:windows コンパイラ名とバージョン:gcc 言語:C言語 期限:1月22日までです
>>640 > 音声を発信
> 秒読み開始/停止
> 音が送信
詳しく
642 :
デフォルトの名無しさん :2007/01/19(金) 13:49:08
DVcommXP2を使って、画像通信しながら音声を送って 遅延を計りたいんだけど・・ Aのパソコンから音声を発信してBのパソコンへ届き信号が 帰ってくるまでの遅延を計りたいです
643 :
640 :2007/01/19(金) 13:52:45
>>642 すみません名前欄書き忘れました640です
ネットワークの通信遅延を測るなら NTP(RFC 1305) 参照汁 DVcommXP2の画像エンコード/デコードにかかる時間含みで測るのなら… ハテ?
645 :
640 :2007/01/19(金) 14:12:15
DVcommXP2を使って音声の遅延を計ってみたいです NTPは時間を同調させるものみたいですが遅延ツールはどのようなものを使えば いいでしょうか?
646 :
330改めタケ :2007/01/19(金) 19:19:06
今ファイル入出力の勉強をしています。 その中でこういうプログラムに出会いました。 /*** ファイルコピーのプログラム例 ***/ #include<stdio.h> #include<stdlib.h> int main(void) { FILE*fin,*fout; charinfile[40],outfile[40],s[256]; printf("入力ファイル名="); gets(infile); printf("出力ファイル名="); gets(outfile); if( (fin=fopen(infile,"r"))==NULL) {/* 入力ファイルオープン */ printf("入力ファイルがオープンできません\n"); exit(1); } if( (fout=fopen(outfile,"w"))==NULL) {/* 出力ファイルオープン */ printf("出力ファイルがオープンできません\n"); exit(1); } while(fgets(s,256,fin)!=NULL) {/* 入力ファイルから読み込んだデータを*/ fputs(s,fout);/* 出力ファイルに書き込み*/ } fclose(fin);/* 入力ファイルクローズ */ fclose(fout);/* 出力ファイルクローズ */ return 0; }
647 :
タケ :2007/01/19(金) 19:20:24
このときに最初に出てくる FILE*fin,*fout; のFILEはなんでしょうか? 教えてください。お願いします。
649 :
タケ :2007/01/19(金) 19:22:47
ハンドルとはなんですか?
651 :
タケ :2007/01/19(金) 19:46:25
>>650 構造体の一種ですか?
そしてfopenするときにはとりあえずFILEをつければ良い?
>>651 >構造体の一種ですか?
まぁそう思っていただいて良いんじゃないですかね
ユーザが知る必要の無いものですから
>そしてfopenするときにはとりあえずFILEをつければ良い?
ファイル操作するならFILEでいいと思います
でも、リファレンスを読めば関数の戻り型がなにか書いてあるので
見聞を広めることもかねて使用する関数を調べることをオススメします
653 :
タケ :2007/01/19(金) 19:55:56
>>653 どういたしまして…
あーこう考えてみてはどうでしょうか.
FILEというものが何か分からないわけですが複数のファイルを開く場合、開いたファイルを一意に特定できなければいけませんね.
一意に特定する…方法は?
考えられるのは、”文字列で特定する”、”数値で特定する”の2種類になるわけですが
お分かりかと思いますが文字列で特定するなんていうのは論外ですね.
”特定する処理”に時間をさくわけには行きませんから.
とすると、数値ですがどーしましょうか?インデックスを割り当てる?
いやいや、簡単なことです.オープンしたファイルの情報をシステムは維持しているはずです.
なら、その情報のポインタを”一意に特定”する手段として利用すればいいわけです.
同一のメモリ番地上に複数の情報があるはずがありませんから.
つまりポイントであることがわかっていても、それの実体が何かは知る必要は無いですからね.
車操作するにはハンドルが必要だからハンドル作って(FILE*fin,*fout;) それを車に挿したり(fin=fopen(infile,"r"))挿したハンドルで操作したりfgets(s,256,fin) 使い終わった後は盗難防止にハンドルを外したり(fclose(fin))してるんだよ、でいいじゃない
656 :
タケ :2007/01/19(金) 20:29:33
>>654 さんへ
説明有難う御座います。
ただその説明を理解するのに苦労しています。馬鹿でごめんなさい。
そんな中また質問よろしいでしょうか?
あれから以下のプログラムに出会いました。
int main( void )
{
FILE *fw;
char maker[10], name[12];
int cc;
if( ( fw=fopen( "car.dat", "a" ) ) == NULL ) {
printf( "ファイルがオープンできません\n" );
exit( 1 );
このときに
if( ( fw=fopen( "car.dat", "a" ) ) == NULL ) {
の文章のcar.datに「""」が付いています。
しかし先ほどの
>>646 には
if( (fin=fopen(infile,"r"))==NULL) {/* 入力ファイルオープン */
のようにinfileには「""」がついていません。
この違いを教えていただけないでしょうか?
657 :
タケ :2007/01/19(金) 20:32:38
>>655 さんへ
めちゃくちゃ納得できました。有難う御座います。
それではちなみにそのハンドル名はFILEでなくとも違う名前でもいいのですか?
たとえばTAKEとか。
それともFILEでないとイケナイ仕様でしょうか?
>>656 >>646 の方はchar outfileという文字列へのポインタを指定しているからです
>>656 は直接文字列を指定していますね
直接文字列を与える場合は ” でくくる必要があります
>>657 ハンドル名はfinとかfout(に格納された値)の方
FILE *型(FILEじゃなくてFILE *)のハンドルを作ってる
660 :
タケ :2007/01/19(金) 20:58:47
真性現る?
文字列リテラルの内容と変数名の区別がつかない人間が、 何でファイルの取り扱いなんてやってるんだ? それ以前に学習すべき事柄が山とあると思うぞ。
663 :
デフォルトの名無しさん :2007/01/20(土) 03:29:49
#include <stdio.h> #include "h.h" /* -- h.h -- */ int main(int argc, char *argv[]){ int a[100]; pt(a, rd(argv[1], a)); return 0; } /* -- 2.c -- */ #include <stdio.h> int rd(char *f, int *a) { int *b = a; FILE *fp = fopen(f, "r"); while (fscanf(fp, "%d", b++) != EOF) ; return --b-a; } /* -- 3.c -- */ #include <stdio.h> void pt(int *a, int i) { while (i-- > 0) printf("%d\n", *a++); } ファイルの内容読み込んで表示するプログラムなんだが 関数rdで何が起きてるのか理解できません
pg実行時の引数で指定されたファイル(ファイルにはひたすら数字が書かれて いると仮定)を開いて(fopen)、それをファイル終端まで読み込んでる。 読み込んだ値は配列(a[])に格納される。
回答ありがとうございます ファイルには100行までの整数地があると仮定していますしかし、 なんでint +b=aとしているのか、なんでreturn --b-aとなっているのかわかりません
return --b-a; ↓ return (b-1)-a; ptの中で何しているのか分かってるなら、後は自分で何とかなるでしょ
bを変えたらaも変わっちゃう?
668 :
デフォルトの名無しさん :2007/01/20(土) 04:05:10
連結な無向グラフが一筆書き可能である(必要十分条件は、すべての節点が、偶数次であるか 、もしくは奇数次の節点がちょうど2つある。)かどうかを調べるプログラムを 教えてください。Cのほうです。
王貞治の本塁打数を格納するプログラムは?
int main(void) { char s[] = "王貞治の本塁打数"; return 0; }
int main(void) { int ousadaharunohonruidasuu = 868; return 0; }
#include <stdio.h> #include <string.h> int main() { char str1[] = "cross"; char str2[80],*p1,*p2; p1 = str1 + strlen(str1) -1; p2 = str2; while(p1>=str1){ *p2 = *p1; p1--; p2++;} *p2 = '\0'; ←ここでstr2の最後に塗る文字が入れられてるんですが なぜこれで最後に入るんでしょうか?この指定なら先頭に入るのではないんですか printf("%s %s",str1,str2); return 0;}
whileの中でインクリメントしてるから char *p="Hello World"; while(*p!='\0'){printf("%s\n",p);p++;} これで何やってるのか理解できるかと
inpo main(vokki)
もうね、ポインタ演算は初心者は一切禁止にしておけばいいと思うよ。
初心者のお前が言っても説得力無し
確かに・・・。自分は初心者じゃないとでも思ってるんですかね・・・(苦笑
inpo manko(vokki) chinpo shasei;
>>663 は
ファイルに100行までの整数が書き込まれてるのを読み込み格納し表示するプログラムなんですが
これを1つにつき最大5文字の文字列が書き込まれている場合読み込み格納するにはどうすればいいでしょうか?
ファイルの中身こんなん↓
aaa
bbbb
cc
ddddd
eee
char*[]を渡せばいいのですか?それともchar[][]とかですか?
682 :
675 :2007/01/20(土) 11:59:38
どこのスレかは忘れたけど、そこで紹介されていた通産省の外郭団体が編纂した コーディング規約の雛形にもポインタ演算を禁止する旨の記述がありましたが何か。 変にCずれした香具師に限ってポインタを駆使することを正当化したがるが、 保守性を考えれば避けた方が無難なのは言うまでもないのだが。 #そういえば、あのvoidもポインタ演算肯定派だったな。
チューリングマシンからちゃんと勉強すればポインタ演算は理に適っていることが分かる。 ろくに基礎を固めず高級言語でばかり遊んでいるからだろ。
C言語を学ぶ上では保守性を考えたコーディングよりポインタ演算を理解することの方が重要だと思うけど
ポインタ演算の有害性を語らずに、 団体がポインタ演算使うなって言ってたとか、レッテル張りだけの主張はおなかいっぱい。
fgetc(fp) を使うか getc(fp)で、そのあとポインタを一つずらすのは もう好みの問題でいいの? 違いがあまりよくわからん
fgetcとgetcは同じ。 ただgetcはマクロとして実装されていても良く、 そのためfgetcより高速かもしれないが、引数に副作用のある式を渡すとまずいかもしれないと言うだけ。 ポインタを1つずらすとはどういうことか。
ごめん、ポインタを1つずらすは俺の勘違いだった。 ありがと
689 :
タケ :2007/01/20(土) 14:37:22
教えて下さい。 以下のプログラムを修正してCtrl+Zを入力するまで作業を繰り返すにはどうしたらいいでしょうか? #include <stdio.h> int main( void ) { char moji; printf( "文字を入力しなさい " ); scanf( "%c", &moji ); if ( moji >= 'A' && moji <= 'Z' ) { printf( "英大文字です\n" ); } else if ( moji >= 'a' && moji <= 'z' ) { printf( "英小文字です\n" ); } else if ( moji >= '0' && moji <= '9' ) { printf( "数字です\n" ); } else { printf( "英字でも数字でもありません\n" ); } return 0; }
>>689 #include <stdio.h>
#include <ctype.h>
int main(void)
{
int b = 1;
while (1) {
int c;
if (b) printf("文字を入力しなさい ");
if ((c = getchar()) == EOF) break;
if (c == '\n') {b = 0; continue;} else b = 1;
if (isupper(c)) puts("英大文字です");
else if (islower(c)) puts("英小文字です");
else if (isdigit(c)) puts("数字です");
else puts("英字でも数字でもありません");
}
return 0;
}
691 :
デフォルトの名無しさん :2007/01/20(土) 15:53:04
#inclution <stding.h> int main(voider) { char c = "まんこ"; return ace; ]
ファイルディスクリプタが開いているか閉じているかを 確認する方法ってありますか? 検索するとisatty()とか出てくるのですが、よくわかりません。 よろしくお願いします。
694 :
タケ :2007/01/20(土) 16:55:44
printfの書式で2進法で出力するものってないですよね?
>>695 標準的にはありませんね。
特殊なコンパイラなら用意していることもあります。
>>696 そうですか。ありがとうございます。
つまり10進法を2進法に変換する場合プログラムを書かないといけないってことか・・・
再帰関数のいい練習になる
C言語ではなるべく再帰を繰り返し文に書き直した方が良いと思うよ。 オーバーヘッドが大きいからね。 関数型言語とは違うんだし。
まず書きやすい再帰で書いてからそれを繰り返しに落とすというのはよくやる。
>>695 動作は違うけど再帰版と繰り返し版
void print_binary(int value){
if(value>1) print_binary(value
>>1 );
putchar('0'+(value&1));
}
void print_binary(int value){
int i;
for(i=sizeof(int)*8-1;i>=0;i--)
putchar('0'+((value>>i)&1));
}
702 :
695 :2007/01/21(日) 01:46:49
GJ過ぎて涙でた。それもとに組んでみる。ありがとう
703 :
タケ :2007/01/21(日) 01:48:24
教えて欲しいことがあります。 以下の課題及びその答えのプログラムと説明に出会いました。 ★ 「Ctrl+Z」入力されるまで、文字列入出力を行う (書き方) #include <stdio.h>…必要 int main(void) { char str[256]; EOFではないので注意が必要 ↓ while (gets(str) != NULL) {…「Ctrl+Z が入力されるまで」 puts(str);という意味 } return 0; } どうしてEOFではなくNULLなのかが分かりません。 どうか教えてください。よろしくお願いします。
705 :
タケ :2007/01/21(日) 02:03:12
>>704 さんへ
有難う御座いました!!
なるほど、¥0に置き換えられるわけですね。
707 :
タケ :2007/01/21(日) 02:08:03
あ、早とちりしていました。 えっと¥0であればNULになるとおもうのですが、NULLなんですね。 ・・・getsはポインタ扱いだからですか?
>>707 getsはchar *を返す関数なので整数であるEOFを返すことができない。
これがEOFを返さない理由。NULLを返す理由は、エラー通知をしたかったのだろう。
「なぜ」と言われても「そうなってるから」程度の答え方しかできない。
709 :
タケ :2007/01/21(日) 02:14:56
重ね重ね有難う御座いました!!
getsは使っちゃ駄目。 fgetsを使う癖をつけよう。
うるせーよ getsを使おうがscanfを使おうが俺の勝手だろ
712 :
タケ :2007/01/21(日) 02:38:53
そういえばfgetsとscanfの違いは、「文字(列)だけ」か「数字もOKか」ということですか?
713 :
タケ :2007/01/21(日) 02:40:47
>>712 は、「getsとscanf」または「fgetsとfscanf」の違いは? に修正します。
>>701 8 は CHAR_BIT の方が良いと思う
うるせーよ getsを使おうがscanfを使おうがお前の勝手だ だから氏ね
バッファオーバーフローをプログラマが制御できないgetsと違ってscanfは気をつけて使えば別に問題ないじゃんw
718 :
デフォルトの名無しさん :2007/01/21(日) 04:54:51
朝小竜を格納するプログラム
719 :
718 :2007/01/21(日) 05:08:12
この問題を質問すべきスレがわからなかったので、ここで聞かせてください。 Cygwinを使ってCのプロジェクトを実行しようとしたのですが、 以下のようなエラーメッセージが出てしまいます。 Debug Assertion Failed! Program : C\・・・・・・・ file fgets.c Line 60 Expression : str != NULL For information・・・・・ 最初はfgetsの使い方が間違っていると思ったのですが、 違うファイルを作って試したら問題ありませんでした。 このエラーメッセージからどこがおかしいのか理解できません。 ご存知の方がいらっしゃったら教えていただけないでしょうか?
マルチいくない
>>719 エラーの起こるソースうp
(基本的には assert 関数に 0 を渡した時にそういうメッセージが出る)
723 :
718 :2007/01/21(日) 05:28:06
>>721 さん
ソースはここに載せられるには大きすぎるんです(;_;)
assert関数ですか・・・たぶん使ってないと思いますので、
ちょっとクセのある間違いをしているのかもしれません。
あと、質問する場所やはり間違ってましたか?
722さんのアドレスの先はJAVAなのですが、そこで大丈夫なんでしょうか?
>>719 おそらくはバッファオーバーフローが原因で、
書き換えてはいけない領域が書き換えられてる。
ソースがうpできないならデバッガでも使えば?
で、なんで JAVA のスレにマルチやねんw
725 :
718 :2007/01/21(日) 12:01:19
>>724 さん
領域の使いすぎはあると思います!!
実行するファイルを分割して正常に動くか確認してみます。
ありがとうございました。
ある構造体をmallocで配列とった後 マップしたファイルをmemcpyで取得していくと7回目ぐらいで エラーが出ちゃうんだけどこれって構造がまずいのか容量的にまずいのか・・
>ある構造体をmallocで配列とった後 >マップしたファイルをmemcpyで取得していくと7回目ぐらいで ??? ソースうp
728 :
726 :2007/01/21(日) 15:49:54
>>727 もうそのソース消しちゃって別のやり方でやったからあれなんだけど
原因がわからなくて気持ち悪いからはっきりさせておきたいんだよね。
ソースはこんな感じだったと記憶してる↓(C言語じゃなくてAPIだが)
LPHEADER lpHeader;
/* 指定したマッピング名のオブジェクトを取得 */
hFileMap = OpenFileMapping(FILE_MAP_WRITE, FALSE, ObjectName);
/* マッピングアドレス取得 */
lpMapAddress = (BYTE *)MapViewOfFile(hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
lpHeader = (LPHEADER)malloc(確保する数);
for(i = 0; i < 確保する数; i++)
{
オフセット = i * sizeof(HEADER);
/* この辺りで7回目でmemcpyが落ちる因みにcallocでやると10回目ぐらいでこの現象がおきる */
memcpy(lpHeader, lpMapAddress + オフセット, sizeof(HEADER));
lpHeader++;
}
構造体はchar型の配列とかを組み合わせて合計1044バイトになってる。
容量がまずいのかな。
例
typedef struct tagHEADER
{
char OOOO;
char XXXX[5];
char AAAA[80];
char BBBB;
char SSSS;
・・・・
} HEADER, *LPHEADER;
>>728 > lpHeader = (LPHEADER)malloc(確保する数);
これだと明らかにサイズが足りない。
> lpHeader = (LPHEADER)malloc(確保する数 * sizeof(HEADER));
多分これかな。
擬似コードを書くときに間違えただけで元のコードだと正しいのかも知れんけどな。
730 :
726 :2007/01/21(日) 15:56:39
あー、馬鹿だ俺 mallocの時引数をsize * sizeof(HEADER)にしなくて 普通に配列の個数を取得してたからか!? つーことは実際取得にやってたLocalAllocもsize * sizeof(HEADER)じゃないと ダメって事か。だから領域破壊が起こってたのかよ。。。
731 :
726 :2007/01/21(日) 15:57:39
732 :
726 :2007/01/21(日) 15:58:26
それにしてもこんな初歩的なミスに気づかない俺ってorz・・・。
作成したソフトウェアに必要な画像や音楽のデータをソースコード内に組み込んで ソフトウェアを起動するときには画像や音楽のデータを不要にするなんてことはできますか
できます。
そういうことができる環境もある。 たとえばWindowsではソースファイル(をコンパイルして出来たオブジェクトファイル)だけでなく、 リソースとして任意のバイナリを実行ファイルに含ませることが出来る。
具体的にどうすればできますか
コンパイラのマニュアル読め。
738 :
デフォルトの名無しさん :2007/01/21(日) 20:34:54
char* ptr; malloc(size); for(i=0; i<size; i++){ *ptr = 0; } っていうコードがあったんですが、 *ptr = 0; をforで回す意味ってなんかありますか?
なんもない
mallocで確保したメモリを代入していない
意味の無いループ
初期化していないポインタへの代入
・・・写し間違いはないか?
>>738
>>738 いろんな意味で意味の無い無駄なコードだな
理由や参考となるコードを記述せず煽るだけ・・・ いろんな意味で意味の無い馬鹿なレスだな
意味はある コードもレスも人を表す
この聞き方だと本人も動作はわかってるんだろうと推測したんだが
745 :
デフォルトの名無しさん :2007/01/21(日) 21:20:00
>>738 int i;
char* ptr=malloc(size);
//ループで'\0'に初期化
for(i=0; i < size; i++){
ptr[i] = '\0';
}
//ptrを'\0'で一括初期化
memset(ptr,'\0',size);
要は上記のように'\0'で初期化したいところを
ソースがおかしいから意味不明なソースになってると思う。
そっ でもどっかに、たとえばサイトとかにこのコードがのってた 意味があるようには思えないがサイトにのってるコードなんだから きっと何か意味が・・・・・・・・・・いや、しかし・・・・ と悩んでいたんだろ つまり的確なレスだぜ
ってゆーかcalloc
748 :
738 :2007/01/21(日) 21:31:10
char* ptr = malloc(size); の写し間違い。スマソ。 *ptr = 0; の部分は正しいです。 ptr[i] = 0; としたかっただけかな、やはり。 ある会社が配布しているデバイスドライバーのコードなんですけど、 Linuxのデバイスドライバーのコードを読むのが初めてだったんで、 なんか特殊な意味があるのかなぁ、あるわけないよなぁ、 という質問でした。
749 :
sage :2007/01/21(日) 21:33:16
main関数の最後に書くreturnなんですが、どうせそこで関数終わるはずなのに returnの後に数字を書いたりするのは何故なんだぜ? 本にはそれが戻り値とか書いてあるんだが、理解が出来ない。
750 :
デフォルトの名無しさん :2007/01/21(日) 21:44:51
int main() なら、関数として戻り値が定義されてる以上returnステートメントがいる。 ちなみに、0を返せば正常終了、それ以外は異常終了とみなされるはずです。 void main(void) なら、組み込み系(自分は書いたこと無いが)とかだと、一度立ち上げたら ずっと動かすためにvoidを使ってソースを書くらしい。
>>749 int main()
{
・・・・・・・・・・・・
・・・・・・・・・・・・
return 0;
}
システムに渡されるコード(戻り値)は何になる?
return がなかったら戻り値は何になる?
いいか、プログラムを呼び出す奴に戻り値を返す必要がある場合があるだろ? 失敗とか成功とか main()の戻り値はそーゆー時に必要なんぢゃよ
おききしたいのですが 出力は1文字づつで 縦7横15の*の平行四辺形をかくにはどうすればいいんでしょうか *************** *************** *************** *************** *************** *************** *************** *************** バージョンとこのはんたいバージョンなんですが 2重るーぷをつかわなければいけないんですけど 縦のループのあと横のループはわかるんですけど 縦にうつるときがわかりません ちなみに使用できるのはfor,while,int,printfです
>>753 int main()
{
int i,k;
for(i=0;i<7;i++){
for(k=0;k<15;k++){
printf("*");
}
printf("\n");
}
return 0;
}
とこのはんたいバージョンって?
int main()
{
int i,k;
for(i=0;i<15;i++){
for(k=0;k<7;k++){
printf("*");
}
printf("\n");
}
return 0;
}
こういうこと?
>>753 >>754 に手を加えた
#include<stdio.h>
int main(void){
int i,k;
for(i=0;i<7;i++){
for(k=0;k<i;k++) printf(" ");
for(k=0;k<15;k++) printf("*");
printf("\n");
}
printf("\n");
for(i=0;i<7;i++){
for(k=0;k<7-1-i;k++) printf(" ");
for(k=0;k<15;k++) printf("*");
printf("\n");
}
return 0;
}
757 :
749 :2007/01/21(日) 22:20:34
うーむスマン真性初心者なんで皆の言ってることも分からん。 戻り値という事の意味も分からないんだ。 今までint main(void)と書いて、最後にreturn 0;と意味も分からず書いてきたんだが 自分で関数を作るとこまで来て、例えば累乗計算の関数を書くとき int ruijo(int a, int b) { int n, ans; ans = 1; for(n = 1; n <= b; n++){ ans = ans * a; } return ans; } と本に書いてあるんだが、今までreturn 0;と書いてきたが今度はreturn ans; になってて、今までと同じreturn 0;じゃダメなのか、と思ってるんだ。 要するに戻り値というのを分かりやすく教えてほしい。
759 :
デフォルトの名無しさん :2007/01/21(日) 22:29:13
>>757 int main(void)というのは引数を取らずに関数呼び出し元にint型の値を返すってこと
だからint ruijo(int a, int b)はint型の値を二つ取り」、int型の値を返すってこと
そこで、関数で戻る時(return)にint型であるansを返している。
return 0;ってのは正常終了をシステムに伝えてる、はず
>>757 たとえばこんな関数があったとする
int nibai(int x)
{
int y;
y= 2 * x;
return y; @
}
int a;
a=nibai(10);・・・A
関数 nibaiに 10 という数字を与えると
関数 nibai は 2×10=20 という計算をしてそれを返すわけだが
戻り値ってのは @で返した値が呼び出したAに戻ってくるというもの
a には 20 が入る
これで分かるかな?
761 :
デフォルトの名無しさん :2007/01/21(日) 22:36:58
>>757 そのruijoという関数には値の受け渡しの箱が3つあると思いなされ。
コールする時はint aとint b、実行終了したら結果がint ruijo()として戻ると。
コールする側で kekka = ruijo(2, 3); とか書いてると思うが、これは関数コールであるとともに代入文でもある。
762 :
754 :2007/01/21(日) 22:37:12
763 :
デフォルトの名無しさん :2007/01/21(日) 22:39:20
>>762 >>755 ありがとうございます!
初心者ですみませんがreturn0って必要なんでしょうか
これなしになぜかコンパイルできるんですが・・・
765 :
754 :2007/01/21(日) 22:52:12
>>763 void main()
になってるんじゃない?
766 :
デフォルトの名無しさん :2007/01/21(日) 22:55:15
>>764 なるほどありがとうございます!
>>765 そうです!void main(void)
ではじめます
767 :
デフォルトの名無しさん :2007/01/21(日) 22:59:53
あともうひとつおききしたいのですが 直角三角形をかくときに最初に高さを入力するけいしきなんですが scanfで入力はいいんですが scanfの関数を縦のループにつかうんでしょうか? これも ーーーーーー | / | / | / | / |/ |\ | \ | \ | \ | \ ===== の形を*でつくりたいんです
768 :
754 :2007/01/21(日) 23:14:47
>>767 どやー
#include<stdio.h>
int main(void){
int i,k,height;
printf("入力(n)=");
scanf("%d",&height);
for(i=1;i<=height;i++){
for(k=i;k<=height;k++) printf("*");
printf("\n");
}
for(i=1;i<=height;i++){
for(k=i;0<k;k--) printf("*");
printf("\n");
}
return 0;
769 :
754 :2007/01/21(日) 23:15:53
あっ return 0; のあとに } つけてね
770 :
デフォルトの名無しさん :2007/01/21(日) 23:18:31
>>768-
>>769 なるほど・・・やっぱりスキャンフの関数を
そのままつかうんですね
ありがとうございます!
多倍長演算の仕方がわかりません。 ライブラリの使い方からさっぱりです。どなたか教えていただけませんか?
772 :
756 :2007/01/21(日) 23:35:27
スレ違いでした?
773 :
771 :2007/01/21(日) 23:36:45
ごめんなさい事故解決しました
>>772 スレ違いとは思わないが、プログラムの質が低すぎて読む気にもなれないだけ。
775 :
754 :2007/01/21(日) 23:41:58
776 :
756 :2007/01/21(日) 23:57:20
>>774 質が低い質問に答えてくれるとおもって入門篇にきたんです・・・
>>775 いえ、一応宿題ってわけではないんでそっちに行ってないです。
宿題スレで聞いたほうが良いですか?
>>776 ・他人の書いたソースなら、書いた本人に解説して貰え。
・そもそも勝手に晒していいのか?
・疑問点を聞きたいのなら、聞きたいポイントを指定しろ。
779 :
754 :2007/01/22(月) 00:09:46
>>776 >>778 が言うとおりだと思う
すべてにコメントつけるなんて無理
で、キミがどこが分からないのか、こっちはそれも分からない
どーしてもソースを理解したいならまず分解してすこしずつ稼動する範囲を広げていくのがいい
と、言っても難しいかなぁ
>>777 小数点以下7桁目まで表示したいなら、8桁目を四捨五入すれば?
printf()も指定桁の一つ下で四捨五入していることだし。
つーか、この関数を作った理由は勉強のため?
まさか"%.7f"を知らないってわけじゃないよね?
781 :
777 :2007/01/22(月) 00:12:00
>>778 >>776 って書いてあるけど文章の内容から推測して私のことですか?
そうだとしたら。
・これは自分で書いたソースですが、自分で書いたソースを勝手に晒す事は違法ですか?
・疑問点は小数部分を文字列に変換する際に誤差が生じてしまう原因とその対処法です。
782 :
777 :2007/01/22(月) 00:14:09
>>780 勉強じゃなくてファイルに出力するためです。
ありがとうございました。
早速改造してみます。
783 :
754 :2007/01/22(月) 00:15:36
>>777 具体的にどの実数を与えたとき?
だれかに検証もとめるなら成功するときと成功しないときのテストケースぐらい書いて
784 :
754 :2007/01/22(月) 00:16:46
>>780 便乗ですみませんが、"%.7f"について説明されてるサイトを教えてください。
786 :
756 :2007/01/22(月) 00:19:49
>>778 >>779 質問がアバウトすぎたんですね。失礼しました。
mainのdo-while文の中身のy--;やx--;、if文の条件と
reverseの中のif文がどういうときで場合分けしてるのか
についてお願いします。
>>782 >>780 =778だけど、>784の言う通り君宛じゃない。
勉強のためじゃないのなら、無駄な努力をする必要はない。
fprintf()で"%.7f"するか、sprintf()で"%.7f"したものをfputs()すればいい。
あーそうそう、誤差が生じる原因は、小数をdoubleで表現すると循環小数になって誤差が生じるため。
789 :
785 :2007/01/22(月) 00:30:55
ありがとうございます。 発見しました。
790 :
754 :2007/01/22(月) 00:47:43
>>786 >mainのdo-while文の中身のy--;やx--;、
scanf による入力は1〜8、しかし配列のインデックスは0〜7なので -1 してる
>reverseの中のif文がどういうときで場合分けしてるのか
文で説明するのは難しいんだが(苦手)
まずreverseの最後の引数(整数)は以下の意味があると覚えておく(仮に方向番号とする)
「1: 左下 2: 下 3: 右下 4: 左 6: 右 7: 左上 8: 上 9: 右上」
この引数はその方向のマスをチェックしていくと言う意味になる
で、オセロの動作を考えて欲しい
1.まずユーザがマスを選択する(scanf入力)
2.ユーザが指定したマスが空いているマスかチェック(if(brd[y][x] == -1))
3.reverseの方向番号が指定する最初のマス(ユーザが4.4を指定して方向番号が7(左上)なら3.3となる)が自分の持ってる石かチェック (仮に方向チェックとする)
4.3.が相手のマスであるならさらに次のreverseを呼び出す(方向番号がさす方向、上の例だと2.2をチェック)
5.3.4を繰り返す
6.自分の持ってるマスに行き着いたら自分の石の色の数値を返す(再帰的に呼び出しているので4.5.でチェックしたマスに自分の石の色が入ることになる)
mainからの
最初のreverse呼び出しがあるif文はユーザ指定のマスから方向番号により方向チェックをする
チェックの結果、相手の石ならその方向を再帰的に調べ、自分の石が見つかるか空いたあマスまで繰り返す
自分の石が見つかったならチェックしてきたマスを戻りながら自分の石にしていく
空いたマスなら相手の石の色を返すことによって石を取れない(エラー)としている
石を取れた場合、ユーザ指定のマスへの自分の石を置く
取れなかった(エラー)場合、なにもしないでユーザ入力に戻る
長文なので誤字脱字があるかも知れん
791 :
754 :2007/01/22(月) 00:53:36
>>786 プログラムの概要は↑
んで当初の質問は
>reverseの中のif文がどういうときで場合分けしてるのか
つまり石を置いた場所からそれぞれの方向に対して相手の石を取れるかチェックし、取れると判断できたなら相手の石を自分の石に変えていく
そして、方向は「1: 左下 2: 下 3: 右下 4: 左 6: 右 7: 左上 8: 上 9: 右上」 の8方向だから
if文も8つあるわけだ
792 :
754 :2007/01/22(月) 00:58:46
ここまで書いてやったのに当の質問者はすでに寝てます・・・・・だったら許せんな つか俺が眠い
793 :
756 :2007/01/22(月) 01:05:45
すみません、必死に説明とプログラムを交互に見比べてました。 眠いのに詳しく書いていただいてすみません。 引き続き読んできます。ありがとうございました
794 :
754 :2007/01/22(月) 01:14:19
>>793 いや、起きてたから俺的には許しちゃる
まぁわかんなきゃまた質問しな
ただし、ちゃんとどこがどー分からないのかを書くこと
具体的にってのは無理だと思うけど、せめてここはどういう意味か?どーしてこうなるのか?とかさ
でなければ答えようがないからな
まーがんばれ
んじゃ、オヤスミ
795 :
デフォルトの名無しさん :2007/01/22(月) 01:24:20
ポインタのポインタのポインタのポインタのポインタのポインタ
君のおかげで間違ってブックマークしていたことに気付いた ありがとう そして さようなら
ポインタポインタ
あれ、まだ消えてなかったのか んじゃ
799 :
デフォルトの名無しさん :2007/01/22(月) 03:04:47
アルゴリズムの質問っておk?
800 :
デフォルトの名無しさん :2007/01/22(月) 03:05:39
おk
801 :
タケ :2007/01/22(月) 04:37:23
教えて欲しいことがあります。 「char *fgets(char *s, int size, FILE *stream);」であるfgets()についてですが、 fgets()においてキーボード入力にするにはストリームになんと記述すればいいのでしょうか?
>>801 標準入力にキーボードが向けられてるならFILE *にstdin。
あと名前入力しなくていい。しない方がいい。
803 :
デフォルトの名無しさん :2007/01/22(月) 12:55:43
c言語勉強してるのですが 肝心のコンパイラが使えません・・・Borland++compilerってのつかってるんですけど c:\sampleディレクトリーに保存するらしいんんですけど c:\sampleディレクトリーってなんですか? 超初歩な質問ですけど 独学でやってるせいで全然わかりません・・教えてください お願いします
>>803 C言語の前にOSの勉強からしたほうがいいと思うよ。
805 :
デフォルトの名無しさん :2007/01/22(月) 15:51:01
>>803 左下の「スタート」を押して「全てのプログラム」を押して「アクセサリー
」を押して「エクスプローラー」を選ぶ。
エクスプローラーが開いたら画面の左側にフォルダ一覧が表示されていると思う。
その中に「マイコンピューター」と言うのがあるはず。
それを押すと「ローカルディスク(C:)」と言うのがあるはず。
そのローカルディスク(C:)に「sample」というディレクトリーを作る。
ちなみにディレクトリーを理解するには、まず家を考えて欲しい。
家には部屋がある。ローカルディスクが「家」、ディレクトリーが「部屋」と思ったらいい。
パソコンを使っているといろんなファイルやプログラムが増えてくる。
それを整理整頓するために、分かりやすい名前の部屋を好きなだけ作って、そこにファイルなどを入れていくわけだ。
で、今はまだローカルディスク(C:)には「sample」ディレクトリーは無いはず。
作り方は、まず先ほどのエクスプローラーのローカルディスク(C:)をマウスでクリックして
一番左上にある「ファイル(F)」を選んで、そこに「新規作成」が一番上にあるはず。
そこに「フォルダ」があるのでそれを選ぶ。その名前を「sample」にする。
まぁsampleじゃなくても好きな名前でいいけれどね。
それとフォルダはディレクトリーの別名です。
これでわかるかな?
・・・・ひょっとしておいらは思いっきり釣られてしまったのかな。
クジラ飛行机氏がテレビに出る模様
TV初出演!1/22(月)放送予定! 20:42
ウノウ(株) (
http://unoh.net ) の開発合宿がTV取材されました!
開発合宿の模様をテレビ東京さんに取材していただきました。
「ワールドビジネスサテライト」テレビ東京系列(
http://www.tv-tokyo.co.jp/wbs/ )
1/22(月)23:00〜にて放送される予定です。
たぶん、私は温泉のシーンでセミヌードが、映るのではないかと思います。
>>805 釣られたって言うか、思いっきり鼬害。
仮に釣りじゃないとしても、>803に理解できると思えないが。
"%s0"と"%s1"をいれたプログラムがあるんだけど どういう意味かわかりますか? %sの後ろに数字をいれるのは
>>808 特に意味はないな。
単純に文字列の後ろの数字を書きたいだけじゃね?
Ex.
printf("%s0", "321"); // ⇒3210
0なら0を表示 1なら1を表示
811 :
デフォルトの名無しさん :2007/01/22(月) 17:03:21
805>>ありがとうございます ローカルディスクに「sample」を作って コマンドプロンプトに【cd sample】と打ったら【バスが見つかりません】と出てしまいました 何回も質問して本当に申し訳ないのですが 今度はどうすればいいのでしょう?
813 :
デフォルトの名無しさん :2007/01/22(月) 17:37:52
811です 本当に聞いてばかりですいません コマンドラインはなんとかなったのですが ファイルの【名前.c】でsampleに保存してもコンパイルできません どうすればコンパイル できますか?
>コンパイルできません 何をしたらどういう風になってコンパイルできなかったのかな?
816 :
デフォルトの名無しさん :2007/01/22(月) 18:05:44
815>> 805さんのいうとおりsampleというディレクトリーを作ったあと コマンドプロンプト でカレントディレクトリーを【cd sample】と打って変更してsammpleに【ファイルの名前.c】で保存しても コンパイルされなくて ためしにソースコードそのまま貼ってみたら【〜は内部コマンド または外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません】 とでてきます・・ いったいどうやったらコンパイルできるのでしょう?
817 :
754 :2007/01/22(月) 18:05:48
コンパイルできないんじゃなくて sampleをフォルダが作れないから何にもできないってだけだろうな
ってゆーかここC言語のスレだろ それはUNIXとかwindowsのコマンドプロンプトの話でしょ。 全く関係ないw
その昔MS-DOSをみんな使ってたころは こういう初歩的なことを理解しないとPCをまともに使えなかったんだよな。
ここでFM-TOWNSを使っていた俺が華麗に登場。
821 :
754 :2007/01/22(月) 18:10:36
まぁ右も左も分からない人に買わせてこそシェアも広がったわけだし、MSは
>>816 コンパイルのやり方は環境依存なので、それぞれのコンパイラのスレで聞いてくれ
ハフマン記号を作るプログラムを今作ってるんだが ややこしくて頭がてんぱってきたからこのスレみたら あの質問
ソースコードを保存しただけで勝手にコンパイルしてくれる素敵なスレはここですか? この初心者君は何でもいいからC言語の初心者本を買ってきて読んだ方がいい。 Cの質問ってレベルじゃねーよ。
Cインタープリタなら、ソース保存だけでも… ま、希少種だな
だ、だから学校ではC MACHINEを使ってたのか。
828 :
754 :2007/01/22(月) 18:33:15
そういえば高校のときポケコンってあって アレCインタプリタだったな あれからCが好きになったんだ
質問です 元金と年利を入力し、複利計算をするときに 元金が2倍をこえるのに要する年数と、その時点元利合計をもとめて 利息計算は円未満切捨てなのですが 実数をintがたにキャストしてint型変数として代入すればいいともうのですが・・・ ちなみに複利は 元金1000円年利10%で りそく 元金合計 1ねんご 100(1000*10%) 1100 2年後 110(1100*10%) 1210 といった計算です
何が質問なのか全くわからんw
>>830 すみませんw
この計算プログラムをつくりたいんです
>>831 結局何を聞きたいのかわからん。
円未満切捨てで扱う数が整数のみでいいなら
int同士で計算すれば加減乗除の計算結果は
キャストするまでもなく全部intになる。
>>832 年利のときに小数点をつかうからdoubleじゃないとだめじゃないんですか?
834 :
805 :2007/01/22(月) 19:15:57
>>816 よしっ!!もう一度釣られるぞ!!イヤッホッー!!
cd sampleでsampleディレクトリに入ったら、画面に
C:\sample>
ってなっていると思う。そこに
[コンパイルしなさいという命令文][スペース][ファイル名].c
と打てばいい。
例えば命令文が bcc32 でファイル名が reidai と言うものならば
画面には
C:\sample>bcc32 reidai.c
となるように打ち込み、リターンキーを押す。
でコンパイルできるはず。
ただ命令文が何なのかはそのコンパイラに拠るからそれは自分で調べてほしいのだが・・・できるか?
>>833 そのように計算式を立てれば、そうなる。
全て整数型でやろうと思えばできなくもない。
836 :
754 :2007/01/22(月) 19:20:55
そもそもパスが通ってないってこと無いよな
>[コンパイルしなさいという命令文][スペース][ファイル名].c 間違い。
839 :
デフォルトの名無しさん :2007/01/22(月) 19:25:14
#include <stdio.h> int main(void) { double r=0.1; int base = 1000; int risoku; for(risoku = 0 ; base < 2000 ;) { risoku += base*r; base += risoku; printf("risoku = %d\n",risoku); printf("base = %d\n",base); } return 0; } 複利計算ってこれでいいんだっけ?
840 :
805 :2007/01/22(月) 19:29:07
あっそうか、パス自体通していないのか? 命令文というのは間違いか。
841 :
754 :2007/01/22(月) 19:30:47
>>840 だって実行可能ファイル、プログラムだし bcc32は
入門書も古いと対象読者が慣れてるだろうGUIでできることまでわざわざCUIで書いてるからなぁ 環境変数にパスセットするだけのバッチファイルも奈にやってるか分から無かったですよ、ええ
>>842 昔はそういうことはPCを触った段階で覚えなきゃ話にならんかったのよ。
そういう時代に書かれた本の対象読者はCUIに慣れてたのさ。
過去を現在の常識で評価するなんてまるで朝鮮人みたいだな。
いや、まあ2000年入ってからの本なんですけどね どうやら書き方が悪かったようで、すんません
>>844 こちらこそ早とちりしてすまんかった。
90年代前半を想像してたんだが。
今ひどいジェネレーションギャップを見た。
記念カキコ..._〆(゚▽゚*)
ノードを使ってハフマン記号をつくるプログラム作りたいんだけど 0.8 0.3 0.1 0.06 0.03 とかから計算はできるんだが0と1での表し方がわからないんですけど。
小数を二進数で表示したいってこと?
851 :
754 :2007/01/22(月) 21:05:13
>>850 ハフマン木が出来てるならrootから辿って
符号を割り当てていくのが普通だと思うんだが。
というか俺は学校の課題ではそうした。
>>850 URL削ったらそこのサイト面白いな。
何か得した気分だ。
作りました。 木の根の部分にポインタがさしてる状態です。 ここから一番下までポインタを動かして 一番下から下の2つずつに0と1をつけていってから ・・・ 考えれば考えるほどこんがらがってくる
>>854 木のデータ構造をどんな表現にしてるからわからないから出来ないかも知れないけど
rootから全てのleafまで走査していく過程で左に行ったら1付加、右にいったら0付加でいいんじゃないの。
そんな難しく考える事じゃない。そのサイトで言うなら
"A"に行く走査→rootから左で到着→1
"B"に行く走査→rootから右→左で到着→01
・
・
・
"H"に行く走査→rootから右→右→右→右→右→右で到着→000000
856 :
754 :2007/01/22(月) 21:23:37
>>854 どして?
>>855 と大差ない説明だけど(説明下手だからわかんなかったらこっちは見なくても・・・)
木はどういう構成なの?つまり(サイトの場合)rootに対して左側が確率が高く右側が低いよね.
再帰処理使うといいよ.
そして現在通過した枝の数字を記憶させておく
だからrootからまず左を辿る.rootからAの赤点までだから Aは 1
次にひとつ戻って今度は右の枝に向かう 通過した枝は今は 0 だよね
節についてもまだ枝があるから、こんどもまた左の枝に向かう 0 1
ここで葉についたからBは01
次にひとつ戻って今度は右の枝に向かう 0 0
するとまた節にたどりつくのでその左を・・・・・
って感じでやればいいと思うけど
いやこれ昇順、降順で値がかわってくるから
短いやつならいいけど
長いやつを入力したら値が違うんだよね。
つくったやつで試しても
>>850 のページの結果にならない・・・
>>857 俺の頭が悪いからかもしらんけど
君が何を言っているのかわからない
859 :
754 :2007/01/22(月) 23:13:44
>>857 だから最初にソートするんだよ
それから確率の小さい方から木を構成していくの
で、0 1 付加するのはrootから
860 :
754 :2007/01/22(月) 23:17:46
>>857 可能ならソースをアップして
そのほうがコメント付けやすい
>>859 はちょっと勘違いしてレスしたけど
確率の大きい順にソートするでしょ
あとは確率の値は必要ないの
木の構成で必要なのは「順番」だけ
code wordの生成に必要なのは木だけ
確率の値は必要ない
わかりました。 迷惑かけてすいませんでした。 書いてたプログラムをニ分木で全部書いたら みなさんがいってたことがわかりました
862 :
754 :2007/01/22(月) 23:48:19
>>861 迷惑だなんて思ってません
少なくとも自分は、
おもしろそーなサイト教えてくれたしね
がんばってね
863 :
デフォルトの名無しさん :2007/01/22(月) 23:50:49
多言語との複合なのですが、 VBで作ったフォームAのボタンクリックで、 Cで作ったexeファイルを実行させてその結果を フォームAのテキストボックスに表示させるには どうしたらよいのですか?
864 :
デフォルトの名無しさん :2007/01/22(月) 23:51:11
ちなみにハフマンを学校でならったとか書いているけど、大学か専門学校で習うの? まさか高校で・・・。(((゜Д゜)))
データ構造のプログラムを書くための参考書があったんだけどない。。。 左のポインタがNULLになるまで左をすすめ 右のポインタがNULLになるまで右をすすめる。 これを再帰的にやったらいいんですかね? 問題はどう0と1を付加していくかだな。
入力された文字列がファイルパスとして正しいか、を調べたいです。 単に指定された文字列のファイルが開けなかったから不正、ではなく、 Windows のパスとして不正な文字列 <>: 等、 エクスプローラで指定するとエラーになるケースを判別したいです。 すみませんが、皆さんのお知恵を貸してください。
>>863 リダイレクトとパイプ。知ってる単語連ねただけだ。
868 :
754 :2007/01/23(火) 01:37:45
>>865 ん〜〜なんか違うような.
http://ja.wikipedia.org/wiki/2%E5%88%86%E6%8E%A2%E7%B4%A2%E6%9C%A8 この図で説明すると
今8にいるのね
で左がNULLになるまで進む(1までいっちゃう)
次にひとつ上に戻る.3にもどるの
3から今度は1つだけ右にいく.6に行くわけね
6からはまた左にNULLまで進む(4にいくのね)
そしたらまた次にひとつ上に戻る.つまり6にもどる
6からは1つだけ右に行く.7ね.ここで7は左も右もNULLだから上に戻るの
6に戻る.3に戻る.8に戻る
したら今度は8からひとつだけ右に行く(10ね)
10からは左にNULLまで・・・・って言うのを繰り返す
ってゴメン.いまさらながら勘違いしてた
木の生成方法だけどひとつ連結(アルファベットを結ぶ)するたびにソートが必要だった
ゴメンナサイ
どーしよ.説明したほうがいい?
>>866 それはこのスレで扱うべき話題ではないと思う。
どこかWindowsのプログラミング関連のスレできくべき。
870 :
754 :2007/01/23(火) 02:00:05
>>865 あーーーごめんなさいぃー
リンクもダメだった
直接リンク踏んでも正常に飛ばないから
一回リンクをコピーしてからブラウザのアドレスに貼り付けて移動して・・・
それから、木の生成方法だけど説明が必要なら言ってください
うまく説明する自信は無いけど・・・
でも、今日は寝ます.寝ちゃいます
普通に飛ぶけど?
872 :
デフォルトの名無しさん :2007/01/23(火) 03:46:28
void a(char str[]) { *str=str[1]+('A'-'a'); } int main(void) { char str[10]; strcpy(str,"abcdefg"); a(str); printf("%s\n",str); return (0); } これの*str=str[1]+('A'-'a')の意味ががよくわからないんですけど、 教えてくださいませんか
>>872 str[0]=str[1]+('A'-'a');
先頭の文字を2文字目を大文字にしたものに置き換えてる。
>>873 即レスありがとうございました!
これですっきりねれますw
toupper()の方が行儀よいんだけどな
>>863 EXEの出力をファイルに落とし、VBではそのファイルから読み込んでやるのが一番楽かな。
具体的な方法は該当スレでどうぞ。
charを初期化する方法って何かありますか? char text[10] for(i=0;i<10;i++) { text[i]=' ' } みたいな原人のような方法しか思いつきません・・・しかも初期化とは言い切れないorz
おれも寝てしまいました。 基本的に左にすすめると。 そして1付加する。 if(左のポインタ==NULL) if(右のポインタ==NULL) 言葉じゃ説明できんな。。。 左も右のポインタもひとつずつNULLじゃないかをみて 基本的には左にいくんだけどもNULLになったらひとつ戻って右にいく こうかな?
>>877 目的は?
文字列として使うのが目的なら、text[0] = '\0';だが。
#つーか、コンパイルできないコードを提示して原人もへったくれもないと思うが。
>>879 目的は
あるファイルの文字を一文字ずつ読む→アルファベットが続く限りtextに一字ずつ入れる
→そうやって出来た単語を読んで単語ごとにカウントする
という風なプログラムに使用したかったんですが、textの中の全文字列を初期化しないと
次の単語を読むときに前の単語の後半の文字が残っちゃって・・・
元のcファイルは大きすぎて提示できませんでした
882 :
デフォルトの名無しさん :2007/01/23(火) 16:46:37
20MBほどの.hファイルをインクルードしようとしたらヒープ領域を使い果たしましたというエラーになりました。 うまくインクルードする方法はないでしょうか?
>>880 memset()とかstrcpy()は?
>>882 ヘッダファイルを分割して、分割した各々を#includeするヘッダファイルを作り、それを#include
20MBって何が書いてあるんだよw インクルード以外の方法を考えた方がいい。
WinXP上で無料でできるという条件で、Cのコンパイルが一番早いのはどのソフトですか?
886 :
754 :2007/01/23(火) 17:48:28
>>885 LSI-C86試食版かな。最近の最適化なんかの成果が全く入っていない、
今となっては単純なコンパイラなので爆速だろうと思う。
まったくお勧めはしないけど。規格準拠度が低いし、
16bitコードしか吐けないし、ライブラリはスモールモデルしかないし。
vc2005expとか、SDK/DDKについてくるコンパイラとかどうよ。
cl.exeがいい感じ
Cのコンパイルについては、だいぶん前から、IO律速になった、 ってUNIXな連中が言ってた記憶があるけどな。
頼む不毛な雑談は止めてくれ 雑談するなら理由もなく「〜はいい感じ」とか教科書や ウェブで調べればすぐに見つかりそうな痛いレスはやめて もう少し知識になるような雑談をしてくれないか?
>893 その書き込みがどんな知識になるのか納得いくように説明してくれたらそうしてやるよ。
正直コテハンつけないと誰が書いてるのかわかんね
つ[#ぶるじょあ]
898 :
754 :2007/01/23(火) 22:10:31
>>893 不毛な雑談って・・・・
雑談ってそういうもんじゃないのかな?
頭の悪い奴が多いな このスレは
900 :
754 :2007/01/23(火) 22:27:11
雑談の意味を知らない人もいるけどね このスレは
じゃー建設的な雑談とはなにか、ちょっと建設的に話し合ってみよーじゃないか
役所の近くには必ず喫茶店があります。何故でしょう?
903 :
754 :2007/01/23(火) 23:26:51
>>902 役所って手続きに時間かかるから
そこで待ってろよ、ってことじゃない
なんでいつまでも754をアピールしてるの? というか恥をさらしてるだけ? w
905 :
754 :2007/01/24(水) 00:05:10
>>904 別に、なんとなく
このほうがNG入れやすいでしょ
754はNGでどーぞ
苦笑
const int a = 0; const int b = a + 1; って書くと、gccで tmp.c:2: error: initializer element is not constant って怒られるんですが、 なんか書き方ないですか? #defineにしろ、以外でお願いします。
908 :
754 :2007/01/24(水) 00:32:41
>>907 const にb = a + 1 いかんでしょ
#define だめなの?
私なら
#define INIT_A 0
const int a = INIT_A;
const int b = INIT_A + 1;
とかにする
INIT_A って名前がクソとかはなしでね
>>908 コンパイラはaがconstだって認識してくれないもの?
右辺の成分は全部constな値じゃんかよ、
initializer element is not constant
とか嘘じゃん、
って思ってしまうんですが。
#defineが駄目なんじゃなくて、
それは思いつくから他にないものかと思いまして。
あざっす。
910 :
754 :2007/01/24(水) 00:51:58
>>909 const int a = 0;
const int b = a + 1;
この場合 a は変数でしょ
C++ならいいんだけど.
Cの場合 const 変数で初期化できない(みたい、規格的なことはしらないんです、無知でゴメンナサイ)
#define INIT_A 0
const int a = INIT_A;
const int b = INIT_A + 1;
この場合なら右辺も定数になるから cnost を初期化できる
911 :
754 :2007/01/24(水) 00:52:38
×Cの場合 const 変数で初期化 ○Cの場合 const を変数で初期化
912 :
909 :2007/01/24(水) 01:10:43
>>910 ああ、そうか、C++ならいいのか。
普段はC++で書いてるもんで、
なんでこんなんで怒られたっけかなーと思ってました。
913 :
デフォルトの名無しさん :2007/01/24(水) 10:44:21
整数を入力し,それを10進,16進(8桁),8進(11桁)で, 次のように並べて表示するプログラムを作成せよ。16進,8進についてはビ ット処理を行うこと。繰返し文を用いることにより,幾つかのデータで実行を 確認してみよ。 12 0000000C 000000000014 -1 FFFFFFFF 37777777777 これ教えてください(>_<)
915 :
デフォルトの名無しさん :2007/01/25(木) 00:20:48
つまりわからないってことか。。。
mixiならやさしく教えてくれるおじさんがいるのに。。。
917 :
デフォルトの名無しさん :2007/01/25(木) 00:26:51
socket.h や、 netdb.h など、特殊なインクルードファイルというのを、 無償でダウンロードできるところはありませんか?
>>917 unix用のコードをwindowsで動かそうとしてないか?
477 名前:ぼるじょあ ◆yBEncckFOU [sage] 投稿日:2007/01/25(木) 00:18:46
>>473 (・3・) エェー おもしろそうだけどそろそろ風呂入って寝るから回答できないお
土曜日までやってくれる人がいなさそうならもいらが回答してやるお
忘れっぽいから土曜日にゆうこりん似のアナ○画像か大沢あかねたんのコラ
(アナ○見せてると尚可)をうpして気づかしてくれお
478 名前:ぼるじょあ ◆yBEncckFOU [sage] 投稿日:2007/01/25(木) 00:20:08
補足: コラじゃなくても大沢あかねたんの激似のエロ画像(ア○ルが見えてると最高なんだけど・・・)
でもいいお
>>918 あ、すいませんでした、とんだ勘違いしてました。
ご教授ありがとうございます。
>>919 あ、すいませんでした、とんだ勘違いしてました。
ご教授ありがとうございます。
922 :
デフォルトの名無しさん :2007/01/25(木) 11:29:58
グローバルで仮引数を設定したあと、 ローカルでその引数をいろいろ変えていった場合 それは関数をまたいで保存されるのでしょうか?
>>922 日本語で(ry
エスパーしてみる
>グローバルで仮引数を設定
関数の引数にグローバル変数を渡した。
>ローカルでその引数をいろいろ変えた
関数の内部において、引数を書き換えた。
>それは関数をまたいで保存されるのでしょうか?
グローバル変数の値はどうなるよ?
グローバル変数の値は、関数内部の引数書き換えでは変わらない
int global = 10;
void func(int arg) { arg++; }
void hoge(void)
{
func(global);
func(global);
.... /* 何回 func() を呼ぼうが global は 10 のまま */
}
924 :
デフォルトの名無しさん :2007/01/25(木) 11:57:35
>>923 お察しいただいた内容ですw
なるほど外側で設定した値は変わらないんですね。
ありがとうございました
>>924 ポインタまわりで混乱するかもなw
char buffer[10] = "123";
char *ptr = global_buffer;
void func(char *p) { p[0]++; }
void hoge(void)
{
func(ptr); /* ptr は buffer の先頭を指している が buffer の中身が変わって "223" になる */
func(ptr); /* ptr は buffer の先頭を指している が buffer の中身が変わって "323" になる */
}
func は 「ポインタを書き換えている」 のではなく 「ポインタが示している場所の内容」 を書き換えている
926 :
925 :2007/01/25(木) 12:07:37
× char *ptr = global_buffer; ○ char *ptr = buffer;
927 :
25 :2007/01/25(木) 13:48:42
/* kimatsu2.c */ /* [メモリの内容とメモリの番地(アドレス)の表示実験] */ /* 変数dataの値をポインタ変数ptrを用いて表示せよ */ #include<stdio.h>/* getchar()関数を使う時に、必要 */ main() { int data=123; int *ptr;/* ポインタ変数の宣言 */ ptr=?????;/* 変数dataのアドレスをポインタ変数に代入 */ printf("\n変数dataの値 = %d\n\n",data); /* 変数dataのアドレスを10進数及び16進数で表示せよ */ printf("変数dataのアドレス = %? @10進表示, %?@16進表示\n\n",?data,?data); /* 変数dataのアドレスをポインタ変数ptrを使って表示せよ */ printf("ポインタ変数ptrの値= %u\n\n",ptr); /* 変数dataの値をポインタ変数ptrを使って表示せよ */ printf("ポインタ *ptrの値= %d\n\n",????); /* ポインタ変数ptrのアドレスを10進数及び16進数で表示せよ */ printf("ポインタ変数ptrのアドレス = %? @10進表示 ,%? @16進表示\n\n",&ptr,&ptr); printf("\n\n何かキーを押してくれ"); getchar();/* キーを押すまで前文で停止している */ } わかりますか?
928 :
754 :2007/01/25(木) 13:54:49
>>927 #include<stdio.h>/* getchar()関数を使う時に、必要 */
main()
{
int data=123;
int *ptr;/* ポインタ変数の宣言 */
ptr=&data;/* 変数dataのアドレスをポインタ変数に代入 */
printf("\n変数dataの値 = %d\n\n",data);
/* 変数dataのアドレスを10進数及び16進数で表示せよ */
printf("変数dataのアドレス = %d @10進表示, %x@16進表示\n\n",&data,&data);
/* 変数dataのアドレスをポインタ変数ptrを使って表示せよ */
printf("ポインタ変数ptrの値= %u\n\n",ptr);
/* 変数dataの値をポインタ変数ptrを使って表示せよ */
printf("ポインタ *ptrの値= %d\n\n",*ptr);
/* ポインタ変数ptrのアドレスを10進数及び16進数で表示せよ */
printf("ポインタ変数ptrのアドレス = %d @10進表示 ,%x @16進表示\n\n",&ptr,&ptr);
printf("\n\n何かキーを押してくれ");
getchar();/* キーを押すまで前文で停止している */
}
929 :
デフォルトの名無しさん :2007/01/25(木) 13:56:57
>>925 ポインタを使えばいいんですね。
ありがとうございました。よく分かりました。
930 :
25 :2007/01/25(木) 14:02:59
928>ありがとうございます。 /* ポインタ変数を使って文字列の長さを求めよ。但しスペースや","、"."は 一文字とカウントする。 */ #include<stdio.h>/* getchar()関数を使用する為に必要 */ main() { char moji[]="To be or not to be,that is the problem.";/* →39文字 */ char *ptr;/* ポインタ変数の宣言 */ int ls=0;/* 文字列の長さの格納場所 */ ???=????; /* ポインタ変数に文字列を代入 */ while (*ptr??'\0'){ /* 文字列の長さのカウント */ ptr++; ls++; } printf("\"%s\" の文字数 = %d文字\n",moji,??); printf("\n\n何かキーを押せ"); getchar();/* 任意のキー入力待ち */ } じゃあこれもわかりますか?
931 :
754 :2007/01/25(木) 14:11:32
>>930 #include<stdio.h>/* getchar()関数を使用する為に必要 */
main()
{
char moji[]="To be or not to be,that is the problem.";/* →39文字 */
char *ptr;/* ポインタ変数の宣言 */
int ls=0;/* 文字列の長さの格納場所 */
ptr=moji; /* ポインタ変数に文字列を代入 */
while (*ptr!='\0'){ /* 文字列の長さのカウント */
ptr++;
ls++;
}
printf("\"%s\" の文字数 = %d文字\n",moji,ls);
printf("\n\n何かキーを押せ");
getchar();/* 任意のキー入力待ち */
}
932 :
25 :2007/01/25(木) 14:15:50
931>いつもいつもすみません #include<stdio.h>/* getchar()関数を使用する為に必要 */ main() { char moji[]="To be or not to be,that is the problem.";/* →39文字 */ char *ptr;/* ポインタ変数の宣言 */ int ls=0;/* 文字列の長さの格納場所 */ ptr=moji; /* ポインタ変数に文字列を代入 */ while (*ptr!='\0'){ /* 文字列の長さのカウント */ ptr++; ls++; } printf("\"%s\" の文字数 = %d文字\n",moji,ls); printf("\n\n何かキーを押せ"); getchar();/* 任意のキー入力待ち */ } これはどうでしょう?
933 :
754 :2007/01/25(木) 14:20:38
934 :
754 :2007/01/25(木) 14:41:49
手取り足取り教えてるとつけあがる、ってことだな
再帰のプログラム struct are{ struct are *p0; struct are *p1; } void saiki(struct are *tp) { struct are *p; if(p==NULL) return; saiki(p->p0); saiki(p->p1); } 前順走査を再帰でやりたいんだけど ノードの左のノードへつなぐポインタはp0 右のノードへつなぐポインタをp1とする。 まあハフマンなんだけどね。 あるノードの中の値を前順走査で探したいんだけど その経路をつけながらやるのってどうやればいいですか?
937 :
754 :2007/01/25(木) 18:02:13
>>936 これでどーかな?
p0 p1 じゃなくて left right の方が分かりやすいと思うけどまぁいいや
void saiki(struct are *tp)
{
struct are *p;
if(p==NULL) return; // rootのsaiki呼び出しでNULLチェック入れてるならいらない
if(p->p0 != NULL) saiki(p->p0);
if(p->p1 != NULL) saiki(p->p1);
}
938 :
754 :2007/01/25(木) 18:03:22
>>936 あっゴメン、経路のこと忘れてた
ちょっとまってね
939 :
754 :2007/01/25(木) 18:24:59
>>936 こういう手法が許されるかは分からないけど
struct are{
struct are *p0;
struct are *p1;
struct are *next;
}
struct are *p_prev=NULL;// グローバルで宣言
// p_prev がNULL は 現在の p がrootということになる
void saiki(struct are *p)
{
if(p==NULL) return; // rootのsaiki呼び出しでNULLチェック入れてるならいらない
if(Prev!=NULL) prev->next=p;
prev=p;
if(p->p0 != NULL) saiki(p->p0);
if(p->p1 != NULL) saiki(p->p1);
}
あとはrootの struct are から nextを辿ればそれが経路になる
next==NULLで経路探索終了
実際に動かしてないからバグあるかも
>>939 だったら
struct node_tag
{
struct node_tag *parent, *child_left, *child_right;
}
てなかんじだろ?
双方向の二分木ってところか
941 :
936 :2007/01/25(木) 18:41:23
再帰をして経路を出す方法でお願いします。 何かのノードを探索するプログラムはできるんだけど それの経路となるとね
しかしローマ字関数名ってなあ・・・学校でそう教えてるのかな?
>>941 宿題?
ここは作ってもらうところじゃないぞ
944 :
936 :2007/01/25(木) 19:10:34
いや宿題の一部だし。 再帰を使ってニ分木の前順走査をしたときの 経路の出し方がわからなくてね。
>>944 >>937-939 に対して何か言うことないの?
経路を出すって何をしたいんだ?
struct areに何らかの値を持たせて出力でもしたいのか、
ノードのアドレスでも出力するのか
だから宿題はスレ違いだって言ってるんじゃないのか
>>946 あなたの言い方だと質問=宿題だな
質問も無理ならなんなんだこのスレ
948 :
936 :2007/01/25(木) 19:25:26
>>937 ありがとうございます。
参考にさせていただきます。
再帰を使っての経路の表示の仕方は少し難しいようですね
950 :
754 :2007/01/25(木) 19:36:03
>>940 >>939 ののコードの prev を parrennt にしろってこと?
>>944 >経路の出し方がわからなくてね
どう出したいの?
root から だどる道を知りたいんでしょ
戻るときの一度通過した節も必要ってこと?
経路が root->left->root->right てこと?
宿題スレは実質宿題丸投げスレだから せっかく自分で努力しようという学生の向上心を無碍に扱うのもどうかと
952 :
754 :2007/01/25(木) 19:39:48
953 :
936 :2007/01/25(木) 19:41:18
いや 5個くらいのノードにはいってる割合をみつけて、 rootからそのノードまでの道を表示したいんです。 木で表示してあって一番上がroot,left,rightは用います。 左にいくときは1を表示、右に行く時は0を表示したいんです。
954 :
936 :2007/01/25(木) 19:44:51
>>953 > 左にいくときは1を表示、右に行く時は0を表示したいんです。
>>954 > probabilityとcode wordを表示したいのです
最初からそう書けよ
saiki関数の引数に0or1を格納するための配列と、格納した数(=深さ)でも渡せばいいと思う
956 :
754 :2007/01/25(木) 19:50:08
>>953-954 いや、君があのときに人ってのは分かってるの
それを知ってる上でレスしたんだけど
この前も書いたけど
木を作る段階でね
1.確率が低い2つを見つける
2.あわせてひとつの節にする
1と2を繰り返して木を作るんだけど、それは出来たの?
957 :
936 :2007/01/25(木) 19:53:24
はいできました。 rootが一番上をさすようになってます
958 :
754 :2007/01/25(木) 20:08:47
知っててコード書いたけどよく見りゃ意味の無いコードだわ
>>939 >>957 木の形は表のTree of Code と同じになってる?
root から左がAで右がH
959 :
754 :2007/01/25(木) 20:15:01
あーあと経路探索は rootから A, B, C,・・・H までのすべての経路が欲しいわけだよね それって一度にA〜Hまでの経路を出すの? それともAの経路が欲しいと思った時に初めて経路探索するようにするの? (Bが欲しいと思ったらroot → Bの経路を出力のように)
960 :
936 :2007/01/25(木) 20:16:59
ひとつの経路のみでいいです。 それがわかればそれをループすればいいですから。 入力の配列も作りなおさないといけないけど
961 :
754 :2007/01/25(木) 20:31:05
>>960 こんな感じかなぁ
引数のstruct are *targetは探索したい葉のアドレス
文字で、たとえば 'A ' や'B' とかで検索したいならchar alpha とかにして
struct are{
struct are *p0;
struct are *p1;
}
char codeword[10];
int saiki(struct are *target,struct are *p,int level,codeword[])
{
if(p==NULL) return 0; // rootのsaiki呼び出しでNULLチェック入れてるならいらない
if( p==target)
{
codeword[level] = '\0';
return 1;
}
if(p->p0 != NULL)
{
codeword[level] = '1';
if(saiki(target,p->p0,level+1,codeword)==1) return 1;
}
if(p->p1 != NULL)
{
codeword[level] = '0';
if(saiki(target,p->p1,level+1,codeword)==1) return 1;
}
return 0;
}
>>936 のやる気が感じられないなあ。
一問一答が延々と続いてるのは質問の仕方等が悪いせいだって事に気づいてないのかね。
void saiki(struct are *tp, int *a, int idx)
{
struct are *p;
if(p==NULL) {
int i;
for(i=0;i<idx;i++) {
printf("%d ", a[i]);
}
printf("\n");
return;
}
a[idx] = 1;
saiki(p->p0, a, idx+1);
a[idx] = 0;
saiki(p->p1, a, idx+1);
}
コンパイルさえもしてないのでいい加減だが、こんなのじゃだめなのかな
963 :
936 :2007/01/25(木) 20:42:50
964 :
754 :2007/01/25(木) 20:45:51
965 :
936 :2007/01/26(金) 00:16:29
num prob
0 0.34
1 0.23
2 0.20
3 0.10のnumとprobを構造体のメンバとして
このノードを作り木を作ったんだけど、それのnumをターゲットとしてできるように
main関数で0から3をループしてをの変数を、
その中に
>>961 さんのプログラムを
参考にして作ったプログラムに、引数として送るように
プログラム作ってようやくコンパイル通ったけど出力できない。。。
わかりにくい文章ですまそ。
このin levelっていう引数って何を送ってるのですか?
numと同じと考えていいのでしょうか?
966 :
754 :2007/01/26(金) 00:36:25
>>965 prob の型は何?
int lebelは節(実際は枝)の深さでありcodewordのインデックスになる
rootの時0で、rootから次の節へ行くたびに1増える.
>>954 のサイトでいうとrootからHへ行くとする
rootから1番目の節までがlebel0、1番目から2番目の節がlebel1ってなって最後の枝は5になる
現在の節から左の節にいく場合はlebelで指定されるcodeword[lebel]に1が、
右にいく場合はcodeword[lebel]に0が入る
葉に到達した場合はcodewordの最後に'\0'が入り
これを文字列出力すれば サイトのcodewordと同じになるはずです
>numと同じと考えていいのでしょうか?
違います
木を作ったソースが気になるのですが、
前にも言いましたがソースを提示してもらったほうが解説しやすいです
まぁ私も人に自分のソース見せるのは恥ずかしくてイヤなんですけどね
967 :
936 :2007/01/26(金) 01:01:04
struct are{ struct are *root; struct are *pointer0; struct are *pointer1; double prob; //割合(0.50,0.31,0.22,0.10・・・) int node_num; //ノードの数(1とか2とか int node; //ノード列(0,1,2,3,4) }; main(){ struct are *root; int i,j; char prob1[N],codeword[10]={'\0'}; 〜 for(j=0;j<N;j++){ prob1[j]=saiki(root,j,j,codeword); printf("%s",prob1[j]); } int saiki(struct are *p,int j,int level,char *codeword) { if(p=NULL)return 0; if((p->node)==j){ codeword[level] ='\0'; return 1; } else if(p->pointer0 != NULL){ codeword[level] ='1'; if(saiki((p->pointer0),j,level+1,codeword)==1)return 1; } else if(p->pointer1 != NULL){ codeword[level] ='0'; if(saiki((p->pointer1),j,level+1,codeword)==1) return 1; } return 0; }
968 :
936 :2007/01/26(金) 01:07:54
木はある配列に0からprobにいれて、N−1までいれて PのポインタがN−1とN−2番目のノードをさすようにして その2つのprobを足してpのprobにいれる。そしてpがひとつ上を指すようにする 一回ループすることにソートかけてるので あってると思います
969 :
754 :2007/01/26(金) 01:12:54
>>965 >このノードを作り木を作ったんだけど
分かりづらいかもしれませんが木はこのように出来ましたか?
ちなみに木構成はrootを上にしたとき 0が左側、3が右側です
root ------- 0 (0.34)
|
----------1 (0.23)
|
------2 (0.20)
|
--- 3 (0.10)
木の作成以外を書いてみました
このコードは木の構造が重要です
しかし木の構成が分からないので動作チェックはしていません
http://sa-wiki.com/upload/src/up0094.txt >>967 のコードは今チェックしてみます
970 :
754 :2007/01/26(金) 01:24:02
>>967-968 for(j=0;j<N;j++){
prob1[j]=saiki(root,j,j,codeword);
printf("%s",prob1[j]);
}
このコードが違います
saiki(...) が返す 0 および 1 は再起処理を継続するかしないかのフラグです
目的のノードが見つかったとき関数saiki(...)は1を返すようにしています
そして関数saiki(...)は自分が呼んだsaiki(...)から1が返ると以降の処理をやめ、return 1を返します
これにより呼び出し元の関数saiki(...)自身もすぐに終了するというものです
ただしくは
for(j=0;j<N;j++){
prob1[j]=saiki(root,j,j,prob1[j],codeword);
printf("%s",prob1[j],codeword);
}
です.
ただし処理ごとに表示しているので配列の必要はないんですけど.
971 :
754 :2007/01/26(金) 01:26:33
>>967-968 ×
prob1[j]=saiki(root,j,j,prob1[j],codeword);
これだと prob1[j],codeword を破壊してしまいます
○
saiki(root,j,j,prob1[j],codeword);
main においては戻り値はいりません
972 :
936 :2007/01/26(金) 01:29:03
973 :
754 :2007/01/26(金) 01:50:01
>>967-968 もう2点
関数saiki(...)のはじめの方の
if(p=NULL)return 0;
ですが、不正な代入です.等価式ではないです
if(p==NULL)return 0;
にしてください
あとmainの表示処理
>>970 のprintf("%s",prob1[j],codeword);の部分ですが
改行を入れたほうが...printf("%s\n",prob1[j],codeword);
今のところ以上です.
明日早出なの忘れてました.
私、今日はもう寝ますので...と、思ったらレス付いてる.
えぇ〜と、明日で良いですか?ソースチェック...
たぶん私以外の人が見てくれると思いますが.
>>972 のソースは略したソースと同じものですよね.省略して無い部分については...
>>972 のソースは明日チェックします.
時間は夜7時以降だと思いますけど.
先に寝かせていただきますね.ゴメンナサイ
では、お疲れ様でしたぁ.
明日には次スレ立ってるのかなぁ((ひとりごと・・・・
974 :
936 :2007/01/26(金) 01:52:55
>>973 すいませんP=NULLのとこなおしたら
それらしいのでました。
ありがとうございました
「続行するには何かキーを押してください」状態を while(1){ if (kbhit() == 1){ break; }else{ Sleep(500); } } fflush(stdin); このように作ったのですが、押したキーがこの次にあるfgetsによって読まれてしまいます。 どうすれば解決できるでしょうか?
>>975 fflush(stdin)は未定義です。getc()等で読んで捨ててください。
>>975 これでいける!多分…
while(1){
if (kbhit() == 1){
while(kbhit())
getch();
break;
}else{
Sleep(500);
}
}
978 :
754 :2007/01/26(金) 17:59:49
>>974 それはよかったです
なにかあったらまた質問どーぞ
あれから書き込み4件しかないとは......
次スレまでまだまだですねぇ
( ・3・)<宿題しか受け付けないから
>>980 は無視するのがいいYO!
淋しい
>>980 は宿題を持ってくれば相手をしてあげるお
>>976-977 ありがとうございます。
しかし、fflush(stdin)を全部入れ替えたら新たな問題が。
#include<stdio.h>
#include <string.h>
#include <conio.h>
main(){
int check=0;
char word[8]="string\n",input[8];
while(check == 0){
// fflush(stdin);
while(kbhit()){
getch();
}
fgets(input, 8, stdin);
if (strcmp(word,input) == 0){
printf("OK\n");
check = 1;
}else{
printf("NG\n");
}
}
return 0;
}
>982 その問題ってなによ?
984 :
982 :2007/01/27(土) 21:22:06
(続き)
単純化すると
>>982 のようなプログラムなのですが、
コメントアウトされたfflush(stdin);の代わりにその下の3行を入れたところ
標準入力の中身が捨てられず、8文字以上入力すると8文字ごとに読み込み
strcmpして、NGと表示してしまいます。
kbhit()って、先頭が読み込まれていたらその残りに関しては
1を返さないんでしょうか。
>>984 kbhit() はキーボードバッファの状態を調べて返す関数だが、
fgets() 関数が呼ばれたときに、キーボードバッファの中身が
ストリームバッファ stdin に移ってしまって、
キーボードバッファの中身が空になってしまい、
意図した動作になっていないんだと思われる。
fgets() を使わずに getch() で読むように変更するか、
fgets() で得られた文字列の終端が '\n' でなければ、
\n または EOF がくるまで読み飛ばすようにすればOK
986 :
985 :2007/01/28(日) 05:55:32
>>984 fgets(input, 8, stdin);
↓
fgets(input, 8, stdin);
if(input[strlen(input)-1]!='\n')
{
char lfbuf[2];
fscanf(stdin, "%*[^\n]%1[\n]", lfbuf);
}
>>984 fflush(stdin); はやめれ
どうしてもというなら環境依存スレ行け
>>987 fflush(stdin)を違う方法で置換したいがための質問だと思われ。
昔も今も、fflush(stdin)はいかんと思うが。
991 :
デフォルトの名無しさん :2007/01/28(日) 14:55:55
992 :
デフォルトの名無しさん :2007/01/28(日) 15:19:11
フォーとらアッーん
993 :
デフォルトの名無しさん :2007/01/28(日) 15:54:07
994 :
デフォルトの名無しさん :2007/01/29(月) 04:51:10
fflush(stdin)はLSI-Cではおk
>>995 んな過去の遺物に依存したプログラミングは推奨できません。
997 :
デフォルトの名無しさん :2007/01/29(月) 11:09:23
これじゃどっちが昔の人かわからんなw
LSI-Cwwwwwwwwwwwwwwwwwww
999 :
999 :2007/01/29(月) 17:41:23
銀河鉄道999
1000 :
999 :2007/01/29(月) 17:42:17
と言うわけで1000年女王も頂きます
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。