トップページ⇒tech
909コメント312KB

C言語なら、俺に聞け! <9>

■ このスレッドは過去ログ倉庫に格納されています
0001C言語ハッカー Kusakabe YouichiNGNG
おれは21才、9年間プログラムを一生懸命作ってきた。
あちこちの言語に手を出したが結局極めたのはC言語だけだった。
大体のことなら分かるからオレに聞け。

だが、いちいちFAQに載った質問に応えるほど暇じゃない。
課題丸投げなら別スレにいけ。

・comp.lang.c Frequently Asked Questions
http://www.eskimo.com/~scs/C-faq/top.html

・C FAQ 日本語訳
http://www.catnet.ne.jp/kouno/c_faq/c_faq.html

・前スレ C言語なら、オレに聞け! <8>
http://pc.2ch.net/test/read.cgi/tech/1005811510/l50
0002デフォルトの名無しさん NGNG
2ゲト(・∀・)
って何か2.3日真面目に仕事してたらえらい勢いですすんでるですね
0003(・∀・)イイNGNG
疑問に思ったんですが、printfがあればputsは必要ないのではないでしょうか?
それとprintfとputcharでは使用するメモリの領域が違うとかあるんですか?
0004Kusakabe YouichiNGNG
>>1 C言語ハッカー Kusakabe Youichi wrote:
> おれは21才、9年間プログラムを一生懸命作ってきた。
> あちこちの言語に手を出したが結局極めたのはC言語だけだった。

これってようするにおちこぼれ? (^^;
0005Kusakabe YouichiNGNG
>>3 (・∀・)イイ wrote:

> 疑問に思ったんですが、printfがあればputsは必要ないのではないでしょうか?

そういう人にとっては、「中華庖丁があれば、柳刃も出刃も菜切りもペティナイフ
も
いらない」んでしょうね :)
0006デフォルトの名無しさんNGNG
(1)printf は\nをわざわざ入れてやらないと、改行しない。
puts は勝手に改行する。

(2)いろんな書式指定をするならprintf が便利だが、書式指定が特にないならputsを使えばよい。
0007デフォルトの名無しさんNGNG
>>3
>それとprintfとputcharでは使用するメモリの領域が違うとかあるんですか?
混在して使っても、特に問題はないと思いますよ。
0008(・∀・)イイNGNG
>>6
やっぱりその程度の違いしかないんでしょうかね?

>>7
そうですか。やっぱり問題ないですか。ありがとうございます。
0009(・∀・)イイNGNG
>>5
悪いんですけど、質問に答える意思がないのならわざわざ書かなくてもいいです。
文句地味たことは必要ありません。
0010newbieMNGNG
全スレで移動しろと勧告されたので
移動して再度質問させていただきます。

今ある特定のディレクトリの中のファイル名を比較して
リネームというようなソフトを作ろうと思っているんです。
つまりaっていうフォルダに
abc.txt
efg.txt
・・・・
ってあったとき
abc.txtをエービーシー.txt
efg.txtをイーエフジー.txt
という風に初めからあるリストと比較してリネームしたいんです。
ですが具体的にどのように書いたらいいかがわかりません。
どの命令を組み合わせるかおしえていただけないでしょうか?
OSはwin98です。
0011newbieMNGNG
使ってるソフトはいちおうVC++6.0です。
0012デフォルトの名無しさんNGNG
>>11
Perlか何かででバッチファイルを書き出せば?
0013デフォルトの名無しさんNGNG
>>10
windowsはディレクトリを開けないんだっけ?
とりあえずdir.hにfindfirst,findnextとかあったかな
あとstdio.hのrename

windowsではwindows.hのfindfirstfile,findnextfile
あたりだな
0014(・∀・)イイNGNG
構造体の宣言で
typedef struct TagPerson{
char *a
int d;
}Person;
と書くのと、
TagPerson{
char *a;
int d;
};
と書くのでの違いはなんなんでしょうか?
0015Kusakabe YouichiNGNG
>>10 newbieM wrote:
> 今ある特定のディレクトリの中のファイル名を比較して
> リネームというようなソフトを作ろうと思っているんです。
> ですが具体的にどのように書いたらいいかがわかりません。
> どの命令を組み合わせるかおしえていただけないでしょうか?

