C言語なら、俺に聞け! <7>
■ このスレッドは過去ログ倉庫に格納されています
0001sageジョブス
NGNGあちこちの言語に手を出したが結局極めたのは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言語なら、オレに聞け! <6>
http://piza2.2ch.net/test/read.cgi/tech/999617524/
0083デフォルトの名無しさん
NGNGOSによってはAPIを呼び出せば非同期型スレッドは簡単
SETJMP LONGJMPで 同期型のスレッドは作れる
もちろんアセンブラでスタック切替をしても同じ。
0084デフォルトの名無しさん
NGNGあいうえお<A>かきく<B>けこ→あいうえお@かきく\けこ
のようにある記号で挟まれた文字列をその内容によって
変換するようなプログラムってどう書けばいいでしょうか?
0085デフォルトの名無しさん
NGNG???
いまカッコ内かどうかのフラグを持たせて、
フラグがたってる間だけ変換処理を実行する。
じゃ、ないの?
0086デフォルトの名無しさん
NGNGpthreadライブラリを探せ
0087デフォルトの名無しさん
NGNGそれって正規表現使うのがいいんじゃない?
Cに正規表現ライブラリってあるかなぁ?
008856
NGNGみなさんレスありがとうございました。
しかし一度は納得したものの、再び分からなくなってしまいました。
というのも、
void main(void)
{
char* p="A";
printf ("%d\n",*p);
}
を実行したら、65 が表示されたからです。
『あれ? この場合は65番地の中に入ってるデータが表示されるんじゃなかったのか!?』
とパニックになってます。
どなたかお助けを!!
0089デフォルトの名無しさん
NGNGp と *p は全然別のもの。
ちなみに 'A' == 65 である。
void main(void) {
char *p;
p=65;
printf ("%d\n",*p);
}
とするか
void main(void) {
char *p = 65;
printf ("%d\n",*p);
}
とすればお望みの動作になる。
0090デフォルトの名無しさん
NGNG文字列を " " で囲むと,それは文字列へのポインタになります
しかも文字列の末尾にはちゃんと nil 文字('\0')が付加されます
p にはその文字列へのポインタが代入されます
*p を参照すれば,そこにはポインタに指し示された部分にあるデータを得ることができます
つまり p にはよく分かんないアドレスが,*p には 'A' が入ってるってこと
65 番地のデータを表示させたいならば
char* p = 'A';
もしくは
char* p = 65;
# きっと正確な説明じゃないと思うけど,こんな理解でも大丈夫なはずです
0091デフォルトの名無しさん
NGNGC言語の文字列はバイト列をそのまま扱うような形になります
他の言語で文字型、文字列と順序型が明確に区別されていたのに馴れていると
訳が判らなくなると思います。
*p は いつでも (int)ord(*p) という変換がされているとでも考えて下さい
009256
NGNG>文字列を " " で囲むと,それは文字列へのポインタになります
そ、そうだったんですか・・・・(納得)
'A'はどういう意味になるのですか?
>>91
すみません、僕の頭ではちょっと難しくて・・・・(^^;)
C以外さわったことないんで。。
0093デフォルトの名無しさん
NGNGchar型という8ビットの"整数"です。
char型はASCIIひと文字分の文字コードを扱うのに使ったりします。
C言語の文字列はchar型の単なる配列です。
0094デフォルトの名無しさん
NGNGどうすればいいかな?
0095デフォルトの名無しさん
NGNG0096デフォルトの名無しさん
NGNGint8_t, int16_t, int32_t を使えと言われたんですが、
char, short, long では何かまずいんでしょうか?
教えてください。
0097デフォルトの名無しさん
NGNGなにもまずくないけど?
0098デフォルトの名無しさん
NGNG目的も書かずに、「char, short, longは使うな、
int8_t, int16_t, int32_t を使え」っていうのでは何とも言えない。
「何のために」っていうのがまずあるはず。
教えて下さいの前に、質問の仕方を改めること。
場合によっては、Cは使うな、Perlの方がずっとその目的には向いてる、
ということもある。
0099デフォルトの名無しさん
NGNGC++やDelphiだと文字コードを意識しなくていいって?
Delはプラットホームが限られるからってことか?
0100デフォルトの名無しさん
NGNGネットでいろいろ検索しましたが、うまく行きません。
知っておられたら、教えてください。
環境:MS-DOS/V 6.2
コンパイラ:VC++ 1.51 (MS-C 8.03)
で行っています。
よろしくお願いします。
0101デフォルトの名無しさん
NGNGテスト中のソースは以下の通りです。
struct SREGS sregs;
union REGS inregs, outregs;
long timl;
short tims;
interrupt timint(void)
{
_disable();
timl++;
tims++;
printf(" %04x\n",tims);
_enable();
int86x(0x1c, &inregs, &outregs, &sregs);
}
void timer_set()
{
void far *ptr;
ptr = timint;
inregs.h.ah = 0x02;
inregs.x.cx = 1; // 1で10[ms]
inregs.x.bx = FP_OFF(ptr);
sregs.es = FP_SEG(ptr);
int86x(0x1c, &inregs, &outregs, &sregs);
}
void main(void)
{
// void interrupt (*vect)();
timl = 0l;
tims = 0;
// vect = _dos_getvect(7);
timer_set();
while(1){
printf("xxx=%04x,yyy=%08ld\n",tims,timl) ;
}
// _dos_setvect(7, vect);
}
tims、timl 共に0のままです。
0102100
NGNGstruct SREGS sregs;
union REGS inregs, outregs;
long timl;
short tims;
interrupt timint(void)
{
_disable();
timl++;
tims++;
// 見やすいようにずらしてます。
printf(" zzz=%04x\n",tims);
_enable();
int86x(0x1c, &inregs, &outregs, &sregs);
}
void timer_set()
{
void far *ptr;
ptr = timint;
inregs.h.ah = 0x02;
inregs.x.cx = 1; // 1で10[ms]
inregs.x.bx = FP_OFF(ptr);
sregs.es = FP_SEG(ptr);
int86x(0x1c, &inregs, &outregs, &sregs);
}
void main(void)
{
//void interrupt (*vect)();
timl = 0l;
tims = 0;
// vect = _dos_getvect(7);
timer_set();
while(1){
printf("xxx=%04x,yyy=%08ld\n",tims,timl) ;
}
// _dos_setvect(7, vect);
}
0103デフォルトの名無しさん
NGNG0104100
NGNGvolatile short tims;
long volatile timl;
short volatile tims;
共に駄目でした。
long far timl;
short far tims;
も駄目でした。
0105100
NGNGメインルーチン側の printf をコメントすると、動かなくなります。
(Ctrl+Alt+del でリセットされるので、永久ループになってるだけですが。)
0106103
NGNGgoogleでちょっと検索してみたら、>>100が参考にしたと思わしきソースを
見付けたんだけど、「PC-9801用」って書いてあるよ?
>>100がMS-DOS/VだということはPC互換機だと思うんだけど、そもそも
この方法でタイマー割り込みが使えるのはPC98onlyだったりしない?
あと、割り込みハンドラ(timint)内でprintf()ってのは大抵の場合
ヤバイと思う。
0107100
NGNG割り込みベクタやアドレスが一緒なので、これでやってます。
> あと、割り込みハンドラ(timint)内でprintf()ってのは大抵の場合
> ヤバイと思う。
削除します。
0108デフォルトの名無しさん
NGNG割り込み周期の変更は知らん。
0109100
NGNG0x1cに、timer_set() で timint() を割り当ててると思ってました。
timer_set() をやめて、_dos_setvect() で 0x08 に timint() を
割り当てると、『1回だけ』動きました。
(数値が1で止まって、カウントアップしませんが。)
まだ問題はありますが、0x08 で テストを続けたいと思います。
どうもありがとうございます・
引き続き、情報を募集しますので、何か知ってたら教えてください。
0110103
NGNGしまうと、DOS自身の割り込みハンドラが呼ばれなくなってまずいような
気がする。
setvectする前にgetvectで古いベクタを保存しておいて、timintの中で
カウントアップの処理をした後で、書き換える前のベクタへジャンプする
必要があるんじゃないかな?
0111デフォルトの名無しさん
NGNGなに言ってんだか。
0112100
NGNGご忠告ありがとうございます。
今は、テスト中なので、リセット覚悟でやってますが、
最終的にはきっちりしようと思ってます。
0x08でやると、凍ってしまいます。
何か設定があるのでしょうか?
誰か知りませんか?
0x1cでやると、カウントアップは出来ました。
ただ、周期が約55msに固定で、必要な10ms間隔にならない為、
使えない事が判明しました。
0114100
NGNGもしや最初にスレを立てた伝説の?(@_@)
> CLIしてるなら、きっと中の処理が遅くて再入してるよ
CLIとかNMIとか、よくわからないんですが
メインループの printf の画面表示が止まらないので、
再割り込みはしてない気がします。
ちなみに0x1cでやると、Ctrl+Cで中断できるんですが
0x08でやると、Ctrl+Cで中断出来ません。
0115デフォルトの名無しさん
NGNG_enable()で割り込みを許可していると思われ。
CLI、STIは割り込みを禁止したり許可したりするアセンブラ命令
割り込み内部(timint)はカウントと
旧ベクタへ飛ばすのみにしておく。
タイマ周期の変更はポート叩く方法しか知らん
しかもアセンブラ。
011656
NGNGそれは分かってますよ。
"a"と'a'の違いがわからないのです。
0117デフォルトの名無しさん
NGNG"a"はポインタ。
0118デフォルトの名無しさん
NGNGもう,これは慣れるしかないと思います・・
とりあえず次のコードを実行してみれば,なんとなく感覚がつかめませんか?
#include <stdio.h>
void main(){
char* a1 = "A";
char* a2 = "A";
char* b1 = (char*)'A';
char* b2 = (char*)'A';
printf("a1=%d,a2=%d,b1=%d,b2=%d", a1,a2,b1,b2 );
}
char* b1 = 'A';
ではなく
char* b1 = (char*)'A';
とキャストしているのは,'A' が const char 型であって
const char * 型ではないからです
0119デフォルトの名無しさん
NGNG0121デフォルトの名無しさん
NGNG"a" == 'a','\0'
というように文字と文字列は違う。
char a='a';
char b="a"; //エラー。文字列は char に収まりきれない。
char *c = "a"; //"a"という文字列のアドレスを入れているのでOK。
char d[2]="a"; //上記に示したとおり、char2個分だから収まる。
c はポインタ。変数や配列のアドレスを c という名前で管理する。
d は配列。変数の連なりに d という名前を付けている。
その領域を"a"で初期化している。
"a"は変数名のない配列。
しかもプログラムのどこにあるのやら人間には判別つかない。
それではプログラマが利用できないので
名前をつけて"a"のある場所を知る必要がある。
その方法が char *c = "a";
printf("a")では"a"という文字列を表示したいだけで、
"a"のある場所を人間が知る必要ないから
そのままPCにおまかせしている。
0122デフォルトの名無しさん
NGNG微妙に痛いんですが。。。
012356
NGNGおお!
なんと解りやすい解説!!
ありがとうございまいた <(_ _)>
0124デフォルトの名無しさん
NGNG文字定数は C 言語では int で C++では charになります
0125デフォルトの名無しさん
NGNG同意。この説明で分かった気になってしまうと後がこわいかも。
012656
NGNG0127デフォルトの名無しさん
NGNGchar *c = "a"; の"a"と
char d[2] = "a"; の"a"は意味が違ってる。
char d[2] = "a"; は、単に char d[2] = { 'a', '\0' }; の省略形。
char *c = "a"; の"a"は変数名のない配列…というのは、当たらずとも
遠からずというか、やっぱり文字列定数は文字列定数としか言いようが
ないような。ただの配列だと思い込んでると思わぬ所でハマる。
上記の後で、
d[0] = 'b'; はOKだけど
c[0] = 'b'; ってやるのは規格上NG(実際は動いたりするのでたちが悪い)
更に、
char *e = "a"; とやった場合、c == e である場合も c != e である場合もある
(規格上はどちらも間違いではない)
0128121
NGNGありがとう。
教えるのは難しいなり。
012956
NGNG>char *c = "a"; の"a"は変数名のない配列…というのは、当たらずとも
>遠からずというか、やっぱり文字列定数は文字列定数としか言いようが
>ないような。ただの配列だと思い込んでると思わぬ所でハマる。
思わぬ所ってどこっすか?
013056
NGNG>(規格上はどちらも間違いではない)
これは感覚的に理解できます。
0131デフォルトの名無しさん
NGNGいまのとこ画像は本腰でないのでこうしているんだけど、
警告される。bfTypeがchar[2]か[3]かわかんないので、
"BM\0"とやる気にもならないし、メンバの場合の[]の
使い方もわかんない。
bMfh.bfType[0]='B'bMfh.bfType[1]='M'で
いいのかな、(\0はどうすんのかな)それとも、bMfh.(&bfType[0])
とかやっちゃうの?それとも(bMfh).bfTypeとか?
もーわかんない。
0132デフォルトの名無しさん
NGNG・・・と、最初は思ってればいいよん。
bMfh.bfType[0] = 'B';
strncpy(bMfh.bfType, "BM", 2);
>bfTypeがchar[2]か[3]かわかんないので、
これは問題あると思うが。
0133127
NGNGうーん、>>127の後半に書いた通りなんだけど、
書き換えができないというのは分かりやすいからいいよね?
後は、「同じ文字列」のとらえ方によって結果が違ってくるってこと。
char *a = "abc";
char *b = a;
この場合、aとbの文字列の内容は同じだし実体も同じ。
if (strcmp(a, b) == 0) { ... } も
if (a == b) { ... } も成り立つわけ。で、
char a[] = "abc";
char b[] = "abc";
これは、aとbの文字列の内容は同じ、だけど実体は別。
if (strcmp(a, b) == 0) { ... } は成立、
if (a == b) { ... } は不成立。だけど、
char *a = "abc";
char *b = "abc";
これは? 文字列の内容はもちろん同じ。
if (strcmp(a, b) == 0) { ... } は成立。でも、
if (a == b) { ... } は?
どちらになるかは不定なので、どちらかを期待してプログラミングしちゃいけない。
こんな感じで、文字列の場合、
・見かけが同じ
・実体が同じ
の二つの「同じ」があって、なおかつ文字列定数の場合は後者の「同じ」が
定義されない場合があるので、自分が期待している「同じ」が何なのかをちゃんと
考えてプログラミングしないとハマるわけ。
てな説明で分かってもらえますか?
0134デフォルトの名無しさん
NGNG0135デフォルトの名無しさん
NGNGtypedef struct tagBITMAPFILEHEADER { // bmfh
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
これか? MSDNで見つかるだろ。
0136デフォルトの名無しさん
NGNGそだね
0137ビル・ジョブス
NGNGじゃー"a"はどこにあるのかな?「記憶クラス」って知ってるか?
0138デフォルトの名無しさん
NGNG0139デフォルトの名無しさん
NGNGちゃんと動いてるんだけど、考えると
strcpy(bMfh....,"BM")←つまり&がない。
でも正解なのが不思議だ・・・
0140ビル・ジョブス
NGNG文字列はアドレスだから、違和感無いよ・・・
0141デフォルトの名無しさん
NGNGbf.bfType = MAKEWORD('B','M');
stBmpFileHeader.bfType = 0x4d42
bmHead.bfType = ('B' | ((WORD)'M' < < 8))
memcpy(&fh.bfType,"BM",2);
bmFileHead.bfType = 19778;
BmpFileHeader.bfType = 'MB'
char bfType[2];
0142132
NGNGげげ。135を見るとbfTypeつーのは
char bfType[2]でもchar bfType[3]でもなくてWORD bfTypeじゃんよ。
早く言ってくれよオイ。聞いてないよ−。
それじゃ strcpy(bMfh.bfType, "BM") は間違い。"&"付きが正解。
0143ビル・ジョブス
NGNG"&"付きでも基本的に間違い!NULLがセットされるでしょ。
しかーし、今回はアライメント合わせされてるので動作するな。
しかし、いかん、おれには書けない・・・。
0144100
NGNG>CLI、STIは割り込みを禁止したり許可したりするアセンブラ命令
アセンブラの割り込み許可/禁止って、EI/DIだと思ってました。
NECだけ?
>タイマ周期の変更はポート叩く方法しか知らん
>しかもアセンブラ。
よろしければ、ポートだけでも教えてもらえませんか?
アセンブラも多少ならわかりますので、見せて頂けたら幸いです。
0145デフォルトの名無しさん
NGNG0146デフォルトの名無しさん
NGNGbf.bfType = MAKEWORD('M', 'B');
0147デフォルトの名無しさん
NGNGかなり昔のを発掘してきた。
ttp://gooside.com/himitsu/timer.zip
DLしたら教えてくれ。即削除する。
0148どしろ〜とちゃん
NGNG「構造体を直接引数で渡すな!ポインタで渡せや!」
って、結構プログラムやってるツレから言われたんですけど、
さっぱり意味がわかりません。
なんで直接渡しちゃだめなん?
0149デフォルトの名無しさん
NGNG0150デフォルト名無しさん
NGNGなんでっすか?
0151デフォルトの名無しさん
NGNGその簡単な例を挙げてくれ
0152デフォルトの名無しさん
NGNGhttp://mentai.2ch.net/test/read.cgi/prog/1002039334/
015356
NGNG知ってますけど、"a"はどこにあるのかは分かりません。
0155
NGNGまあそのツレもあえて「構造体を」って言ってるところがまだ青い。
0156どしろ〜とちゃん
NGNG結局、場合にもよるが、基本的にメモリにバカバカコピーすんのは
タコでそ?・・・ってことで、おけ〜ですか?
しかし・・・>155サンの
>まあそのツレもあえて「構造体を」って言ってるところがまだ青い。
が、わかんないっす〜。なんで?
0157デフォルトの名無しさん
NGNG0160デフォルトの名無しさん
NGNGvirtual foo(const char *name);
virtual foo(const unsigned int num);
}
class B:public A{
foo(const char *name);
foo(const unsigned int num);
}
class C:public B{
foo(const char *name);
foo(const unsigned int num);
}
と書くと、class Cでのオーバーロードが解決できないと言われてしまいます。
もしかして根本的に勘違いしてるのでしょうか?
0161デフォルトの名無しさん
NGNG0163デフォルトの名無しさん
NGNG例外中立をぶちこわしたいとき
0164デフォルトの名無しさん
NGNG構造体を実体渡しすると全部をスタックにつむから、ポインタ渡し
と比較して余計にスタックを消費する.
昔の人はメモリは貴重な資源だったので、実体渡しは裂けていた.
あと、ループ中に [] を使用して構造体を参照しているところは
ポインタを取得するとアドレス計算か減って早くなった.
ex)
for (i = 0; i < 100; i++) {
a[i].hohoe01 = 100;
a[i].hohoe02 = 200;
.
.
}
を
for (i = 0; i < 100; i++) {
pa = &a[i];
a->hohoe01 = 100;
a->hohoe02 = 200;
.
.
}
といった理由で、漏れは必ずポインタ渡しを使用しており、その
習慣は今でも引き継がれている.
ただ、自分の使用している コンパイラでアセンブラソースを
出力するようにして、なにが最適化確認するのが吉.
へたなことして自己満足していると最適化処理の足をひっぱるだけに
なっていることがある.
0165デフォルトの名無しさん
NGNG実測で十分。
0167デフォルトの名無しさん
NGNG処理系は?
むしろクラス定義の後にセミコロンがないとか戻り値が宣言されてないとかで
文句いわれそうな気が。
0169デフォルトの名無しさん
NGNGうーむ、ネタでしょうか.詳細キボンヌ
0170デフォルトの名無しさん
NGNG下のプログラムが動きません。
表示されるのは0.000000になってしまいます。
#include<stdio.h>
void main(void)
{
double data;
FILE *fp;
fp = fopen("data.txt","r");
fscanf(fp,"%f",&data);
printf("%f",data);
fclose(fp);
}
0171デフォルトの名無しさん
NGNG0173デフォルトの名無しさん
NGNG%lf にしてみて。
%f は float に反応するけど double には無反応みたい。
0174デフォルトの名無しさん
NGNGとりあえず、これならコンパイルできるぞ。
class A
{
virtual void foo(const char *name);
virtual void foo(const unsigned int num);
};
class B : public A
{
void foo(const char *name);
void foo(const unsigned int num);
};
class C : public B
{
void foo(const char *name);
void foo(const unsigned int num);
};
あと、C++こっちでやって
http://piza2.2ch.net/test/read.cgi/tech/1003832761/
0175デフォルトの名無しさん
NGNGおそらく、fooに戻り値が無いから、
コンストラクタと解釈されておかしくなってると思われ。
0176デフォルトの名無しさん
NGNGその場合、グローバルでとってあるか、動的に確保した領域使うと思う.
前者ならプロセスの寿命で、後者ならポインタで管理になるよね.
0177デフォルトの名無しさん
NGNGありがとうございました。
うまく動きました。
017856
NGNGわかりやすい解説ありがとうございました!
今>>133のレスに気付きました、遅くなって失礼しました。
了解です、理解しました♪
これで僕の>>56の疑問はかなり霧が晴れました。
レスくれたみなさん、ありがとうございました!!
0179デフォルトの名無しさん
NGNG#if 1 == 2
#error 1 == 2 <- ここはエラーにならない
#endif
#if a == b
#error a == b <- ここでエラー
#endif
何でこれエラーになるの?
0180デフォルトの名無しさん
NGNGファイルの操作を行う中でファイルの先頭行と最終行を削除すると
いう機能を盛り込みたいのです。
fopenを追加モードで開いてポインタを先頭に持ってけばいいかなと
簡単に考えていたんですが、思ったようにうまくいきません。
先頭行、最終行ともに文字列があります。
どなたかよろしくお願いします。
0182デフォルトの名無しさん
NGNG定数じゃないぞ。enum を #define で書き直せ
■ このスレッドは過去ログ倉庫に格納されています