トップページ⇒tech
1001コメント308KB

C言語なら俺に聞け(入門篇) Part 4

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/11/09(木) 00:31:01
C言語の入門者向け解説スレです。
・C++言語はスレ違いです。
・分からない事をなるべく詳しく書いて下さい。
・ソースコードを晒すと答えやすくなるかもしれません。
・質問者は最初にその質問をした時のレス番号を名前欄に書いて下さい。

前スレ
C言語なら俺に聞け(入門篇) Part 3
http://pc8.2ch.net/test/read.cgi/tech/1160682950/

過去スレ
Part 1 http://pc8.2ch.net/test/read.cgi/tech/1146700389/
Part 2 http://pc8.2ch.net/test/read.cgi/tech/1153818463/


関連スレ
くだすれC言語(初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1153542424/

【ISO/ANSI/JIS】 C言語なら俺に聞け! Part 130
http://pc8.2ch.net/test/read.cgi/tech/1159613789/
0792デフォルトの名無しさん2006/11/27(月) 03:22:00
>>790
どの括弧が足りないんでしょうか?

それとコンパイルできないのが正しい形なんでしょうか?
0793デフォルトの名無しさん2006/11/27(月) 03:29:23
たぶん VC++ の方は
getch(); → _getch();
にすればコンパイルできるんじゃないかなかな。
0794デフォルトの名無しさん2006/11/27(月) 03:39:15
例えばsin2θ=xで、xがわかっている場合にθの値を求めるにはどうすればいいですか?
0795デフォルトの名無しさん2006/11/27(月) 03:40:57
>>794
ニュートン法とか二分法とか
07967942006/11/27(月) 04:02:27
>>795
具体的にはどうすればいいんですか?
まったくわからないので教えて下さい。
0797デフォルトの名無しさん2006/11/27(月) 04:04:12
>>796
ぐぐれよ

例えば平方根を求める場合
http://www.sm.rim.or.jp/~shishido/newton.html

これのx*xをsin(x)にかえて、2*xをcos(x)に変えるとか
07987942006/11/27(月) 04:50:43
>>797
ぐぐっていろいろ試してみましたができませんでしたorz
0799デフォルトの名無しさん2006/11/27(月) 05:17:08
>>798
だいたいこんな感じ
#include <stdio.h>
#include <math.h>

#define f(x) (sin(2 * (x)) - 0.5) /* x = 0.5 */
#define g(x) (2 * cos(2 * (x)))

#define MAXCOUNT 10

int main(void)
{
double x = 0.5;
int k;

for (k = 1; k <= MAXCOUNT; k++) {
x = x - f(x) / g(x);
printf("%17.12f %15.8e\n", x, fabs(f(x)));
}

return 0;
}
0800デフォルトの名無しさん2006/11/27(月) 06:43:31
>>794
theta=asin(x)/2;
0801デフォルトの名無しさん2006/11/27(月) 06:47:48
math.hをインクルードするのを忘れんようにな
0802デフォルトの名無しさん2006/11/27(月) 14:15:57
sin2θって表記は2が上付きなのをまんま書いてるかも。
そうだとasin(sqrt(x))とasin(-sqrt(x))。
0803デフォルトの名無しさん2006/11/27(月) 15:24:01
putchar,getcharを使って、20061109のように日付を入力すると
曜日を出力するプログラムを作成せよ、って課題が学校で出たんですが
全く分かりません・・・
誰か教えてください
0804デフォルトの名無しさん2006/11/27(月) 15:32:16
>>803
宿題スレへどうぞ。
08057942006/11/27(月) 17:18:45
>>799
>>800
ありがとうございました
おかげでできました
0806デフォルトの名無しさん2006/11/27(月) 17:45:31
なんで int *x じゃなくて int* x にする人がいるの?
0807デフォルトの名無しさん2006/11/27(月) 17:55:36
C++やると、参照型 (int& r;)との兼ね合いで、そっちも悪くないように思えてくる。
C++作った人もint* p;派だというし。

もちろんC++やったことがなくてもint* p;の人はいるし、その逆もそう。結局は好みの問題。
0808デフォルトの名無しさん2006/11/27(月) 17:57:51
こんばんわ。質問さしてください。
英数字とか漢字をを入力し、それを16進数で表示したいと考えています。
scanfで取り込んでprintfでみたいにしてみたんですがうまくいきません。
アドバイスいただけないでしょうか?よろしくお願いします。
また、このやり方で漢字を16進で受け取ることはできるのでしょうか?
0809デフォルトの名無しさん2006/11/27(月) 18:02:01
C++ より Objective-C の方が明らかに上。
仕様も性能も。
0810デフォルトの名無しさん2006/11/27(月) 18:15:28
>>808
漢字はchar型の変数に収まらないので、文字列(char配列)として扱え。

>>809
シェアはC++のほうが明らかに上。
でもたぶん、そもそもC++とObjective-Cが目指している方向は違うと思うんだ。比べるだけ無駄だと思う。
0811デフォルトの名無しさん2006/11/27(月) 20:41:12
>>808
入力された文字列の文字コードを表示するって意味だろうか。
0812デフォルトの名無しさん2006/11/27(月) 21:44:22
ひらがなとかを1バイト文字に変換するにはどうすればよくて?
2バイトURLを1バイトに直したくて・・・
0813デフォルトの名無しさん2006/11/27(月) 21:58:45
>>812
ひらがなは1バイトにできん
2バイト文字だ
0814デフォルトの名無しさん2006/11/27(月) 22:07:16
URLなら、英数字2バイトを1バイトにしたいわけだろ?
汎用関数みたいな都合のいいものはないみたいね。
変換するのが英数字なら、なんとか自分で(環境依存のものを)書こう。
適当だけど、
unsigned char hoge[] = "abcde:/";
int i;
for (i = 0; i < sizeof(hoge); i++)
{
printf("%x ", hoge[i]);
}
こんな感じでコードの規則性を調べて、
unsigned char hoge[] = "abcde:/";
char str[256];
int i;
for (i = 0; i < sizeof(hoge) / 2; i++)
{
switch(hoge[i * 2]) {
case 0x82:
str[i] = hoge[i * 2 + 1] - 0x81 + 'a';
break;
default:
break;
}
}
str[i] = '\0';
こんな感じで変換するしかないんじゃない?コロンとかスラッシュは
一つずつ対応して・・・ああめんどくさい。しかも移植性なし。
0815デフォルトの名無しさん2006/11/27(月) 23:55:54
812がやりたいことはURLエンコードのような気がする。
0816デフォルトの名無しさん2006/11/28(火) 06:39:06
case WM_CREATE時のコードをcase WM_KEYDOWNの時にも
使いたいのですが、関数にして何度も使うには文が長く
参照する変数が二次元配列などが多くてごちゃごちゃしてます。
どうすれば同switch内でもう一度使えるでしょうか?
教えてください。お願いします。
0817デフォルトの名無しさん2006/11/28(火) 06:52:16
関数にして何度も使うには文が長く、って、
その長い文を同じswitch文の中で二ヶ所使う方がさらにごちゃごちゃするんじゃないか?
まず、その長い処理を切り出して関数にする。
関数内で使うために渡すべき変数が多すぎて引数がごちゃごちゃするようなら、
構造体等でまとまりを作って呼び出しをすっきりさせる。
まとまった処理とのインタフェースが変数がごちゃごちゃしているせいで美しくないと感じるようなら、
データ構造の変数への切り出し方を再考することも考えてみたら?
0818デフォルトの名無しさん2006/11/28(火) 06:55:10
>>817
うっす。ありがとうございます。
0819デフォルトの名無しさん2006/11/28(火) 07:53:40
単純に、
case WM_CREATE:
case WM_KEYDOWN:
// 処理
って話ではないのかね。
08208082006/11/28(火) 12:48:13
>>811 そうです。文字コードを受けってそれを表示したいので
   scanfで取り込んだらコードが出てくるかなと思い質問さ
   していただきました。
   JISコードを表示することは簡単ではないのでしょうか?
0821デフォルトの名無しさん2006/11/28(火) 13:42:03
JISコードで入力してもらえれば簡単だろうけどな。
0822デフォルトの名無しさん2006/11/28(火) 18:00:27
整数を入力して、その数までを2のべき乗ずつ表示していくという
問題なんですが、エラーは出ずにコンパイルできても
実行したら何も起きません。
宜しければどこが間違ってるか教えて頂けないでしょうか?

#include <stdio.h>

int main (void)
{
    int i,no;

    printf("正の整数を入力して下さい:");
    scanf("%d", &no);

    i = 1;
    while (i <= no)
    {
        if (i == (2 * i))
            printf("%d ", i);
        i++;
    }
    if (no > 0)
        putchar('\n');

    return (0);
}
0823デフォルトの名無しさん2006/11/28(火) 18:04:14
if の条件が不備。 2のべき乗かどうかのチェックをしていない。

さらに i が 2 * i と等しくなるのは i=0 の時だけ。
0824デフォルトの名無しさん2006/11/28(火) 18:33:27
>>822
#include<stdio.h>

int main (void)
{
    int i,no;

    printf("正の整数を入力して下さい:");
    scanf("%d", &no);

    for(i=1;i<=no;i<<=1)
        printf("%d ", i);
    if (no > 0)
        putchar('\n');

    return (0);
}
0825電信男2006/11/28(火) 18:34:08
小文字から大文字に変換したいので↓のようなプログラムを作ったのののですが、
うまいことできません。
AppleがyPPLEになってしまいます。
どーすればいいでしょうか?
#include <stdio.h>

int main()
{
int i = 0;
char c[] = "Apple";
char b [80];

printf("String: %s\n", c);

for(i = 0;i < 5; i++){
if ('a' <= c[i] && c[i] <= 'z' )
b[i] = c[i] + 'A' - 'a';
}
printf("Upper case: %s\n", b);
return 0;
}
0826デフォルトの名無しさん2006/11/28(火) 18:36:50
>>825
c[i]が小文字以外の時の処理を加えるといいよ

または #include<ctype.h> と b[i]=toupper(c[i])
0827デフォルトの名無しさん2006/11/28(火) 18:46:19
>>823
アドバイスありがとうございます。
ですが、2のべき乗のチェックの式がわからないのです。

>>824
例題がwhileを使ってるのでできればwhileのままでやりたいのですが…
0828デフォルトの名無しさん2006/11/28(火) 18:53:01
>>827
2のべき乗なら1になるまでずーっと2で割り切れる。

forのループをwhileに直すことぐらい自分でしろ。
0829デフォルトの名無しさんNGNG?2BP(200)
>>827
「2のべき乗かどうか」をチェックする必要など無い。
「2のべき乗にしかならない」値を作ればいい。

i=0;while((2<<i)<=no){printf("%d ", (2<<i));i++;}
0830デフォルトの名無しさん2006/11/28(火) 18:59:04
>>829
2の0乗=1 も仲間にいれてやって
0831デフォルトの名無しさんNGNG?2BP(200)
間違いた。
i=0;while((1<<i)<=no){printf("%d ", (1<<i));i++;}
こうだな。
0832デフォルトの名無しさん2006/11/28(火) 19:01:46
>>825
文字列の終端に '\0' もいれないといけない。
0833デフォルトの名無しさん2006/11/28(火) 19:35:22
>>828
>>829
すみません。
アドバイスありがとうざいました。
0834デフォルトの名無しさん2006/11/28(火) 22:55:33
質問です。
C言語でフォルダの中身の一覧を表示させるには
どうすれば良いでしょうか。
0835デフォルトの名無しさん2006/11/28(火) 22:57:39
>>834
system("dir");
system("ls");
のどちらかでいいんじゃないかな?
0836デフォルトの名無しさん2006/11/28(火) 22:58:09
>>834
ls -R
0837デフォルトの名無しさん2006/11/28(火) 23:05:14
質問なのですがvisual C++ で         = :左のオペランドが,左辺値になっていません。
というエラーが出るのですがこれはどういうことなんでしょうか?
0838デフォルトの名無しさん2006/11/28(火) 23:06:07
左のオペランドが,左辺値になってないんじゃないか?
0839デフォルトの名無しさん2006/11/28(火) 23:08:00
すみません。オペランドってなんですか?
0840デフォルトの名無しさん2006/11/28(火) 23:09:38
手術室のこと
0841デフォルトの名無しさん2006/11/28(火) 23:10:26
>>839
x = y + z;
ってあれば、yとzはオペレータ'+'のオペランドで、
xとy+zがオペレータ'='のオペランド

>>840
ワロタ
0842デフォルトの名無しさん2006/11/28(火) 23:15:41
>>841
教えていただきありがとうございました。ということは=の左辺と右辺が矛盾してますよってことですか?
0843デフォルトの名無しさん2006/11/28(火) 23:23:51
>>842
矛盾しているということではなくて、=の左辺にあるものが
代入可能なものではないということ。
0844デフォルトの名無しさん2006/11/28(火) 23:24:07
代入できないってことじゃないの
エラーが出た行を貼り付けてくれれば簡単に答えられると思うが
0845デフォルトの名無しさん2006/11/28(火) 23:32:18
if(i>l && i>o){

if((l*l+o*o)>i*i)
printf("鋭角三角形");
if((l*l+o*o)=i*i)  ←ここです。
printf("直角三角形");
if((l*l+o*o)<i*i)
printf("鈍角三角形");
}               
0846デフォルトの名無しさん2006/11/28(火) 23:33:26
>>845
==
0847デフォルトの名無しさん2006/11/28(火) 23:36:23
どうもありがとうございました。おかげで完成しました。
0848デフォルトの名無しさん2006/11/28(火) 23:43:54
なんかの一行AAに見えた
0849デフォルトの名無しさん2006/11/28(火) 23:49:03
テキストエディターを作成しようと思うのですが、
fopen関数とかその辺のファイル入出力関係の関数を使って作っていけばいいんですよね?

なにかコツとか陥り易い問題点とかあったらアドバイスよろしくお願いします。
0850デフォルトの名無しさん2006/11/29(水) 00:01:02
ファイル操作の関数が何かを聞くということはたぶんかなりの初心者かと思うけど、
テキストエディタを実装するには理解すべきことがかなり多いと思うよ。
ファイル入出力だけじゃなく、GUI(描画、ユーザ入力)とか、メモリ上のデータ管理とか。

とりあえずアドバイスとしては
・いきなり高機能なものは目指さない。
・基本はしっかり学ぶ。入出力が良く分かってないなら、テキストエディタはいったん置いておいて
 ある程度自由に入出力が扱えるくらいには勉強してみる。
・ちゃんとテストする。いろいろ作りこんでから上手く動かないと分かっても、原因を調べるのは大変。
・自分でいろいろな情報を調べられるようにする。
・めげない。
0851デフォルトの名無しさん2006/11/29(水) 00:35:24
シューティングゲームで、
方向キーを押しっぱなしで弾をうちたい時などに、
何のボタンを押しているか というのを
取りたいのですがどうすればいいでしょうか。

kbhit()では最後に押されたキー1つしか取れないですよね・・
0852デフォルトの名無しさん2006/11/29(水) 00:41:47
Func(int byte_len)
{
int i = 1000;
char data[4], *pc;

pc = (char*)&i;
data[0] = pc[3];
data[1] = pc[2];
data[2] = pc[1];
data[3] = pc[0];
}

↑のdataに入る数字の並びをエンディアンを気にせずに、
ビッグエンディアン形式にしたいのですが、
エンディアンを気にしない書き方はありますか?
0853デフォルトの名無しさん2006/11/29(水) 00:48:39
>>852
1.バイトオーダーを隠してしまう関数を作る。
2.シフト演算を使う。
1,2のどちらかだな
0854デフォルトの名無しさん2006/11/29(水) 01:19:55
シフト演算で取り出す関数を作ろうと思います。
ありがとうございました。
0855デフォルトの名無しさん2006/11/29(水) 02:08:40
>>851
そもそもkbhitじゃ一つも入力取れないぜ?
0856デフォルトの名無しさん2006/11/29(水) 02:10:02
>>850
テキストエディタにGUIってどんなだよ?
ワープロと間違えてんのか?
0857デフォルトの名無しさん2006/11/29(水) 02:12:32
>>856
ed みたいなの想像してる?
スクリーンエディタなら GUI でしょ
0858デフォルトの名無しさん2006/11/29(水) 02:24:32
かなや漢字を表示するからGUIだな。
0859デフォルトの名無しさん2006/11/29(水) 02:29:51
GUI使ってるテキストエディタって少なくね?
使ってるとしてもツールバー程度じゃね?
ほとんどのエディタはCUIだろ?
0860デフォルトの名無しさん2006/11/29(水) 02:36:22
ASCII文字以外を表示したらそれは GUI なんだよ。
だから DOS/V は GUI-OS なんだよ。
0861デフォルトの名無しさん2006/11/29(水) 02:46:54
GUI が気になってググってみた。
思ってたのとかなり違ってた。
オレは古い人間なんだと思い知らされた。
0862デフォルトの名無しさん2006/11/29(水) 02:49:27
int d; //入力値
while(1){
//移動する数値を入力する
do {
d = -1;
printf("動かす数字を入力して下さい > ");
scanf("%d", &d);
while (getchar() != '\n') { }
if(d == 0) { r = 1; break; }

これで、d = -1; に何故-1が付くのかわかりません。
入門書に書いてある説明に依ると数値以外の文字や文字列が
入力されると、scanf関数の入力値を格納する変数には何も
入らないので、前に入力した値が入っている状態です。
なので、scanf関数を使う前に、入力値を格納する変数に
毎回数値-1を設定しておきましょう。

との事です。
>>scanf関数を使う前に、入力値を格納する変数に
毎回数値-1を設定しておきましょう。
何故、-1を設定しなければならないのでしょうか?

それと、>>前に入力した値が入っている状態です。
前に入ってるから、何故-1にするのかわかりません。

アドバイスを宜しくお願いします。
0863デフォルトの名無しさん2006/11/29(水) 03:02:55
>>862
>>862 でしっかりかいてある通り。
自己解決ってやつだな。しかも一つのレスでw
0864デフォルトの名無しさん2006/11/29(水) 03:03:34
別に意味は無い。
それ書いた人がそういうルールに決めただけ。
0865デフォルトの名無しさん2006/11/29(水) 03:13:23
ではー1を入れる事に依り、空白に戻すと言う事でしょうか?
0866デフォルトの名無しさん2006/11/29(水) 04:30:25
-1が入っていた場合はscanfに失敗していると分かるかもしれません。
前に入力した値がそのままだと失敗したことが分からないかもしれません。
0867デフォルトの名無しさん2006/11/29(水) 05:01:48
でも-1を事前に入れておくくらいなら、scanf()の戻り値をチェックすべきだがな。
事前に-1を入れる方法だと、入力ミスと-1の入力の区別がつかないジャマイカ。
0868デフォルトの名無しさん2006/11/29(水) 05:15:46
何だかよくわかりませんが、ありがとうございました…
0869デフォルトの名無しさん2006/11/29(水) 05:17:49
すみません、Winnyは何言語でできているのでしょうか?
JAVAでしょうか?VISUAL C++でしょうか?
0870デフォルトの名無しさん2006/11/29(水) 06:20:55
>>869
確か、
初期のバージョンは VC++
途中から BCB(Borland C++ Builder)
バージョンはよくわからん。

途中から使用してるツールは違えど、言語自体はC++言語になるね。
0871ぴゅあ2006/11/29(水) 07:53:41
>>862
恐らく解説の中にあると思いますけど
入力される数は、処理を終了させるための"0"か
正の整数であることを条件にしているでしょう

それより、負の整数は入力されることはないとして
つまり現れることはないもの(例外値)として
scanfで無効な入力があったときに-1(例外値)となるように
予め入れてあるものです
(この例では入力処理(scanfの部分)をきちんと書くことを
目的としているわけではないので簡単に済ませてある)
なので、-2でも-99でもよいわけですが
-1を割り当てようと思う人が比較的多かったりする
というところですね

つまり"-1"という値が重要なのではなく
"例外値"であることが大切なわけです

もし、-1も入力される値であったとすれば
-2(d = -2;)とかにされていたかも知れません

恐らく簡単に済ませてあって
もしdの値が-1であったときそれ以降の処理をスキップさせる
なんて処理も省略されているかも知れませんね
>>866-867の言われているようなところは
省いている筈ですから(それが示されたコードにも現れているのとscanf自身ではなく何か他の解説が目的であろうということ)
08728342006/11/29(水) 11:48:35
>>835
人大杉でレス遅れてすんまそん。
回答有難うございました。
08738342006/11/29(水) 11:51:33
836さんも!!
0874デフォルトの名無しさん2006/11/29(水) 12:37:12
ちなみにフォルダの中身を一覧表示させ、
その内容をファイルに書き込む方法はどうするんでしょうか。
0875デフォルトの名無しさん2006/11/29(水) 12:39:10
>>874
system("ls > a.txt");
0876デフォルトの名無しさん2006/11/29(水) 12:49:26
Cっていうよりシェルの使い方だなw
0877デフォルトの名無しさん2006/11/29(水) 13:23:59
>>875
「一覧表示させ、その内容をファイルに書き込む」
だからそれじゃダメだろ。
0878デフォルトの名無しさん2006/11/29(水) 13:25:28
system("ls");
system("ls > a.txt");
0879デフォルトの名無しさん2006/11/29(水) 13:28:07
1行目と2行目の一瞬の間にディレクトリ内容が変更される可能性を考慮してない。失格。
0880デフォルトの名無しさん2006/11/29(水) 13:28:42
system("ls | tee > a.txt");
0881デフォルトの名無しさん2006/11/29(水) 13:31:02
system("ls > a.txt");
system("cat > a.txt");
又は
system("ls | tee a.txt");
0882デフォルトの名無しさん2006/11/29(水) 13:31:09
teeなら '>' は必要ないなとマジレスしてみる
0883デフォルトの名無しさん2006/11/29(水) 13:32:56
フォルダってことはこうジャマイカ?
system("dir > a.txt");
system("type a.txt");
0884デフォルトの名無しさん2006/11/29(水) 13:35:20
>>874 をよく読め。
「ディレクトリ」じゃなくて「フォルダ」だぞ。
表示される内容は微妙に違うぞ。
0885デフォルトの名無しさん2006/11/29(水) 13:40:07
>>883
それはあくまでディレクトリだ。
0886デフォルトの名無しさん2006/11/29(水) 16:23:48
なぜか次の単純なプログラムにエラーがでます。

#include <stdio.h>

int main(void)
{
int i = 10;
int k;
int m[i] = {1,2,3};

for(k = 0;k < i;k++)
printf("%d\n",m[k]);
return(0);
}

配列mの初期化を”m[i] → m[10]”にするとうまくいきました。
配列の要素の初期化に変数はつかえないのですか?
0887デフォルトの名無しさん2006/11/29(水) 16:31:57
>>886
define i 10
0888デフォルトの名無しさん2006/11/29(水) 16:39:40
#ifdefにelse ifはないのでしょうか?
0889デフォルトの名無しさん2006/11/29(水) 16:44:08
>>886
ヘタレはC99使ってろよプ

>>888
あるよ。
0890デフォルトの名無しさん2006/11/29(水) 17:12:23
>888
#elif
08918742006/11/29(水) 17:29:34
レスくれた方々ありがとうございます。
とても参考になりました!!!
0892デフォルトの名無しさん2006/11/29(水) 17:55:23
fprintf のファイル名をfor文などを使って数字1から順番に作っていく
ことはできないでしょうか?
例えばガウス関数のσ=1の計算を1.datに書いて、
σ=2の計算を2.datに書くようにしたいです。
■ このスレッドは過去ログ倉庫に格納されています