man 5 rename
0016(・∀・)イイNGNG
ごめんなさい。14の訂正です。
構造体の宣言で
typedef struct TagPerson{
char *a
int d;
}Person;
と書くのと、
struct TagPerson{
char *a;
int d;
};
と書くのでの違いはなんなんでしょうか?
0017Kusakabe YouichiNGNG
>>13 デフォルトの名無しさん wrote:
> >>10
> windowsはディレクトリを開けないんだっけ?
> とりあえずdir.hにfindfirst,findnextとかあったかな

Windows移植したopendirもころがってますね。
0018デフォルトの名無しさんNGNG
>>16
そのまえに typedef の意味わかってる?
0019デフォルトの名無しさんNGNG
>>16
typedef使うと、タイプ量が減って楽。
0020(・∀・)イイNGNG
>>18
typedefの意味は知っています。ようは型定義でしょ?

struct TagPerson{
char *a;
int d;
};
でのグループ名はどこにいっちゃってるんでしょうか?
違いがよくわかりません。
0021デフォルトの名無しさんNGNG
>>20
「グループ名」って、なんだったっけ?

a
0022デフォルトの名無しさんNGNG
typedef struct TagPerson Person;

の意味は分かる?
0023Kusakabe YouichiNGNG
>>14 (・∀・)イイ" wrote:
> 構造体の宣言で
> typedef struct TagPerson{
> char *a
> int d;
> }Person;
> と書くのと、
> TagPerson{
> char *a;
> int d;
> };
> と書くのでの違いはなんなんでしょうか?

前者はtypedefしてるんですね。
struct TagPerson {char *a; int d;} Person;
typedef struct TagPerson;
と2つにわけてみればわかるでしょう。

また、2つに分けない場合、typedefした名前だけを使うなら、
タグ名はなくてもいいですね。

このへんは第7章にわかりやすく解説されています。
0024デフォルトの名無しさんNGNG
typedef struct TagPerson Person;
Person person;
person.a = "name";
person.d = 0;
---------------------------
struct TagPerson person;
person.a = "name";
person.d = 0;

わかる?
0025デフォルトの名無しさんNGNG
>>20
struct tagPerson1{...};
typedef struct tagPerson1{...} Person2;

int main()
{
struct tagPerson1 *p1;
Person2 *p2;

p1 = (struct tagPerson1 *)malloc(sizeof(struct tagPerson1));
p2 = (Person2 *)malloc(sizeof(Person2));
}


まぁ、実際にはmallocのも取り値はキャストしなくていいけどね。
0026デフォルトの名無しさんNGNG
>>20
この疑問って、自分でコード書けば一発で分かる類のヤツだと思うが。
(それとも、なんか深い意味でもあるのか)
0027デフォルトの名無しさんNGNG
>>20
struct TagPerson{
char *a;
int d;
};
で、TagPerson 型の構造体を宣言したら、後は
struct TagPerson suzuki;
で、 struct TagPerson 型の変数suzukiを宣言すればいいよ。
0028Kusakabe YouichiNGNG
>>20 (・∀・)イイ wrote:

> >>18
> typedefの意味は知っています。ようは型定義でしょ?

実際には型定義ではないのだが、そうだと思っていても実害はほとんどないので
最初のうちはそう覚えておけばいいかも。

> struct TagPerson{
> char *a;
> int d;
> };
> でのグループ名はどこにいっちゃってるんでしょうか?

