ptintfの%nはハッカー用に用意されているのでしょうか?
visual studioが重いからvisual studio codo使って勉強してますが、これでデバッグできる環境設定がネットのだとよく分からないんですがどうやってやれば出来ます?
>>9
gdb からは逃げ回っています、可能な限り printf() デバッグの方を選択します >>11
fflush() は必ずペアで使いますよ、まあそれでも iostream<<と混在させるとぐちゃぐちゃになりますね ここはC言語のスレなので iostream の事は忘れてくれ。
14デフォルトの名無しさん2018/02/21(水) 07:13:52.97
setbuf(stdout, null);
setbuf(stderr, null);
しとけばいいじゃん
変数宣言後に値を代入する前にprintfで表示させると数値がでてきますがこれは何の数値ですか?
意味のある値を期待してはいけない謎の値
固定値か実行毎に変わるかも謎
スカートめくりしてはいけないのと同じ、見てはいけない場所
グローバル変数とstaticなローカル変数はその変数の型によって決められている値(0や0Lや0.0など)で初期化される
staticでないローカル変数(殆どはこれ)の値は不定
定まった値を入れる手間すら惜しんでもいいようにしてるから
Cで引数リスト部分が空の関数ポインタと構造体値渡しを↓のように組み合わせて使うのはNGですか?
#include <stdio.h>
long func(long a, char b, short c) {
return a+b+c;
}
int main(int argc, char *argv[]) {
long(*pfunc)() = func;
struct {
union {
char a;
short b;
long c;
} u[3];
} param;
param.u[0].a = 1;
param.u[1].b = 2;
param.u[2].c = 3;
printf("%d\n", pfunc(param));
return 0;
}
全くの初心者だがプログラム手に入れて動かしている。
最近はテトリスを動かした。C言語は学生の時に
挫折しているので高望はしていないが俺の時代よりも
学習環境も随分と楽になったもんだ。
[] [[[ [[ [] ][ [] [ ] [] ][]] [[[ [] }
>>25
NGっていうか、それ普通にダメだよね。型が一致しないし。
まあ、Cコンパイラの実装によってはうまいことスタックに積まれて a, b, c が意図した通りに伝わるのかも知れないが、
しかしそれは実装依存だ。同じコンパイラ使っても最適化したら違う結果になるんじゃないだろうか。 >>25 >>30
引数リストが空の場合に「引数を持たない関数」ではなく
「引数の整合をチェックしない関数」と解釈する、
古いCでの動作を期待してるんじゃないかな。一応は規格準拠のはず。
コンパイルオプションでの規格指定がモロに影響する部分かも。
構造体を値渡しで引数にするとき、単純型とは異なるスタックの使い方をする
可能性があるから期待とおりに動くかもしれん、動かないかもしれん、だな。
仮に各要素をスタックに積む場合でも、単純型の並びとは逆順に
スタックに積まれる可能性もあるんじゃないか。 たびたび申し訳ない。
引数リストを書かない関数定義/宣言 func() は
どのCでも func(void) とは解釈されないんだっけ?
C99で将来廃止予定という情報は見つかったけど、まだ廃止されてないか。
ウインドーズのコマンドラインオプションで記号が{があると
ダブルクオートで囲んでもこの記号の前で引数がおわってしまうんですけどなぜでしょうか?
リナックスではそうはなりませんでした、{の前にエスケープ文字\を置くとうまくいきました。
なぜこうなるのか教えてください。調べてもわかりませんでした。
>>36
それはC言語の範疇ではないよ。
windowsのコマンドプロンプトやLinuxのシェルとかを調べるといいかも。 >>36
具体的にどういうプログラムやコマンドでどういう操作をしてそういう現象が起きたのか、手順を一通り書いてみて
ひょっとして自作のCプログラムでそうなったとか? 自作のプログラムでやりました。
具体的に書くとa "abcd{efghijk"みたいにコマンドをじっこうすると
メイン関数のおぷしょんをしらべるとabcdしか入っていませんでした。
>>36
自作コマンドにコマンドライン引数が渡る前に何者かが横取りするんだな。
Windowsのバージョンとか、コマンドプロンプトの種類とか、
Cコンパイラの種類を書くと情報が集まりやすいかも。 >>39
gcc (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 7.2.0
Microsoft Windows 10 Pro 10.0.16299 N/A ビルド 16299
→ 再現せず >>39
コマンドシェルの都合か コンパイラのランタイムの都合か
環境(使ってるコンパイラ 実行環境:コマンドラインからなのかデバッガーからなのか etc) に
委ねられてるかんじだな ありがとうございます。
シェルを変えたらできました。
eshellからmsys2に付属のやつに替えますた
>>47
それを先に言わないと
一番肝心のことじゃないか・・ >>47
eshellは{}に特殊な意味がある。
それはeshellコマンドの実行結果に置き換えられる。(shのバッククオートと似ている)。 スロットゲームを作成しようと思っていろいろサイト見てるんですけど、数字の1〜9を順番にループ表示ってどうやるんですか?
>>50
0〜9、そして0が描かれた画像を表示部分だけをクリッピング(切り抜き)して、回転させてアニメーションする。 >>26 >>30 >>33
コメントありがとうございました。
狙いは>>33に書かれてる通りで、>>25のコードもMinGWのgccでコンパイルが通って
実行結果も期待通りだったことから大丈夫なのかなと思ったのですが・・・。
そもそも古い書き方で、将来無くなる予定(ってC99の6.11.6に書かれてるんですね)との
ことですので止めておきます。 int main(void), int main(int, char**) どちらも ok なのだか
int (*pfunc)()のような書き方はなくならないと思う
long(*pfunc)() = func; の行がエラーになるのか。
long(*pfunc)(long, char, short) = func; なら通る。
「longを返す関数なら何でも入れられる関数ポインタの変数」てのが
認められないのね。
良く考えると関数用の汎用ポインタが無いのはおかしい
無理だよ
仮引数の違い=スタック構造の違いなんだから
gcol(rcol & 0xFF , & gcol & 0xFF ,
bcol & 0xFF)
これの意味を教えてください。
>>58
gcolor(rcol & 0xFF , & gcol & 0xFF ,
bcol & 0xFF)
これの意味を教えてください。 >>57
呼出側が責任持つのがc流で、だから可変引数が実装出来る
って習ったんだが、最近は違うのけ? >, & gcol & 0xFF ,
間違ってるような気がするけどな。
変数/関数名からRGB値取ってるだけに思えるし。
>>61
それは変数宣言で
rcol gcol bcol =64です。
&16進数なのはどうしてですか? >>60
可変引数?
void func(double);
void (*ptr)() = func;
ptr(1); //1.0で渡すべきところ1が渡される
void func(double arg) //スタック構造の不一致が起きる
{
//全然関係ねえだろ
} >>63
8 bit 幅分だけ &(and) 演算子で切り取っているのではないですか? >>60
可変引数なら可変引数として書かないとだめでしょ >>64
そうか、良かったな。
所で、最近はそういうのも可変引数って言うように
なったのか。varargs.hは廃盤か。 >>68
あれが可変引数?
俺は全然関係ねえだろって書いたんだが ID:fgXllc68d は必要な情報書かな過ぎ。
可変個引数は va_start() するときに番兵となる引数が必要なので
最低でも1個は固定の引数が欲しいんだよね
func(int , ...) とかになる
可変長引数なんて認めなければよかったのにな。
またはJavaみたいにシンタックスシュガーにしておいて実は配列に変換して要素数と共に渡すみたいにしておけばもっとましな感じになったのに。
Bの頃からあったprintfの実装テクニックだし
だいいちCは簡潔さを売りにしてたんで
理想論に走って複雑さを増すようなことを嫌ったんだよ
>>72
せやな。
で、func(int,....) な関数ポインタは作れるよね。
それを汎用的に使うことは出来る。ってのが56への回答じゃね? void func(int, double);
void (*ptr)() = func;
ptr(1, 1); //1.0で渡すべきところ1が渡される
void func(int top, double arg) //スタック構造の不一致が起きる
{
va_list ap;
va_start(ap, top);
assert(va_arg(ap, double) == arg); //通るわけねえだろ
va_end(ap);
}
>>75 いいや ポインタだけじゃ片手落ち
(キャストじゃだめで)関数の実体側の引数も同じ引数で実装しなければならない スタートアップは argc,argvをスタックに積んで _mainを呼ぶ
_mainが int main(void)だとしても問題ない
>>67 はエラーなくコンパイル・実行できてるようだから、もう少し検証。
ideone.com でなくローカルのgccで実験。
どうやら func() 定義の引数リストに制限があるみたい。
void f(double x) ... エラーなし ( >>67 の例と同じ)
void f(int x) ... エラーなし
void f(void* x) ... エラーなし
void f(char x) ... 警告:「互換性のないポインタ型」
void f(short x) ... 警告:「互換性のないポインタ型」
void f(float x) ... 警告:「互換性のないポインタ型」
警告は void (*pfunc)() = f; の行で発生。
実引数の自動拡張よりも狭い幅の仮引数の型を使おうとすると警告かな?
コンパイラによって動作が異なる部分で、深追いする価値は無いのかも。 >>77
78が正解。更に言えばmainの引数には envp もある >>81
posix にもある、推奨されているわけではないが 補足というか訂正。
>>55 で「long(*pfunc)() = func; の行がエラーになる」
と書いたけど警告だった。よって >>25 のソースもコンパイル可能。
ちなみに結果は期待の 6 とは桁違いのデカい数値だった。 >>83
>>25の書き方そのままじゃlong aの部分しか渡されてないからb, cは不定値になってるのでは? >>87
param には「long幅の共用体3要素の配列」が含まれるから、
値渡しすればスタックに (sizeof(long) * 3) byteのデータが積まれるはず。
というか、main()でparamの各要素をlong解釈で表示させたら
見事にaやbの上位ビットにゴミが入っていた。 >>88
> 各要素をlong解釈で表示させたら見事にaやbの上位ビットにゴミが入っていた。
それは初期化の問題では?
確かに値渡しはスタックにコピーされるけど、関数の引数にはもう一回コピーはいるから、そこで関数不一致の弊害が発生すると思う
>>25のコードそのままだとaしか正しく渡されてなくて、b,cは明後日の方向からデータ取ってきてるかと >>88 に「期待の6」と書いたせいで誤解させてしまった。
もちろん実際の動作で6が表示されると思っていたわけじゃないのだ。
この流れの発端の質問 >>25 と、それに追加された >>52 の、
「実行結果も期待通りだった」て記述を受けての「期待の6」でね。
むしろ共用体への代入で、
param.u[0].a = 1; // charの代入 byte転送命令
param.u[1].b = 2; // shortの代入 word転送命令
param.u[2].c = 3; // longの代入 dword転送命令
てな具合にアセンブルされ a, b の上位ビットに未初期化のゴミが残り、
関数に実引数の値として渡されるときもゴミごとコピーされるのは当然。
>>52 で期待通りに動いたのは、paramの未初期化での状態が
たまたま全部ビットで0だったんだなぁ、というお話。
>>25 のリストで、関数 func() の仮引数 a, b, c の型と、
共用体の要素 a, b, c の型が食い違ってる点にも注目して頂きたい。
…長々と失礼。誤解の余地なく説明しようとするとクドくなってしまう。 #include <stdio.h>
#include <string.h>
#define BUF_SIZE 80
void* my_realloc( void* p, size_t bytes, int line ) {
if( (p = realloc(p, bytes)) == NULL ) {
fprintf(stderr, "realloc failure called at line %d\n", line);
exit(EXIT_FAILURE);
}
return p;
}
int main () {
FILE *fp;
char *file = "data.csv";
char buf[BUF_SIZE], input[BUF_SIZE], format[20];
char **result, *s;
int i, size = 50, count = 0;
if( (fp = fopen(file, "r")) == NULL ) {
perror(file);
exit(EXIT_FAILURE);
}
sprintf(format, "%%%ds%%*[^\n]%%*c", sizeof(input) - 1);
scanf(format, input);
result = my_realloc(NULL, sizeof(*result) * size, __LINE__);
while( (fgets(buf, sizeof buf, fp)) != NULL) {
if( strstr(buf, input) == NULL ) continue;
s = my_realloc(NULL, strlen(buf) + 1, __LINE__);
strcpy(s, buf);
result[count++] = s;
if( count >= size ) result =my_realloc(result, sizeof(*result) * (size += 20), __LINE__);
}
for( i = 0; i < count; i++ ) {
printf(result[i]);
free(result[i]);
}
free(result);
return 0;
}
上記のコードから追加でしたいことが2つあります。
@検索単語を2つにしたい。
Aフォルダないの全ての.csvファイルを検索かけたい。
sprintf(format, "%%%ds%%*[^\n]%%*c", sizeof(input) - 1);
scanf(format, input);
result = my_realloc(NULL, sizeof(*result) * size, __LINE__);
ここの文の意味が分かりません。
>>94
クソコードだ。あまり参考にせず、自分で考えた方がいい。
my_reallocはreallocをラップした関数形式マクロのようだ。リファレンスのreallocを参照。
__LINE__は現在の行番号を表し、デバッグなどに使う。
sprintfはprintfを文字列出力にしたものだ。%%は%になって出力される。 sprintfで出力した文字列をscanfに書式として渡している。でもこのようなscanfの使い方はオススメできない。
%dは整数を表す文字列になるので、%%%dsは%(何らかの整数)sになる。これは文字列出力の幅指定だ。
幅指定には、別の直接的な方法があるので、こんなことしなくてもいい。
scanfの使い方は引数の個数がちょっと間違っているように見える。
バグや不具合の元になるscanfなんて使うな。fgetsとsscanf使えば充分で分かりやすくて確実だ。
>>94
@else ifでええやん
Areaddirでええやん
myreallocみたいなモンはマクロにしとけ
reallocみたいな糞ライブラリ使うな
sprintfみたいな糞ライブラリ使うな 特定のフォルダ(dir)内のファイルを順次処理したいときは
Unix系ならばopendir()、readdir()、closedir()を使う。
VCならばFindFirstFile()、 FindNextFile()、FindClose()を使う。
たしかに realloc() はいろいろまずいところがあって、
一番悪いのは、やり直しができない、ということ
一致した行をそのままファイルに書き出す方が簡単な気がする
>>99>>101
え? realloc() が糞?じゃあ malloc() で確保したメモリ領域の大きさを変えるのは何を使えばいいの?
自分で確保し直して中身を自分で全部コピーしろと? >>101
てか、やり直しができないってどういう意味?幾らでもできると思うが。 1バイトでもメモリ消費量を節約する事が求められた世代と
湯水の如く無尽蔵にメモリが使える世代のバトルが始まる?
>>92 >>94
sprintf(format, "%%%ds%%*[^\n]%%*c", sizeof(input) - 1);
の行では input[BUF_SIZE] で BUF_SIZE が80であることから
format[] に "%79s%*[^\n]%*c" (\nは改行コード) が格納される。
よって scanf(format, input); は scanf("%79s%*[^\n]%*c", input); の動作。
変換指定の "%79s%*[^\n]%*c" の意味や妥当性は別のお話。
>>96
scanf() の変換指定文字列を sprintf() で生成するやり方は
『プログラミング作法』(カーニハン&パイク)に載ってる。
BUF_SIZE の定義を変えたときにscanf()の変換指定の文字数指定部分も
自動的に追随させる便法(片方だけ修正忘れの防止)として、悪くないかと。
バッファサイズは固定なのに変換指定を動的に作るのは非効率だ、
という気持ちも分かるけどね。 片山氏はscanfがまともに使えず
自分のミスを道具のせいにする手合いか
>>103
そう
糞と言った理由は冪等性がないから
冪等性よりも結果整合性を重視するならrealloc使えば良いと思うよ >>109 「冪等性がない」の意味を補足してくれまいか。
realloc()に冪等性がない、結果整合性はある、という意味が分からないのだ。 失敗したとき NULL を返しつつ 「引数で渡したポインタは開放されない」
あたりに引っかかりを感じてるんでない?
NULL 返すなら 引数で渡したポインタを開放しろと?
※ 使いにくいかもなぁ…
>>111
それはメモリ確保に失敗してるんだから解放したらダメだよね。
自分で malloc() 使って新規にメモリ確保しようとした場合でも NULL 返されたら元の方は free() しないだろう。 >>110
結果整合性って言葉が悪かったな
reallocの機能を重視するなら使えば良いと思うよって書けば良かった
冪等性の意味が分からないならググってくれとしか あ、もしや >>109 の言ってる冪等性がないって引数で渡したポインタとは違うポインタを返してくることがあるって意味?
あまりにも当たり前すぎて思いつかなかったが。
しかし malloc() の実装にもよるだろうがこれを許さないと効率は悪くなるのではないか? >>115
そう
違うアドレスを返して初めて発現するバグをボケナスビがやらかしてから俺は戒律で禁じた
他にも初期化やアライメントの点もある
メモリ効率を重視するなら自分で管理構造作るべきだと思ってる
冪等性を最重視する俺はこのスレじゃ少数派みたいだからあまり気にせんでくれ >>115
× 効率は悪くなる
○ まともな実装は無理(ほぼ全ての場合に失敗する)
>>116
気持ちは分からんでもないが、
reallocはそれが仕様で、いやならstd::stringみたいにラップするしかない。 >>118
質問者の疑問を解決する事より自分の主張したいことに論点がシフトしちゃうのはよく見る光景だね。
質問スレでそれじゃダメだと思うが。 >>118>>119
確かにそうだな
俺は安価ついた分しかレスしないつもりだったけど、この話題についてはもう止めとく
スレ汚しすまんかった >>103 >>104
c++ には realloc() は取り入れられなかった
ちょっと例が悪いが
concat3(char *a, char *b, cha *c) 文字列a と 文字列b と文字列c を連結して文字列a に返す関数を書こうとする
ここで 2 回の realloc() を行うとする
1 回目の realloc() は成功するが、2回目の realloc() は失敗したとする
このとき「関数 concat3() が失敗したときは状態は不変、成功したときだけ状態を変更する」という原則を満たせない
我ながらちょっと例が悪いとは思うが、
realloc() を暢気に使っていると、エラー処理が一手ばったりになってしまう。 >>120
俺はいいと思うぞ。
むしろ無理に「質問者様が神様だ」的にしたがるゆとりは死ねと思うが。
そもそも質問には回答つきまくってるし、質問者側が何らかの反応しないと話は進まないだろ。
流れも読めない癖に流れを主張するゆとりは殺すしかない。 なるほど。まあ確かに使い方や使い所を間違えればハマるものではあるな。
そういや以前 realloc() で渡すポインターがNULLではなくサイズの指定が0だとfree()されるってのでハマったことがあった。w
ANSI準拠のreallocは、mallocとfreeの代わりになる。
>>121
それはプログラムの組み方が悪いだけでrealloc()のせいじゃないだろ >>121
最初から文字列3つ分の領域確保すれば良いんでないの? >>121
reallocではなく、自前でmalloc+memcpy+freeでやればいいだけ。
ただその前に、指摘されているとおり、
3つの「同時に変更される」生ポインタを掴ませるのが問題。
その場合には普通は一つの構造体に入れてそれ経由で使い、
「同時に変更される」という条件が外部に見えないようにする。(隠蔽)
勘違いしている奴も多いが、OOPは文法の話ではない。 reallocをmallocとmemcpyでやろうとするともとのメモリサイズわからずに詰まない?
結果何をどうすればいいんですか?レベルが高すぎて何を言ってるのかさっぱりです
だからreallocはいまいちって話なのでは?
>>132
malloc_usable_size, _msize >>133
reallocに関してはひとまず気にしなくて良いかと >>133
見つかった行の保持ってメモリー上でやりたいの? >>136
別にこだわりがあるわけではないです。
明日やろうと思うので、調べるあたりこれ見とけとかあります? メモリ上に保持しなくても良いなら、検索して見つかった行をそのままファイルに書き出してしまう方が簡単だと思う。
あと、どういう環境で実行するか分からないんだが、もしも正規現が使えるなら、それを利用する方が簡単だと思う。
複数のキーワードで探したいときは一括で指定できるし。
>>137
1. grep/sedでおk
2. AWK/Perl/Ryby/Pythonでもおk
3. つかその用途でC使うとか正気じゃねえ。メモリ上でゴリゴリやるにしても普通はスクリプト言語。
4. それも分かっててC使う覚悟のある奴がここでこんなアホな質問する訳ねえ。>>138 >>139
>用途でC使うとか正気じゃねえ。メモリ上でゴリゴリやるにしても普通はスクリプト言語。
その判断をするのには、一定の C での経験が必要だと思います
python なんかでやったほうがいい仕事をあえて C で書く経験はあったほうがいいでしょう VBでは出来るんですがCの勉強をかねてトライしてます。
いろいろとありがとうございました!明日頑張ってみます!
>>132
メモリーサイズを知る必要はない
そもそも確保されてるサイズと strlen(a) が同じかどうかはわからんし >>142
concat3とかいうQZのボケたろくでもない例のことは忘れろ >>132
メモリサイズは非公開というだけで、内部的には持っている
だからreallocの作者=mallocの作者が詰むことはない
それ言い出したらfreeも解放量わかんなくて詰むだろ >>144
reallocの作者がmallocの作者と違う場合なんだが 違うかなあ?まあ、ソース公開されてれば違う人が書くことは楽だが。
>>147
どの辺がどうできなかったかを書いてみて >>148
俺は、それを空想論と断言してみる
おまえさん恥をかかせてくれることはできるかな? >>150
単純に自分でやってみようと思い一から書き始めたんですけど
CSVファイルのカンマ区切りで、行は日々増える形式で、13列の固定。それぞれ数字だったり文字だったり混合。
ファイルを開いて読み込んで一行ずつ検索文字列と比較して一致したら表示列を指定して表示させ、一致しなかったら次へを繰り返していこうと思って始めたんですけど。
配列に入らずうまいこといきませんでしたね。ネットの参考もいいのが見つからなくて...
前載せたコードを読みといた方が近道ですかね? >>151
もともと標準mallocやfreeを使って自前realloc作るならという話の流れだっただろ >>152
CSVファイルを読み込むプログラムは作った事ありますが
CSVの仕様をどの位受け入れるかで複雑さも変わると思います。
この辺は汎用的に作るか、自分が処理したいCSVの仕様の範囲にするかで違うとは思います。
scanf系の処理はとても癖が強く、
よっぽど仕様に精通していないと填まります
私ならその道を行くのはやめます >>152
grepでおk、マジで
そんなことをCでやる馬鹿はいないから、ろくな参考情報がないのも当たり前。 "と , のエスケープと 1要素の中に改行を含む文字列周辺 RFCみて頭いたくなった
配列とかポインタとか難しいと聞いていたから心配していたけど
とりあえず基礎の解説書レベルなら分かった。やれやれ。
指定したサイズの2次元配列を確保する関数を設計してくれまいか?
>>159
無理じゃね?
char (*dim_alloc(size_t width, size_t height))[width];
最後の[width]がエラーになる[*]にしてもあかん
[]にすると通るには通るが、今度は
char (*a)[3][4] = dim_alloc(3, 4); //型の不一致になる あ、失礼
char (*a)[4][3] = dim_alloc(3, 4);
結果は同じだけど
できた
void dim_alloc(size_t, size_t, char (**b)[*]);
int main(void)
{
size_t width = 3, height = 4;
char (*a)[width];
dim_alloc(width, height, &a);
}
void dim_alloc(size_t width, size_t height, char (**b)[width])
{
*b = (char (*)[width])malloc(width * height);
}
これならおk
ポインタの配列使っちゃえばいいじゃん。free()する時注意が必要だがアクセスがa[y][x]形式なのは同じだし。
二次元配列とポインタの配列だと、使い方が違うでしょう
165デフォルトの名無しさん2018/02/27(火) 12:21:42.40
mallocされたサイズが分からんとか何言ってるの?
gccもVCも確保サイズを返す関数を提供してるだろ
>>164
確保時と解放時が違うが読み書きアクセスする時の表現は同じにできる。 >>159
gcc6 では一筋縄ではいかなくなっているね… >>162
>>159
>char (*a)[width];
これに値をいれないといけないし、そもそも、それも含めて malloc() してほしい、のでは ああ。先頭にポインタを詰め込んで一発で全部free()できるようにしたのか。
>>165
非標準だし、そもそもそんなものを使う必要は滅多にない 173デフォルトの名無しさん2018/02/27(火) 19:27:39.38
>>168,172
上の方でmalloc作者じゃなきゃrealloc作れないっていう主張があったから、普通は処理系で専用関数を提供してるだろって話 >>159
わざわざ関数を設計しなくても、例えば3次元配列なら
int ary[dim_z][dim_y][dim_x];
int (*ptr)[dim_y][dim_x] = malloc(sizeof(int) * dim_z * dim_y * dim_x);
とやれば ary と ptr は同等に扱えないかな。
ptrはfree()する必要があること、sizeofの対象にしたとき同じ値を返さないことは
別関数を作っても同じだし。 175デフォルトの名無しさん2018/02/27(火) 19:54:46.22
>>159は二次元配列を確保とは言っているがインタフェースは特に注文ないんだからxとyと型サイズを掛けて(必要ならアラインメント考慮も入れて)mallocしてvoidポインタを返せばいいよな >>174
別関数を作っても同じとは思わないな
void dim_alloc(size_t, size_t, char (**)[*]);
void dim_free(size_t width, char const volatile (*head)[width])
{
free((void *)head);
}
dim_allocが内部的に割り付けに使っている手段を
dim_freeに隠蔽する意味はあるんだから >>173
> 上の方でmalloc作者じゃなきゃrealloc作れないっていう主張があった
そもそもその主張がおかしいだろ >>177
だから、その主張はおかしいって話の流れだったろ そんなには難しくはないと思う
作る人がグラフィック処理を理解していて
キー入力のリアルタイム処理をこなせればね
>>179
自分で組むためにはいろいろと段取りが必要で結構難しい部類になるかと思います
一時間で組む、とかいうやつも下準備はしてあったと思います PetiteTech にあるテトリス
ブロックパズルの作り方 だと これはどうなの?
高校生ぐらいが無理なく取り組めるゲームプログラムって
無いですかね?もちろん初心者。
パズル系は楽そうに見えるけど、判定部分を作るのがキツいと思う
まずは固定画面でブロック崩し
次は横スクロール画面でスーパーマリオもどきぐらい
描画ライブラリを自作出来なかったら dxlib とかのフリーライブラリが使える
2Dに慣れたらUnityのフリー版で3Dゲーム作ってみるのもいい
ここに来て何でこんなに初心者が沸いているのか分からんが、
スレ分けた方がいいんじゃないか?
というか、上級者用のスレがあったら紹介してくれ。俺がそっち行くから。
>>183
高校生なら学校の勉強しとけ。特に数学。
俺はゲーム畑ではないが、今ですらエンジンは統合されつつあり、
フレームワーク化は今後ますます進む。というか、そうならない理由がない。
そのとき、中途半端にCが出来ても使い物にならない。
ゲームプログラミングは上位のフレームワーク上の部分と
下位のゲームエンジンの部分に分離され、Cが担当するのは後者で、
当たり前のように座標を使いこなし、ゴリゴリにチューニングすることが求められる。
つっても通じないだろうが、多分高校生の考えるゲームプログラミングなら、
C#でunity使うのが今風なんじゃね?そっちやっとけよ。 そもそも枯れた技術のC言語スレで上級者なんているのかな・・・?
>>186
>>159 をサクッと解ける人は上級者かもしれません、私は size(int)=sizeof(int *) を仮定していたために酷くはまりました >>186
むしろお前含めて一通りも使えない馬鹿が沸きまくっていることが問題だ。
それでも初心者は初心者同士で好きにやればいいが、
元々居た連中は逃げるしかない。
大体、>>184も間違いだ。
そもそもプログラミングすら出来ない奴がCから始めることが間違っている。
今は昔みたいにCしかない状況ではない。他に適した言語がいくらでもある。
だから「C初心者」は許容するとして、「プログラミング初心者」はお帰りください、でいい。
というか、それが本人の為だ。
「判定部分」は言語に依らない。
だから「判定部分を作るのがキツい」のなら、まずその程度簡単に出来るまで他言語で鍛えろ、でしかない。
それで、速度的に問題がある場合はそこをCに切り替えていくわけでさ。
(俺は使ったこと無いから推測だが、)普通の当たり判定ならエンジン側で当然持ってるだろ。
落ちゲーもそれなりの歴史はあるし、判定ルーチンがエンジンにあってもおかしくない。
そもそもテトリスの判定(一列埋め)が難しいという時点で論外だし。
お前は>>184が本人の為になるとでも思ってるのか?
高校生なら学校のお勉強しとけ、がよっぽどマシだろ。
そもそも高校生が2chするのが間違っていると思うし。 >>188
そんなに不満ならスレ立てれば良いのでは?
上級者が集まったらどんな話題が出るのか興味あります 上級者かそうで無いかは、どの辺で分けるの?
もしかして年齢?
ここにいる自称上級者の人達は、C++やC#なら標準で使える様な物を何で再発明しているんだろう?
ポインタ返すだけの関数だとメモリオーバーランが検知出来ないから業務では危なくて使えないし、
バッファへのポインタは別ソース内にstaticで隠蔽してintとかのハンドルだけ返して、
引数範囲チェック付きのget,setと、ハンドルでfreeする関数まで作らないと正解とは言えない
とりあえず他の人の反応見て週末にでも俺が立てるよ。
テンプレは>>1踏襲だが、以下に変える予定。
スレタイ:C言語相談室
C言語の話題のみ取り扱います C++の話題はC++スレへ
上級者専用です。
10,000行程度のソースを取り扱ったことがない人は以下スレへどうぞ。
(このスレ)
>>190他
Cなら10k行で切っても人数集まるんじゃないかな?と思っている。
ゆずって5k行くらいにしとくか?
或いはC++も混ぜとくか?C++スレも「上級者専用にしていいんじゃないか」って話も出てたし。
ポシャったけど。
>>191
そもそもそういう思想ではないし、C++やC#がいいと思うのならそれらを使えばいいだけ。
個人的にはC使いは無駄に頑張りすぎていて、
もうちょっと上手く手抜きをすることも覚えるべきだとは思うが、
わざわざCスレで「何回目だよそれ?」をぶちかますお前も頭おかしいと思う。 あ、ごめん。リロードしてなかった。そういうテンプレは入れてないな。
じゃあ俺の作った方は放置でいいよ。新しいのできたら削除依頼しとこう。
>>192
1CU1ソースって仕事を昔してた。
モジュール分割すら認めてないサイトだった
ソースはそれぞれ1万行越えてたな
最大2万行あったと思う
1日に600行書いたことはある
でも自分を上級者だとは思っていない
そんな自信はありません
書くソースは500行程度だな
どんなに詰め込んでも2000行が限界だわ >>193
これ何故コードに展開したんだ?何かの実験か?
それにしても意味があるとは思えないが。
さすがに手打ちとは思えないから、当然自動コード生成として、
その場合は入力は木データなのだから、歩くのが普通だろ。
100行程度で済む内容だと思うが。 >>198
どういう課題かは知らんが、
データとして処理するべき案件をcase文にしてしまうという発想が間違っていると思うけどな。
普通は bool flags[6] でありなしを管理し、10行程度で書ける内容だぞこれは。 >>199
ああ、それは説明が必要でしたね
確かにこの課題内容の「縛り」は理解不能でしたが、当時、それに知恵を絞った者も複数いたようです、宿題スレ、粘着の嵐でもう見る影もなく廃墟になってしまったんですが
課題内容
C言語で、
#include <stdio.h>
int main(void){
char n;
/*
ここを埋める。変数の新たな定義
や,printf,scanf以外の関数の呼び出しは禁止
*/
}
な場合で、
1から6までの数字をキーボードから最小で5回受ける
(同じ文字の入力や範囲外の文字の入力は
「無視しました」と出力)
残り一つの数字がわかる場合はキーボード入力
を待たずに決めてよい
最終的に、入力された順番とは逆順に入力
された文字を出力 >>200
クソ問題はやるだけ無駄だぞ。
大体そういうのを考えた奴は実際はプログラマではないことが多い。
だからどういう事が実際に必要なのか分かってないのさ。
K&Rにしても禿本にしても、演習課題付けてくれてるだろ。あれをやる方が1万倍マシ。
或いはテトリスなりを実際に自分で作った方がいい。
少なくともそこでは「実際に必要なこと」しか要求されないわけでさ。
スタックを1バイトも使ってはいけない状態で、
展開したコードならどれだけ大きくてもいいとか、あり得ないよ。
スタックは128バイトまでな、とかならまだ分かるが。 状態数が有限じゃないってことだけど、解析できないし分類上も有用じゃないので、現実には扱わないよ
>>183
市販品=プロの作品を真似しようったってそんなの無理だ
必要なのはアイディアの発想力、つまり遊びのセンスだ
たとえばキーボードを壁に吊して射的ゲームとかなら
プログラム的には簡単だろ >>183
「ヒット・アンド・ブロウ」や「ハングマン」あたりかな。
乱数ベースの当て物に飽きたらテキストアドベンチャーに移行。
自然言語処理に至る。
…真に受けないでくれよ。 キーボードを壁に吊るしてって、斬新なアイディアだな。
そういや昨日秋葉に行ったらUSB接続で反対側が何にも繋がってないやつで、自分でスイッチ繋げて入力用の何かを自作できるっていうの売ってたな。(確か東映無線にあった)
一応ハードウェア工作を含んで尚且つOS経由でUSBからの入力をしなければならないが、キーボードを壁に吊るすぐらいでは飽き足らない人はやってみたらどうかな。
>>186
グラフィカルなものとかアクション性のあるものとかは敷居が高いから、
まずはオセロや五目並べあたりをCUIで作ってみるのが取っつきやすいかな。 テトリスとぷよはそんなに難しくなかったなぁ。
省メモリで作ると果てしなく大変だけど、富豪的に作れば大したことない。
オセロとかもそうやな。富豪的に作れば難易度は各段に下がる。
>>208
高校生というか中学生レベルかもしれんが、パソコン買ってBASICで最初に作る定番だな。懐かしい。
ヒット・アンド・ブロウ(マスターマインド)って簡単な割に意外と遊べるんだよな。
あとブラックボックスなんかも。 対戦マスターマインドとか簡単で面白いカモな。
伏せられた一つの答えを解きあう感じの。
敵作る経験にもなるし。
それぞれありがとうございます。ヒットアンドブロウって初めて聞きました。
確かに学校の勉強も大事ですね。数学検定準2も終わったので(多分合格)
中3・高1のメンバーですが。2級までの間、AO入試にプログラム使えないかと
思って(将来的にも使えるようにしたい)勉強し始めています。
(立命館のあいちゃれとか参加してみたいとか・・・)まあそんな感じ。
>>216
BASICで・・・30年以上前の話かな・・・ BASICか。。。
始めて作ったのは
敵がいないパックマンに
バック走行のレーシング
マシン語おぼえて任意方向のスクロールができるようになったら
ボスコニアンとかゼビウス
敵キャラはマシン語より難しい
完全にランダムな動きはすぐできるが
自機を狙ってくるやつの思考ルーチンは奥深い
ハングマンはわりと簡単に作れてわりと楽しめるよ
英語の勉強にもなる(かもしれない)
>>220
「バック走行のレーシング」て発想はなかった。
俺は「風船を背負って縦穴を落下する」という設定だった。
…そういや、今のプログラム初心者は「とりあえずスター・トレック」で
ゲーム作り始めないのね。
真面目な話、BASICでINPUT命令を使うのに比べると
Cでユーザーからのキーボード入力を受け取るのは面倒なんだよね。
そのせいで同じネタでもプログラム課題としての難度がいくらか上がる。 conio.hを発見して非標準に絶望するまでが一セット。
俺、発見するのに数年かかったんだぜ。
BASICで3日でできたことがなんでできんのじゃーって悶えたわ。
cursesライブラリの方が対応している端末が多くてほぼ標準なんじゃないかな
非標準ておまえら。。。
// basic_like.h
int inkey(void);
こんなん一発作っときゃ終わりだろうがよ
自分の使ってるコンパイラの枠組みの中だけで実装できればまだいいんだが…
めんどくさいので既存のものを探すことにになる
マスターマインドは
正解にたどり着くまでの
最短最速最適な質問の仕方
を次の一手で出すアルゴリズム考えたな
4列だったら最大7手未満とかそんなやつ
>>224
ウインドウズで開発してるから、VCはconioもってるんだよな。
ただ、布教できなくて悶える。ソース配布できない。
GCCも持ってない環境あるからなぁ。 マスターマインドのAIはダサいのは作ったことある。
正解にはたどりつけるけど、パーミテーションでグルグル回す奴だから回答がキモイ。
そして遅い・・・。
>>230
まあ、非標準だから仕方ない。そういうのは条件コンパイルとか、たくさんあるなら環境ごとに別のソースファイルにしてビルド時に選択とか。
そういうことをちゃんとやってるオープンソースソフトウェアが参考になるかも。 >>234
UTF-8型というものはない。
wchar_tにウニコードかOSの文字コードが入ってることを期待しよう。
まぁ、stdinをgetchで読んで解析とかかな。またはfgetsで全部読むとか。
世知辛いのじゃー。 238デフォルトの名無しさん2018/03/03(土) 19:55:40.33
>>237
一定のchunk sizeでreadして1byteずつ解析やな あ、そうか。
UTF-8って生バイトfreadしないといけないのか。
失念してた。
>>236
削除依頼出して誘導の書き込みしておいた。 おまいらってすごいね
C検定の1級とか余裕なんだろね
いやいや、これでもISO/IEC 9899:2011のつまみ食いをしてるだけですよ
昔のCと違い、今のCは付き合ってらんないところが結構あるんで
10,000行程度のプログラムで何ができるのか想像が出来ん。
244デフォルトの名無しさん2018/03/05(月) 00:51:13.54
10000行程度を書いた経験だろ
全体だと30万行とかだろ
一プロジェクトで1万行はないな。趣味だから。
トータルならそれ以上書いてるけど。
一万行ねえ。しかしあまりに行数が多くなるとするとC言語を使うこと自体が適切ではなかった可能性も出てくるよな。
あるいは何か設計がまずいか、書き方がまずいか。
何れにしてもプログラムが多くなればなるほど人間がバグを作り込んでしまう率が高くなり更に全体の把握が困難になってくる。
最高効率で1万行ってやりたくないなぁ。
ぜったゲシュタルト崩壊起こす。
普段から1万行程度書いてる上級プログラマが
今から模範演技を見せてくれそうな予感
int
MyFunc
(
int param
)
{
return param * param;
}
行数で評価とかいまだにあるのかcobolの習慣持ち込むな
生涯ではたぶん 書いた行数より消した行数の方が多い
>>249
一万行の上級者様は上級者様専用スレに行ったみたいだから、実演はしてくれないだろう voidポインターの足し算は未定義なんだってね。
charのポインターみたいに1バイトずつ増えるからつかえると思ってた。
C言語初心者向けのスレって結局ここでいいんだろうか?
フォルダ内の複数のエクセルシートの決まったシートをtext形式1つにまとめるのって出来ます?
>>255
gccもそうなってて以前それ前提に書いてあるソースを見てビックリしたことがある。
特別扱いしているらしい。 プリプロセッサで
#define foo(n) foo_##__typeof__(n)(n)
double a;
foo(a);
って展開したら
foo_double(a)
になって欲しかったのに
foo___typeof__(n)(n)
になりました
良い方法はないでしょうか?
>>261
型名の解釈は、プリプロセッサのレイヤーでは無理です。 __typeof__ って 演算子っぽいけど
(プリプロセッサ処理の段階では解釈されない:sizeof と同じで
リテラルの整数に展開されているわけではない)
がーん
_Genericも二箇所に分けて書こうとするとredefineって言われて先に定義したほうが消えるし、ジェネリックは結構厳しいんですね……
ありがとうございます
sizeof(void)って未定義?
未定義ならそのポインタの加算幅も未定義だな。
void* p = (((void*)(&i))++);
本当は void * に対しては足すことも引くこともできない。
今ならuintptr_tにキャストして足し算引き算した後でvoid*に戻すのかな。
uintptr_t以前はchar*へのキャストだったかも知れんけど。
しかし実際のところvoid*に対してポインタを進めたり戻したりしたいって、
どういう場面で必要になるんじゃろうか?
char *でいいじゃん
構造がわからないものはバイト列って認識でしょ?
そういやポインタ演算と言うと8086用のCコンパイラはfarとか拡張キーワード作ったりして面倒だったな。TurboCだったか。
ああいうなんとも言えないCPUコンパイラだと特殊な決まりがあったりするから要注意だ。
まあ、二度とあんなの市場に出ないような気はするけどな。
ハーバードアーキテクチャだとdmとかpm修飾なんてのも
farはTurbo Cに限ったことじゃない
8086用である限り必要になる
>>279
でもコード64KBの制限はどうしようもない 64KBしかいらないときに使うのがtiny
tiny使いながら64KBじゃきついとか発想が逆
だったら端っからlarge使えつーの
>>281
それは根本的な間違い
誤解産むからやめれ >>272
charか符号付きかどうかは処理系とかによる
なので決めつけてるのはお前ってオチ char は、符号付き・符号なしの、どちらか分からないから使うな!
エラーに、-1 を使っていたら、0〜255 しか表現できない事もある
例外を範囲外の値で判定する様なインターフェースが悪い。
はっきり戻り値は動作結果、値は出力用の引数に入れる。
みたいな設計にすべき。
ちな、C#みたいに戻り値を構造体にするって手もあるぞ。
素人が、char型の-1 を、エラー値に使っていると、
OS・コンパイラが変わって、その環境では、char型が0〜255 になってる
char型は、符号付き・符号なしの、どちらか分からない
>>288
言語内の話と環境(シェルやOS)の話を混同してはならない >>288
charの使い方が間違っていることが問題なのであって、charを使うこと自体が悪いのではない。 はいー。
1バイト整数を使いたかったら、stdintを使いましょう。
int8_tは内部がcharかもしれないけど便宜上charではありません。
ハイ、復唱。int8_tはcharではありません。
ちなみにC++でバイト表現専用のstd::byteが入りました。すごく使いにくいけど。
>>294
Windows用のコンパイラの話?
知らないけど、多分 size の s じゃない? 昔はpc-98DOS用に作ったソフトがハード依存コードが無ければ
DOS/V機やTOWNSでも動くって聞いて驚いた。
N5200 で LSI C-86 試食版を使ってた……ような気がする。昔のことだから記憶が曖昧だ。
secureじゃねーだろ。
暗号化だってされてねーんだからw
safetyくらいな感じじゃね?
DOSのシステムコール(なんて言うんだっけ?DOSコール?忘れた)だけを呼び出しているプログラムならハードウェアが違っても動く。
しかしMS-DOSはCUIしかサボートしてないのでグラフィックスは使えない。
当時のプログラムはみんな勝手にOS無視してグラフィックスのVRAMに直接アクセスして絵を出していた。
すると当然他の機種に持っていくと意図した通りに動かない。
INT 21H なら ファンクションコールだったかの
#define a(b) c##b##d
というマクロでcdを出力したいのですが
a()を呼び出すとエラーになります
解決策ありますでしょうか?
>>314 俺のところはエラー出ないみたい。環境によるのかな。
コンパイラのバージョンを示せば詳しい人が現れるかも。 コンパイラーのエラーが出ないという意見をきいて
試してみたら別のところ―がエラーになっていたということでした。
そして自分が悪質なコンパイラーに騙されていたことに気づきました。
Cのエラーはエラーの発生個所を教えてくれるけど原因個所は教えてくれない
おそらく警告とエラーを混同していると思われ
> warning C4003: マクロ 'a' に指定された実引数の数が少なすぎます。
関数型マクロの使用時、カッコの内側が空の場合に、
「引数が指定されていない」と解釈して警告を出すか、
「1個の引数(内容はヌルストリング)が指定されている」と解釈するか、
そういう問題みたいね。
>>292
>int8_tは内部がcharかもしれないけど便宜上charではありません。
普通はsigned charだな。当たり前。「charかもしれない」なんてこともありえない。 そういう一般仕様から外れるコンパイラの使用を強制させられたことあるの?
cout << typeid(__int8).name(); //char
符号なし64ビット整数を64ビット右シフトすると
0にならないでそのままの時や変な別の値になるときがあるんですけど
コンパイラーのバグですか?
>>329
もしかしてですが、
悪質なコンパイラに騙されているのでは? >>329
a >> b で、bの値がaの型のビット数「以上」のときは未定義動作、
に該当するから、コンパイラのバグではない。…と思う。
本当は規格の引用をすべきなんだが、どなたか頼む。 コンパイラーは
gcc version 7.3.0 (Rev1, Built by MSYS2 project)
で試しました。
悪質なコンパイラーに騙されているのかもしれませんね。
ファイル1
#include<stdio.h>
#include<stdint.h>
uint64_t f(uint8_t a,uint64_t b){
printf("%llx\n", b>>(64-a));
return b>>64-a;}
void e(uint8_t a){ f(0,0x8318318318318318);}
void g(uint8_t a){ f(a,0x8318318318318318);}
ファイル2
#include<stdint.h>
uint64_t f(uint8_t a,uint64_t b);
void g(uint8_t a);
void e(uint8_t a);
int main(void) {
g(0);
e(0);
return 0;
}
この二つのファイルをコンパイルして実行してみてください。
よろしくお願いします。 その昔、CPUのバグで16bitレジスタを32bitシフトすると0にならないとかいうのなかったっけ
これからは64ビットのシフト使ってるコードは全てバグの温床になるな。
C11の6.5.7の3より。
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
>>337 フォローありがとう。この部分ですわ。
6.5.7 Bitwise shift operators ビットシフト演算子 の項。
もしも右オペランドの値が負、または汎整数拡張後の左オペランドの(ビット)幅より
大きいか等しい場合、振る舞いは未定義である。
と言った感じかな。
promoted left operand の部分が「汎整数拡張後の左オペランド」で
合ってるのか自信ないけど。 64bit 符号なしを、64bit シフトするって、そもそも無意味だろ
元のビットが残っていない。
全部のビットが変わっている!
意味があるのは、63bit まで
340デフォルトの名無しさん2018/03/09(金) 22:22:53.87
>>339
0になってくれれば余計な分岐やら演算やらを省けるかもしれないだろ 1010 XOR
1010
----
0000
n は任意のビットで、n XOR n で、全ビット0にできる
343デフォルトの名無しさん2018/03/09(金) 23:25:22.45
>>342
そんなん全ビット読まなきゃいけないじゃん n and 030 とかで任意ビットのonはわからないか?
定数リテラルにullって使ってなくてもだいじょうぶなんだっけ?
>>343
xor は少サイクルなのが利点ですね。 今じゃ乗除演算さえワンサイクルの時代に何アホな話してんだ?
アセンブラについてはどうしても自分でアセンブリ言語で書かねばならない事態に陥らない限り書くことはないだろうなあ。
>>354
そうそう、printf デバッグでは力不足でもう否が応でも gdb に行くのを逃げ回っているのと同じです 割り込みん中でprintf使って暴走してデバッグが出来なかった思い出。
俺はシグナルハンドラの中でログ出力しようとして FILE * 経由で fprintf() 等で出力したら
そのライブラリの中でデッドロックしてハマった。 kill -ABRT で core dump させて gdb
で core ファイルと共に読ませてようやっと停止箇所がわかった。
gdbマスターしてからprintデバッグバカにしてたけど
printデバッグ自動化してからprintデバッグ信者になった
無論レアケースデバッグはgdb使うけどね
printf() をデバッグで使う時はバッファリングを考慮していないとハマる事がある。
それと stdout と stderr と両方に出る可能性がある場合にその順序が食い違う可能性もある。
シグナルハンドラ内やマルチスレッドプログラムで使ってうまく行かない事もある。
その辺を全て考慮するならいいだろうが、しかし、それなら初めからログファイルに出力される
ように作った方が良いような気もする。
printデバッグなら専用モジュール作るべきだな
俺は時刻、関数名、コンテキストIDを付けて
標準出力かファイルにはかせてる
>>361
setvbuf忘れなければ済む話だよパパ >>363
そだねー
>>364
本当にそれだけで大丈夫かね?
この頃のライブラリは多分マルチスレッドでもちゃんと動くように内部でロック掛けている部分があると
思うんだけどね、例えばシグナルハンドラの中でそのロックを掛けている最中にまたシグナルが来て
同じシグナルハンドラに入ると同じロックを掛けようとしてデッドロックするなんてことが起こり得ると
思うんだが。(まあその程度のことでデッドロックしてしまうこと自体がバグかも知れんが。それ以前に
シグナルハンドラの中でprintf()は使うなって話でもあるか…)。 >>365
ロケールがCならprintfだってスレッドセーフだしぎりぎりシグナルセーフだよパパ 世の中には完全なCライブラリを実装していないタイニーなマシン用のサブセットだってあるんだよ坊や。
それはCじゃないから、このスレで話し合っても無駄では。
30年以上前だったかな、あるメーカーのプリンタファーム開発用Cコンパイラが配列要素上限が255だった
当時アスキーネットでこれを聞いたvoid氏が呆れていたようだ。
インストラクションに8ビットまでの即値を組み込めるなら、その制限によって(そのような最適化が必要なプロセッサにとって)強烈な最適化をかけられるから、アリやナシやと問われればアリのような感がある。
Cライクって言っときゃいいのにCと名乗ってしまうから
イチャモンつけたいヤツの標的になる
本場ドイツ直輸入ポークソーセージを買ったら魚肉ソーセージだったような感じですね。
つまり詐欺です。
>>369
それ言ったらバッファリングの話題もCの話にならないだろぉオヤジィ 何が正当な教義かについて議論したければ、上級者スレでやってね
こういう掲示板で宗教対決を規制したら過疎化するんじゃないだろか。
377デフォルトの名無しさん2018/03/11(日) 18:26:39.19
>>366
マルチスレッド版のライブラリーがあるかと
行出力中にスレッドが切り替わらない >>374
なお初代K&Rにはライブラリーの仕様は含まれない。
WhiteSmithとかはprintfが実装されてない 5Vシングルエンドがそのままコネクタに出てるアレか
アレを基板に直付けするアフォが多くて頭クラクラした
for(i=0;i<10;i++)
scanf("%d",&num[i])
で入力した変数がiに入ってしまうことがあるのですがなぜですか?
アルゴリズムによってはdo whileの方が素直なときがある。まれだが。マクロを本当の関数っぽく使うのにdo while (0)使うハックがある。まれだが。
コンパイラによってはdo whileの方が速いコード出す。まれだが。
>>370
プリンタっつーてもピンキリだからなぁ
レシートプリンタとかならその程度で充分かもしれん >>385
んなこたーない
whileのほうが使用頻度は高いけど
本質的に後判定なロジックはそんなに珍しくもない do〜whileは、必ず一回は処理してくれるから便利。
繰り返し対象処理が実行される条件がブレるから気をつけないといけないけどね
do{continue;}while(false); で無限ループになるのウケる。
391 error: undeclared symbol 'false'
こんな書き方たまにする
do{
・・・
条件
break;
・・・
条件
break;
・・・
条件
continue;
・・・
条件
break;
・・・
条件
continue;
・・・
}while(0);
>>387
一応汎用のレーザープリンターなんだ
30年って一寸行き過ぎだな
95が出てきた頃だから、20年前か >>394
GOTOを怖がるな。
俺は反GOTO教は抜けた。
まぁ乱用しようとも思わんけど。
>>392
文脈で察してくれ。
boolはいったことだし。 B 判定 A B 判定 A B … みたいに
do { } while () のブロックの途中に飛び込んで開始するようなのが悩ましい
goto ENTER;
do {
A();
ENTER:
B();
} while(条件);
出口が複数は可だけどエントリーポイントが変なとこにあるのは読みにくいからやめたほうがいい。
この例の場合はB Aの無限ループにして、Bのあとの条件で脱出するのが定石。
for(;;) {
B();
if (条件) break;
A();
};
こんな感じですか。
やっぱり頭から入っていくほうが読みやすいし…
処理内容がそうならそういうことなんだろうが、
見ていて気持ちが悪くなるロジックだな、すまん
エントリーポイントが変なとこって、mainだって1行目にはまずならないしな
実装されることなく廃止になったキーワードにentryつーのがあって
そいつがおそらくは1行目に
entry main;
とか持ってこれるようにするつもりだったのかもな
>>397
昔の BASIC を思い起こさせる goto の使い方だなw gotoは禁止はしないが、異常系の終了処理にジャンプするパターンだけ許容だな。
コンストラクター/デストラクターのような機構があれば
異常時の後始末は割と楽に書けるっすね
>>408
volatileをつけ忘れて最適化で暴走するなんてよくあること。 >>395
1995年頃でLBPだと16bitから32bit CPUに移行する頃だから配列サイズが最大255なんて言うのはさすがに見たことないわ
ちなみにうちはSH-2+独自モニタからR3000+VxWorksへの移行期だった
コンパイラもチップベンダーかOSベンダーのものを使ってた gotoを後始末以外の使い方して変な所に飛ばしたりするから禁止って言われるんだよな。
昔のBASICにはON ERROR GOTOとかON ERROR GOSUBつーのがあって
異常系から復帰できたんだよな、それがCやC++にはない
RESUME NEXTに相当する処理はsetjmp.hにはない
gfortranで言うところのfcheck=allを設定した時のように配列の範囲外アクセスを検知したいのですが、いい方法はありますか?
Linuxなので代用を探していたらvalgrindに辿り着きました
ありがとうございます
初期化
タイトル
...
GOTO 本編
GAME OVER
...
GOTO タイトル
ゲーム本編
...
GOTO GAME OVER
>>412
まあ、ないけど、エラーになったら自分でif文使って分岐すれば良いだけでは?
C言語は単に言語レベルでのそういう便利機能が少ないってだけで実現する方法は内部的な動作まで考えたら結局は同じにしかならんと思うよ、 C言語はマクロアセンブラから派生した感じなんで、言語体系はお世話にも良いとは言えないんだよな。
当時はマシン語で演算結果フラグで条件ジャンプや条件コールしてた煩わしさから開放されただけでも有り難かったんだ。
そんなチープな言語にオブジェクト指向だの例外処理だのとか求めて迷走したのがC++
ええい、いっそ作り直してしまえって出したのがJavaやC#
だからC言語使う時点で諦めれ。
>>421
そのif文でゴチャゴチャしだしたら「例外処理」を名乗れない 基本的にウオーターフォールを守るのが大事やな。
そのうえでどこに飛びたいかって感じ。
425デフォルトの名無しさん2018/03/13(火) 12:12:14.52
フォールウオーバー機構を言語レベルで用意すべき
>>423
名乗らんでいいのでは?
Cが不便なら他の言語使えばいいじゃない。 >>428
ああ、議論できないのね
いいよ話さなくて ここで幾ら議論してもC言語は変わらない。
Cから派生した言語を新たに作るというのであれば議論することには意味があるだろうが、そうでないならそれはただの愚痴だ。
おまえさあCの例外処理が言語のビルトインとか思っているわけ?
Cは変わらないとか言っちゃってるけど、
その現状のCがわかってないのに変わったかどうか気付けるのか?
一応errnoだったかっていう、失敗理由を示す変数がある事はある。忘れられてるけど。
C言語で唯一トラブルシューティングに使える変数。
>>436
> その現状のCがわかってないのに
お前だけだろ w
>>437
ライブラリレベルの話を入れるかどうかは悩ましいな
普通の言語なら入れなくてもいいと思うがC言語にはsetjmp/longjmpなんて言うとんでもないものもあるからなぁ errnoだってwww あれが例外処理なのか
setjmpがどうとんでもないのか具体的には言えないんだろうな
だから聞かない
>>439
大域ジャンプするとエラー処理したところが戻ったりして変数グチャグチャになることがあるからな。
まぁ、C++の例外も大域ジャンプだし。個人的には使わないな。
古き良き-1やら_boolであきらめる方が精神的には良い。
んで、趣味位のケースなら正常系だけ書いておけば大体問題ない。
エラー系は大体ロジックエラーだからデバッグで落とす。 >>439
> setjmpがどうとんでもないのか具体的には言えないんだろうな
他の言語でライブラリレベルで実装してる例はないから
まともな頭があれば理解できるはず あれジャンプじゃなくて、スタックロールバックだからな。どっちかっていうとリセットの類。
他の言語でこれは実装できない。というかやりたくはないだろう。
大域ジャンプ+動的メモリアローケート。あぁおそろしい。
なので、大域ジャンプはやめましょう。
>>440
> 大域ジャンプするとエラー処理したところが戻ったりして変数グチャグチャになることがあるからな。
それはお前の能力が足りないだけの話だろ w
> まぁ、C++の例外も大域ジャンプだし。
C++はデストラクタとかの処理も要るからライブラリレベルでは実現できない
そう言う処理を全てプログラマに押し付けられるC言語だからできるってことでもある >>445
あーすげー。この人、他人がいじった変数全部把握してるんだな。すげー。
メモリ確保したのなかったことになっても正常系に戻せるんだな。
超人か!! C++のクラス機構をライブラリで実装するときは、構文糖入れたりとか、イベントモデル入れたりとか。
エネルギーばかりかかって収穫がない。
>>436
Cには言語レベルでの例外処理はないのでは?何のことを指してそう言っているのか? Cにだって例外処理はある。
でもそれって、CPUの例外割り込みの事だけどね。
あー結局言語仕様じゃ無いじゃんw
割り込みっていうならシグナルがあるがしかしOSの問題だよな?
てか標準じゃないか。それにシグナルのために特別な言語仕様が作られてもいない。
>>441
現状のCの話じゃなかったのか?
なんで他の言語が出てくるんだ
俺はてっきりsetjmpの仕様がとんでもないと言っているのかと思ったが
実装方法がとんでもないと言っているのか?
あれか動作保証のないマイクロ診断命令でも使っていると言いたいの? >>448
言語を定義する規格票が定義しているライブラリのことだよ
まさか知らんのか? 何やら雰囲気が悪くなってるように感じるけど、カレンダー絡みかな。
やたら突っかかってくるやつを構ってやっているだけだが
>>454
知らんなあ。Cの例外処理ってなんなの? >>457
そうか、知らんのか
じゃあ話にならんな 人の話の腰を折ることに専念せざるを得ない防戦一方なつまらんやつ
>>460
おまえ、そこで3回まわってワンといえ
書いてやるかも知んねーからw >>446
むしろそう言うのを把握せずにどうやってプログラム組んでるんだよ?
動けばラッキーってか? w >>453
> 現状のCの話じゃなかったのか?
> なんで他の言語が出てくるんだ
どんだけ理解力がないんだよ...
> 俺はてっきりsetjmpの仕様がとんでもないと言っているのかと思ったが
> 実装方法がとんでもないと言っているのか?
だから他の言語ではライブラリでは実装しづらい機能って話な
> あれか動作保証のないマイクロ診断命令でも使っていると言いたいの?
背伸びしてマイクロ診断命令とか言い出すとか w 自作関数からのlongjmp()利用するなら似たようなものは作れるが、それは言語レベルで例外処理をサポートしている状態とは違う。
あ、関係ないけどホーキング博士が死んだという速報が入った。
>>463
大域ジャンプなんぞつかわんので。GOTOくらいは使うけど。
戻った変数と戻ってない変数把握するの無駄すぎる。
んで、どうやってって関数かくときにifで入力要件位書くだろ。無駄な引数減らしたりとか。 HDLCの状態遷移を大域jump無しで書くのは大変だろうなぁ
>>469
gotoじゃなくGOTOね
Cに限らない一般論ということだな
しかしlongjmpやthrowなんか大域ジャンプだろ
おまえさんはそう思わないのか? >>452
それな
Cのソース書きながらアセンブラのソースが思い浮かぶ >>473
早く書けよ。こっちゃあ昼からずっと回ってワンワン言いっぱなしなんだからよ。もう千回ぐらい回ったぞ。 >>476
よかったな
ほら、もう1000回
# アホ 情報持ってるふりして出し惜しみするのがマウンティングの基本
煽れば出ると本気で思っているならやってみな
この程度の話、マジこの程度にも付いて来れないアホの泣き声は物笑いの種だぜ
>>469
無駄じゃねーよ、把握しろ
把握しやすく設計するのも能力のうち >>480
持ってるふりすらできてないだが...
どうみてもいっぱいいっぱいやん w ま、どうでもいいから>>436で書いたC言語の例外処理についてどういうものなのか書けよ。 >>485
それよりあと1000回だぞ
急がないと日付が変わっちまうぞw わかったわかった。もう書かなくていいよ。かわいそうなやつだな。合掌。
491デフォルトの名無しさん2018/03/15(木) 07:11:47.68
>>490
できますん
Excelがインストールされている環境で動かす前提であれば
COMコンポーネント (Microsoft Excel Object Library) を使えばいいが
C++じゃないとダメかも
自前でExcelフォーマットを解析して変換することも
膨大な工数を費やせば理論的にはできるだろうが
現実的には選択肢に入らないな
xlsx限定ならまだ楽かも知れんが
Excelを扱う部分は他の言語で開発してCからはそれを呼び出すのが普通かな >>490
できるけど結構面倒だよ
ところでなんでC縛りなの?
なんかの苦行とか? Cにあっていると思う
バイナリを呼んでキャストして
キャスト後も分岐ルートが色々あって
構造体はほとんど可変長
細かいものを組み上げるのは、たぶん Cが最適
FIFO(名前付きパイプ)で、大量データを分割して送受信したいです。
送信側
---------------------------
buff=malloc(datalen);
len=512;
pos=0;
do{
w=write(fifo,buff+pos,len);
pos+=w
datalen-=w
len=datalen < 512 ? datalen : 512
}while(0<datalen)
---------------------
こんなんでok?
・最初に飛び込んでくる段階で datalen が 分割サイズ(512) より小さい時の考慮
(ループ中と同じ記述で良いのでは?)
・書けなかった時(w=0 だったとき) の脱出をケアする
ぐらいでしょうか
499デフォルトの名無しさん2018/03/15(木) 12:00:46.26
>>494
実用的にするなら非同期送受信でいろいろケアしたほうがいいけど
学習用とか数人で使うテストツールとかならいいんじゃね? >>496
そうそう。しかしその辺はOSや接続先によって違うかも。 >>494
これの受信側read()のコードを求むm(__)m プロトコルなんか無しに来たものを読みきるだけの話なら
allocsz = blocksz = 512
buff = malloc(allocsz);
use = 0;
for (;;) {
w = read(FIFO, buff+use, allocsz-use);
if (w == 0) { /* もう来ない */
break;
} else if (w > 0) {
use += w:
if (use >= allocsz) {
// 器が尽きた
allocsz += blocksz;
buff = realloc(buff, allocsz); // 手抜きで realloc
}
} else { /* エラーケアしてね */ }
}
buff に use バイトだけ収まってる
>buff = realloc(buff, allocsz)
リークするからやめなよ。
>>505
ん?realloc() はリークするのか? >>509
確認した
buff = realloc(buff, allocsz) という書き方は、たしかに realloc() に失敗すると buff が null で上書きされてしまうのでまずいね 前、ANSI準拠のreallocは、mallocとfreeの代わりになるって話をしたよな。
だから、最初のmallocは、NULLに対するreallocで置き換えできるんだよ。
それから、この場合はintよりもsize_tを使った方がいい。
素朴な疑問なんですが、Cでメンバ関数を関数ポインタで定義して、そのメンバ関数から引数なしにメンバ変数を参照することってできませんか?
>>516
C++でいうところのメンバ関数を構造体の関数ポインタのメンバで実装したいという意味だろ。読解しろ。
>>515
むり。C++で見かけ上引数がなくても内部で引数で渡してる。 >>515
http://2chb.net/r/tech/1434079972/39
メンバ関数 h() を返す メンバ関数 g() を定義
メンバ関数へのポインタ f を定義
メンバ関数へのポインタ f にメンバ関数 g() の返り値を代入
ここでメンバ関数へのポインタ f にはメンバ関数 h() が格納されている
->* 演算子を使用してメンバ関数へのポインタ f が指すメンバ関数 h() を実行、 h() ではメンバ変数 C::a を出力する ポインタ構造体変数をポインタ変数で扱いたい時って
&p(ポインタ変数構造体変数)-> member(メンバ名)
みたいにわざわざ一回通常変数に直してからアドレスになおさないかんの?
(&p)->memberなんてまずやらん
p.memberで同じことができる
>>521
それやったらコンパイラにそんな構造体変数ないぞって言われた >>522
質問するときは変数の宣言も使う文脈も省略せずに書け >>522
&p->membar
(&p)->membar 型教えないと何やっても無理だろ。
あと。下手に型変換させると、奇数バイトからワード処理とかさせてしまい、石によっては例外処理が走るか暴走するよな。
今なら、LLVMがあるからコード生成はそちらに任せるという
選択肢があるね。
>>526
コンパイルというくらいだから、最後に機械語に落とし込むのにアセンブラの知識は必要になるのではないか? C++ to C コンパイラとか 生成物が機械語で無いのもあるんじゃね?
(昔そういうの欲しかった)
>>517
Cには無理なんですね
ありがとうございます >>530
>>515 でメンバ関数という言葉を使うのだから C++ を仮定している、というのならば C++ では >>518 で可能
C で可能かどうかを問題にしているのであれば、>>515 のメンバ関数という言葉が自己矛盾 C言語の範囲では 構造体のメンバ中に関数のポインタをもつまで
C++言語のメンバ関数の機構(暗に this ポインタが渡ってくる) のを
C言語でやりたけりゃ自前で引数に渡すしかない&その関数はポインタを引数で受けなきゃいけない
>>529
C++の初期のコンパイラはそういうやつだった。つまり、Cへのコンバータだった。 ああ、各ファイルの先頭に構造体の領域宣言とか関数にいちいち構造体のポインタが追加されるんだよな。
そういや昔々のX68000のBASICにもCへのコンバータがあったな。
俺は、6502アセンブラコードをCに変えるコンバータ作ったけどな。
アセンブリをprintfにパースするのって大変なのかな。
>>531
ではどういう言葉なら齟齬なく伝わりましたか? >>538
「関数へのポインタ」では?
それが構造体のメンバとしてあるわけだし。 >>538
コード断片で示すのもよい、誰かがコードを補完してくれるだろう Cスレで「メンバ関数」だぜ?
それをアスペとか、どんだけボキャ貧なんだよ
>>539
> Cでメンバ関数を関数ポインタで定義して
一応そのつもりで書いたんだけどなあ
アスペ基準に合わせようとした俺が悪かったのか >>544
・関数ポインタとは別に「メンバ関数」というテクニカルタームが C++ にあった
・C/C++ の区別がついていない人の質問も、ここではよくみかける
という背景があって小さな誤解が発生したまでのこと、気にするでない、苦しゅうないぞ >>526
どうやってコード生成部分を作るつもりなんだよ... 548デフォルトの名無しさん2018/03/16(金) 22:33:58.96
Cコンパイラがマシン語を出力しなきゃいけないって誰が決めたの?🙄
誰も決めてないしマシン語じゃなくてアセンブラのソース出すコンパイラはいくらでもあるし
552デフォルトの名無しさん2018/03/17(土) 00:28:10.69
シェルスクリプトとまでは言わないからPerlスクリプトを出力して欲しい
C++の非仮想関数 == Cの普通の関数
C++の仮想関数 == structの項(vtbl)の項
>>553
上の方の関数。普通の関数pointerで保持出来るの? C++のextern "C"関数 == Cの関数
Cに普通じゃない関数ってあるんだっけ
557デフォルトの名無しさん2018/03/17(土) 07:51:22.83
>>555
そんなの当たり前じゃん
まさかできないと思った? >>557
先生、非仮想なメンバー関数をcの構文では保持出来ません。
例をご教示願います 559デフォルトの名無しさん2018/03/17(土) 09:00:39.42
>>558
「上の方の関数」すなわち「Cの普通の関数」を
「普通の関数pointerで保持出来るの?」
→Cの普通の関数は、普通の関数ポインタで保持できます
質問文に忠実に答えただけだが、何か問題でも? Cにゃメンバーって言語レベルの概念は無いから、そういうのはコーディング時に人様がメンバーのつもりになる書き方を明示的にやらないとならないんだよな。
namespace のことを脇においとけば
非仮想関数って FILE 構造体と その関数だべ
LLVMはまずパースレイヤーが中間言語出力して中間言語を解釈するレイヤーが各種コードに吐き分けるということができる。
3段階のコード最適化ができるはずだったが、ちょっと迷走してる。
>>557
struct A
{
void func() {} //C++の非仮想関数
};
void (*ptr)(); //普通の関数pointer
ptr = &A::func; //まさかできると思った? ちょっと間違えました。
上の投稿は無視してください