それに「グループ名」ってなんだ? 「構造体名」のこと?
0029デフォルトの名無しさん NGNG
日下部が厨房を吸い寄せててんのか?
前の800位から凄いなちょっと
0030デフォルトの名無しさんNGNG
さあ、誰の教え方が一番うまかったか(藁
0031デフォルトの名無しさんNGNG
>>9

あんた、「適材適所」って言葉も知らないでしょ ? C 言語の前に、「日本語」
覚えたら ?
0032newbieMNGNG
/*rename.c*/

#include<stdio.h>

main()
{
char old[] = "借金帳.txt", new[] = "asdcz.txt";
rename( old, new );
}
みたいに作ってみました。ディレクトリからって言うのは
調べてみたんですけどやっぱり使い方わからなくて・・・
でもこれだと200個とか変換するのに
かなり書かなきゃいけませんよね?
そこで
借金帳.txt→asdcz.txt
の部分をリスト化してそれを使ってリネームしたらいいのかなと
思ったんですが・・・そういった場合はどうすればいいんでしょうか?
0033でNGNG
printf("逝ってよし");
0034デフォルトの名無しさんNGNG
>>32
名前リストをコンパイル時に確定してしまっていいのなら、これが楽かなぁ。

struct renlist {
  const char *rl_src;
  const char *rl_dst;
} renlist[] = {
  { "借金帳.txt", "asdcz.txt" },
  { "ノート.txt", "note.txt" },
  { NULL, NULL }  /* sentinel */
};

struct renlist *rp;
for (rp = &renlist[0]; rp->rl_src != NULL; ++rp)
  rename(rp->rl_src, rp->rl_dst);
0035デフォルトの名無しさん NGNG
めちゃめちゃ機能限定じゃん! (^∀^)ハハッ
0036デフォルトの名無しさんNGNG
>>35
Yup. シンプルで良いでしょ? (まぁ、実際には rename の戻り値ぐらいチェック
しないとアレだが)
0037名無しだゴルァNGNG
前スレで2分法やらの質問をしたものです。
簡単じゃねえかゴルァ!!
誰か答えてくれたっていいじゃないかゴルァ!!
ってもう出来たからいいけど・・・

以上、愚痴でした。
0038デフォルトの名無しさんNGNG
>>37
愚痴は sage でな。
0039デフォルトの名無しさんNGNG
------
Kusakabe 先生のスレ違い/意図不明な書き込みに対する苦情には専門のスレ
が用意されて いるので、ム板では書かないようにお願いします。そのような書き
込みにコメント をつけるのは、彼と一緒に一緒になって荒らし行為をし てるのと
変わりません。

日下部 陽一先生の隔離スレッド void ***
http://pc.2ch.net/test/read.cgi/prog/1006918877/

#同意も反論も不要。なんかあったら↑のスレで言ってくれ。
------
0040デフォルトの名無しさんNGNG
>>39
おまえの方がよっぽどウザイよ。
風紀委員やりたいなら、学校でやってろ。
0041デフォルトの名無しさんNGNG
>>40
オマエモナー
0042(・∀・)イイ NGNG
typedef struct TagPerson{
char *a
int d;
}Person;
で、structの部分、TagPersonの部分、Personの部分をそれぞれなんていうんですか?
なんかこの前聞いた人と違うこと言ってて・・・
0043デフォルトの名無しさんNGNG
>>42
プログラミング言語Cの付録から。

TagPerson はタグ名
Person は typedef 名
0044(・∀・)イイNGNG
>>43
ありがとうございます。
struct TagPerson{
char *a;
int d;
};
こういうときは、どうやって使うんでしょうか?
0045デフォルトの名無しさんNGNG
>>44
アレだけみんながよってたかって教えてるのに全滅かい!
0046デフォルトの名無しさんNGNG
>>44
目的語が良く分からんけど、もしかして >>34 見ると解決したりします?
0047デフォルトの名無しさんNGNG
>>40
まあそう言うな。向こうじゃ全員ではないが
たいていの人間が同意してる。
彼も良かれと思ってやってることだ。
彼のkittyさを知らないわけでもないだろ。
0048デフォルトの名無しさんNGNG
糞壁の書き込みに対する苦情には専門のスレ
が用意されているので、荒れないようにそこでレスしてください。
http://pc.2ch.net/test/read.cgi/prog/1006918877/
#同意も反論も不要です。何かあったら↑のスレでお願いします。
糞壁はカスです。みんなで力を合わせて排除しましょう。
0049デフォルトの名無しさんNGNG
(´-`).。oO(Kusakabeって自分の書いてる事面白いつもりなのかな)
0050デフォルトの名無しさんNGNG
>>48
言いたいとは良く分かる(やつのせいでお気に入りのスレが荒廃したし)。
だが、基本的にスレ違いな内容だから sage で書け。
0051デフォルトの名無しさんNGNG
>>48
言いたいことは良く分かる(やつのせいでお気に入りのスレが荒廃したし)。
だが、いちいち書かれるとはっきり言って鬱陶しい。10回に一回くらいの割合で書け。
0052デフォルトの名無しさんNGNG
>>43
struct TagPerson{
char *a;
int d;
};
で、TagPerson 型の構造体を宣言したら、後は
 struct TagPerson suzuki;
で、 struct TagPerson 型の変数suzukiを宣言すればいいよ。
そしたら
*suzuki.a = 25
suzuki.d = 125
と代入できる。
0053妊娠中NGNG
>>43
typedef struct{
char *a;
int d;
}chinpo;
でchinpo型ができますか?
0054妊娠中NGNG
あちがえた。>>52
0055デフォルトの名無しさんNGNG
>>53
できる。
0056デフォルトの名無しさんNGNG
C--言語はないんですか?
0057デフォルトの名無しさんNGNG
C言語やる人はスタックをあまり気にしない人なのでしょうか。
また、構造体メンバのデータ位置もあまり気にしない人なのでしょうか。
0058デフォルトの名無しさんNGNG
>>57
気にしますよ。
0059デフォルトの名無しさんNGNG
>>57
人や環境による。
オレはかなりおおまか。
0060デフォルトの名無しさんNGNG
>>57
場合による。
組み込み系で、開発にPC上のエミュレータなんか使ってる場合、
バウンダリの扱いに気をつけて構造体使わないとハマる。

PCアプリ作る場合なら、ほとんど気にしない。
0061デフォルトの名無しさんNGNG
>>56
JAVAがそうです。
0062デフォルトの名無しさんNGNG
十回乱数を求める時、
1、2、3、・・・10と並んで出る確率と
1、1、1、・・・1と全部1が出る確率は同じでしょうか?
0063デフォルトの名無しさんNGNG
>>62
それC言語関係ないんじゃ?
確率論的には同じじゃない?
0064デフォルトの名無しさんNGNG
>>62
rand()の実装についてききたいのか?
0065デフォルトの名無しさんNGNG
>>56
C--あるよ
0066デフォルトの名無しさんNGNG
>>65

B言語?
0067デフォルトの名無しさんNGNG
>>66
検索しろ
0068デフォルトの名無しさんNGNG
>>67

検索しろって言われてもな、--←これはキーワードとして見てくれないんだよ。
0069デフォルトの名無しさんNGNG
"C--"じゃだめ?
http://www.google.co.jp/search?q=%22C--%22&hl=ja&lr=
007067NGNG
ここで検索してみそ
http://www.programmersheaven.com/search/search_all.asp
0071デフォルトの名無しさんNGNG
>>69

だめみたい・・・
多分--もキーワードとして見てくれているんだろうけど、Cと--を勝手に分けてしまっているんじゃないかな?

>>70

本当にあるんだね(笑)
面白い情報サンクス
0072newbieMNGNG
>34さん
無事それを使ってできました!
今やっと250ほどのデータ打ち込み終わったところです。
ありがとうございました。
007362NGNG
重複しない乱数を取得する質問で、
過去に取得した値を調べて、同じのが無ければ決定する
方法が紹介されていましたが(どのスレだったか忘れました)。
これだと、なかなかループから抜けなくなるかもしれません。

よって、
0〜100の値を10個取得する場合、
配列A[101]にA[0]=0、A[1]=1、...と代入して、
最初は0〜100からランダムに一つ選び、その値を配列から削除し、配列の要素数を-1する。
次は、0〜99からランダムに一つ選び、.....
...
とやる方がいいかな? と思ったのです。

で、乱数関数が全部1を返した場合。
このやりかただと、求まる値は 1, 2, 3, ...となります。
わからなくなってきた・・・。

それより、ある値が出る確率は
(1/101) * (1/100) * (1/99) * .... * (1/92)
になるから・・。
0074Kusakabe YouichiNGNG
In article >>73, 73 62 wrote:
> 重複しない乱数を取得する質問で、
> 過去に取得した値を調べて、同じのが無ければ決定する
> 方法が紹介されていましたが。

どろくさい方法ですよね:)

> これだと、なかなかループから抜けなくなるかもしれません。

数が増えるとかなり遅いですね。
(現実的にはたいがい有限時間内に終わっていますが^^)

> よって、
> 0〜100の値を10個取得する場合、
> 配列A[101]にA[0]=0、A[1]=1、...と代入して、
> 最初は0〜100からランダムに一つ選び、その値を配列から削除し、配列の要素数
を-1する。
> 次は、0〜99からランダムに一つ選び、.....
> ...
> とやる方がいいかな? と思ったのです。

それって意味ないような(^^;
0075デフォルトの名無しさんNGNG
意味ないの意味が分からないよ。
乱数の範囲が大きくなると、配列のサイズがでかくなるので、
使えないって事?
0076デフォルトの名無しさんNGNG
あらかじめ含めない値をランダムに求めておいて、並べ替えるやり方はどうですか?

たとえば、2を含めないと決めたら、
A[10] = {0, 1, 3, 4, ..., 9}
を作って、並べ替えるやり方。
0077Kusakabe YouichiNGNG
In article >>75, 75 デフォルトの名無しさん
wrote:

> 意味ないの意味が分からないよ。
> 乱数の範囲が大きくなると、配列のサイズがでかくなるので、
> 使えないって事?

そうじゃなくって、要件を満たしていないのでは? っていう意味。
0078デフォルトの名無しさんNGNG
#同意も反論も不要。なんかあったら↑のスレで言ってくれ。とか貼られそうな予感・・・・
0079Kusakabe YouichiNGNG
In article >>76, 76 デフォルトの名無しさん
wrote:

> あらかじめ含めない値をランダムに求めておいて、並べ替えるやり方はどうです
か?
> たとえば、2を含めないと決めたら、
> A[10] = {0, 1, 3, 4, ..., 9}
> を作って、並べ替えるやり方。

ですから、その「あらかじめ含めない値をランダムに求めておいて」のところは
どうやるの? :)
0080デフォルトの名無しさんNGNG
>>62
結局何の確率が知りたいのかわかんない。

rand()関数の出目の確率なのか。
配列を使った自作関数での出目の確率なのか。
0081デフォルトの名無しさんNGNG
>>79
自分なりに考えてやって見ました。
これで何点くらい、もらえますか?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define M 100 // 乱数の範囲
#define N 10 // 必要な乱数の範囲

int main()
{
 int table[M];
 int i;
 srand(clock());

 for( i = 0; i < M; i++ ) {
  table[i] = i;
 }

 for( i = 0; i < N; i++ ) {
  int r = rand() % M;
  int tmp = table[i];
  table[i] = table[r];
  table[r] = tmp;
 }

 for( i = 0; i < N; i++ ) {
  printf("%d ", table[i]);
 }
 printf("\n");

 return 0;
}
0082デフォルトの名無しさんNGNG
符号付き整数を符号維持したまま右シフトするもっとも単純な方法って?
FAQには符号付き整数の右シフトは処理系依存と書いてあります。

#define RSHIFT(i,n) ((i>0?1:(-1))*(signed)(((unsigned)i)>>n))

こんな馬鹿みたいなのしか思いつかないのですが。
0083デフォルトの名無しさんNGNG
sizeof(unsigned long) < sizeof(void *)
な処理系、あるいは両者のcastがうまくいかない処理系って
どんなのがありますか?規格では保証していないようですが。
0084デフォルトの名無しさんNGNG
>>82
そのやりかた、あってる?
あと、FAQの何章に書いてありました?
見つからなかった(^^;
0085デフォルトの名無しさんNGNG
>>82
いいんじゃないの?
それならcharでもintでもいけるし。たぶん。

最上位ビットを残して云々 って一瞬考えたけど
処理系にすげー依存しそうだしやめた。
0086デフォルトの名無しさんNGNG
>>85
マイナスのとき、処理がうまくいかないよ。
0087Kusakabe YouichiNGNG
余談ですが、

In article >>81, 81 デフォルトの名無しさん
wrote:
>  for( i = 0; i < M; i++ ) {

こういうふうに「for」と「(」をはくっつける、
「(」と「)」の内側に空白を明けるっていうのは、
どこの影響だろう :)

括弧のフォントをデザインした人がかわいそうだ :)
0088デフォルトの名無しさんNGNG
>>82 シフトせず、2で割る。 i /= (2 << n);
でも、そういうのはアセンブラで書いたほうが確実。
処理系依存部分は、処理系依存言語に任せる。これ最強。
0089Kusakabe YouichiNGNG
In article >>82, 82 デフォルトの名無しさん
wrote:

> 符号付き整数を符号維持したまま右シフトするもっとも単純な方法って?

「>>>」 :-P

> FAQには符号付き整数の右シフトは処理系依存と書いてあります。
> #define RSHIFT(i,n) ((i>0?1:(-1))*(signed)(((unsigned)i)>>n))
> こんな馬鹿みたいなのしか思いつかないのですが。

unsignedにcastするか、負の場合だけ場合分けしてmaskを使うかでしょうね。
009082NGNG
>>84
すみません。処理系依存とは書いてないですね。
ですが Q20.15(書籍版ですが)に「負の数を右シフトすることは割算と
等しくない」とあります。

また、K&R第2版の253ページに「右シフトを負の数にした場合、結果は処
理系依存」という旨の文章があります。

>>84,86
思いきりまちがえてますね。失礼しました。

(ちょっとオリジナルFAQ&JIS本見る時間が無いので夜まで失礼します)
0091デフォルトの名無しさんNGNG
なるほど、カニチャーハンには
右シフトしたときに処理系によって
0が入るのと符号がはいるのと両方ある
って書いてあるね

手元のだとP60だから、まあその辺
0092デフォルトの名無しさんNGNG
>>89
>>> って古いコンパイラでもつかえる?
0093デフォルトの名無しさんNGNG
>>81
60点。確率が均等でない。
ためしにN=2でtable[0]が2になる確率を考えてみろ。

19,4c19,7
<   int r = rand() % M;
<   int tmp = table[i];
<   table[i] = table[r];
<   table[r] = tmp;
---
>   int r = rand() % (M - i);
>   if (r) {
>    int tmp = table[i];
>    r += i;
>    table[i] = table[r];
>    table[r] = tmp;
>   }
0094Kusakabe YouichiNGNG
In article >>91, 91 デフォルトの名無しさん
wrote:
> なるほど、カニチャーハンには
> 右シフトしたときに処理系によって
> 0が入るのと符号がはいるのと両方あるって書いてあるね

私なら、「そこだけJavaやる」:) も。
なんでCには「>>>」がないんだろうね。
0095Kusakabe YouichiNGNG
In article >>92, 92 デフォルトの名無しさん
wrote:

> >>89
> >>> って古いコンパイラでもつかえる?

いや、新しいのでも無理では?
0096デフォルトの名無しさんNGNG
>>94
> 私なら、「そこだけJavaやる」:) も。

もうね、アホかと。馬鹿かと。
0097Kusakabe YouichiNGNG
In article >>96, 96 デフォルトの名無しさん
wrote:

> >>94
> > 私なら、「そこだけJavaやる」:) も。
>
> もうね、アホかと。馬鹿かと。

そんなにうれしいですか? :)
0098デフォルトの名無しさんNGNG
インラインアセンブラはあっても、インラインジャヴァはありません
0099Kusakabe YouichiNGNG
In article >>98, 98 デフォルトの名無しさん
wrote:

> インラインアセンブラはあっても、インラインジャヴァはありません

あってもだれもつかわなそう:)
0100てきとうNGNG
#define RSHIFT(i,n) (((i<0?1:0)*(~((unsigned)~0)>>n))|(i>>n))
0101てきとうNGNG
(i<0?1:0) は 真偽値が 真:1 偽:0 でない処理系を考慮

かっこがおおいのはかんべんしてちょー ぷりぷり
■ このスレッドは過去ログ倉庫に格納されています