C言語なら俺に聞け 153
■ このスレッドは過去ログ倉庫に格納されています
仮想アセンブラは、元々、日本の情報処理資格試験用に、CASL2 が作られた。
個別のCPU 命令では、試験にふさわしくないから、抽象化した命令が必要だった
でも、世界的には流行らなかった
それで、学生が作った、LLVM に、Apple が飛びついた 実像を見てない試験で社会から乖離してるな
バkの集団なんだろうか?
それともz80の問題だしたらライセンス料でも払わないといけないのか?
カネに掛けてはとかくケチな貧乏人が思い付きそうな小手先だ
至るところで独自規格で無意味の羅列、全く学習にならず、受けるだけムダな試験が練り上げられる 試験用のアセンブラは、仕様を公開せずに
試験問題の中で初見にすればいい
それで対応力を試すようにすれば
いくらか意味のある試験になる 以前に実施されていたマイコン応用システム開発技術者試験のアセンブラ問題は8080, Z80, 6800からの選択だった
現在の情報処理試験エンベデッドシステムの前身となった資格試験 実際に使えないものを教えられてるのは英語と同じだな
CASLやっても機械語の練習にならない
「教育用」にまで形骸化すると使い物にならない、現実と実用から乖離する、ファンタジーになる、
これが「教育用」の弊害だ
PASCAL不人気の原因もここら辺にあるんじゃねえか?
IT界隈は教育用と実用の間で揺れてる >>2 先生 700行の数式パーサーまたHPに載せて下さい! コンパイルもリンクも正常に動いているようだぞ
生まれたのがバグじゃなくて良かったな ha ha ha http://program-lecture.info/c_structure5.html
ここのサイトを見ながら学習しているのですがこのshowStatus関数では何故int配列を
int型の仮引数で受け取れてるのでしょうか?配列は配列かポインタでしか受け取れないと思ってたんですが
その認識は間違ってますか
よろしくお願い致します。 >>13
showStatus()はint型でもint型配列でもなくcharacter型を受け取ってるようだが? showStasus() の引数は struct person 型の実体を受けてる
main では
struct person 型の配列を用意 party[]
配列の各要素 party[0], party[1] のぞれぞれについて showStatus() を呼んでいる
本質的には
void foo(int arg);
int main() {
int array[2];
foo(array[0]);
foo(array[1]);
return 0;
}
これと同じ >>15
理解出来ました。ありがとうございます( ;∀;) >>8
あのコードは今となっては時代遅れだ。意味がない。 下のコードの部分を実行すると、最後の行だけ2回表示されます。
理由はなぜでしょうか?また、最後も1回にするにはどう変更したら良いでしょうか?
よろしくお願いします。
http://codepad.org/WCL1vHLd >>20
if ( !fgets(buf, sizeof(buf), fp) ) break; >>21
サンクス!
While 行と fgets 行の間にその行を入れたら1回になりました。
修正はこれで良いのでしょうか? >>22 の修正だと最後の行以外にもだいぶ表示されなくなってました。
どうするのが正解なのでしょうか? 良いのか?って聞かれると
色々言いたくなる奴が大勢出てきそう >>23
//while ( !feof(fp) ) {
while (fgets(buf, sizeof(buf), fp)!=NULL){
//fgets(buf, sizeof(buf), fp);
こんなんでどうか >>25 うまくいきました! Thanks!
やっぱり俺に訊けスレですね。ここの人達はすごい。
if ( (fp = popen(cmdline,"r")) == NULL ) {
perror ("can not exec commad");
}
while (fgets(buf, sizeof(buf), fp)!=NULL){
printf("%s", buf);
}
pclose(fp);
最終的にこうなりなした。助かりました。 Ruby では、Windows の、powershell, clip コマンドも呼べる。
UTF-8, CP932 の文字コード変換もできる
クリップボード内の複数行文字列の、各行の先頭・末尾から、
連続する空白類を除去して、クリップボードに入れる
str = `powershell Get-Clipboard`
str.encode! Encoding::UTF_8, Encoding::CP932 # UTF_8 へ変換
ary = str.each_line.map( &:strip ) # 連続する空白類を除去する
IO.popen( 'clip', 'w:cp932' ) do | clip | # CP932 へ戻す
clip.print( ary.join "\n" )
end defineマクロで以下をやりたいです。
struct my{
int d0 =0;
int d1 =0;
int d2 =0;
int d3 =0;
int d4 =0;
}:
struct my val;
val[0:2] = (1, 1, 1);
と入力した時にvalのdata0〜data2に1が入るようなマクロはどう書けばいいですか? __VA_ARGS__ つこて2段呼び出しだな
qiita.com/saltheads/items/e1b0ab54d3d6029c9593 >>29
ありがとうございます。
リンクを参考に、可変引数にするマクロまでは出来ました。(作った関数が間違えていたらすみません。)
struct my def2(struct my val, int s, int e, int d1, int d2){
int *p = val.d0;
*(p+s) = d1:
*(p+e) = d2;
return val;
}
/*def3省略*/
#define GET_MACRO(_1,_2,_3,NAME,...) NAME
#define DEF(val,s,e,...) GET_MACRO(__VA_ARGS__, def3, def2)(val,s,e,__VA_ARGS__)
ここから、表記を変える方法が分かりません。
下のようなことをしたいのですが、このように書くとコンパイルエラーになりました。
どう書けばいいでしょうか。
#define VAL[A:B]=(...) DEF(VAL,A,B,__VA_ARGS__) マクロ使わずにこれで十分だろ。
typedef struct my;
val = (my){1,1,1};
val = (my){1,1,1,1};
以下のようにはできるけど、
マクロの多用は誰もソースを読みたくなくなるから避けたほうがいいよ
#define SET(v,...) v=(struct my){__VA_ARGS__}
SET(val, 1, 1, 1) >>31
すいません、説明不足でした。
どうしてマクロかと言いますと、3つのデータを入れたい場所が0〜2だけではなく5〜7や2〜4の場合もあるからです。 #define SET(x,s,e,...) memcpy(((int*)&val)+s,&(int[]){__VA_ARGS__},sizeof(int)*(e-s))
SET(val, 1, 3, 1, 1)
SET(val, 1, 4, 1, 1, 1)
部下がこんなコード書いてきたら突っ返すわ ID:Y/GLm+KZ0 が上司だったらと想定してみよう。 うーん、どうにかして上のように[]を使って書き換えることは出来ないのですかね。
ちなみに下のようにして全パターン定義しようとしたらエラーでした。何故でしょうか。
#define val[0:2]=(...) DEF(val,0,2,__VA_ARGS__) >>37
なぜって、#defineを使用するための構文を完全に無視してるからだよ。こちらが思ったことを都合良く解釈してくれるわけでなく、構文通りの単純な置換をしてくれるだけだよ。
一度ちゃんと調べておいた方がいい。 >>39
なるほどです。
では、[]や:を利用して独自の構文を定義するのはC言語において不可能、ということですか? >>40
不可能。やるなら自前でプリプロセサでも書けばいいが、そんなことするくらいなら、ソース上に書くのではなく独自のデータファイルとそれを読み込んでデータを初期化するような処理でも作れば? >>41
ありがとうございます。
最終的な目標は、Cを他言語ライクな記述でコーディングすることなので、プリプロセッサについて調べてみます。 新言語作った方が良さそうな。
初期のC++みたいにC言語へのコンバータとして作っちゃえば楽だと思う。Cと同じで良い部分はほとんど素通しで行けるし。 あの変態的にC言語には見えないObjective CでさえほとんどプリプロセッサでCに変換してからコンパイルしてたと聞くので、やろうと思えばできるんだろうね。 独自言語を開発したときなんかはとりあえずCに変換するというのはわりとある話。
コード生成とか最適化とか考えずに済むから。
昔、独自じゃないけど、とある言語からCへのコンバータ作ったよ。
楽しかった。 コンパイル前にソースを別のソフトで変換、置き換えさせて・・・ #define ARR_NAME(n) arr##n
int arr0 [] = {0,0,0};
int arr1 [] = {1,1,1};
int* select_arr(int i){
return ARR_NAME(i);
}
これはどうしてコンパイルエラーになりますか?
ちなみにreturn ARR_NAME(0)だと正しく動きます。 タイミングの問題だ
#defineはコンパイル前に解釈されるが
関数仮引数の値は実行時に渡される
実行時とはコンパイル〜リンクまで全て終わった後の話だ
だから関数仮引数の値を#defineで置き換えることができない arriという変数はない。プリプロセッサでは変数の中身までは見られない。 分かりやすかったです。ありがとう。
この機能の代替として良き方法はありますか?配列のdimを増やすしかないですか? 配列変数名はコンパイル時には分かっているのだから
その配列のアドレスを格納したポインタ配列を用意してやる __、
iー'゙゙゙゙''''ー-,/^´ ゙';
| ゙ゝ....‐ .}
! |,
i____________......r'".'''゙ヽ . ..,,、
,,. -/ `'ー | .' 、
,..-'" l゙ __.. -''′ ./
. ,/ .`''''〜- ....---''''"゛ ,/
/.,, ,,..r'"
`''ー、,、 _,,,-'" `!、
/'r‐、 ,/´ /゙゙', ヽ
/ レ'゙ ´゙リ´ . `^^゙゙゙゙゙゙厂j .! │ . l
/ | .l. 丿/ / . / !
l ! .,,....--ー'''''''″ / .| (、 . !
_ .ィ‐¨゙゙'广゛ ...... ./ ,ノ.l. `'ィ ..,,_/
..-‐'"゛ 'l_゙'ーノ`' ..........,,_ .,, -" / │ .! ゙''''-.
.i''i ヽ、 / .! !
,)イ : ..,,,,,>u;;;;,、.__ _,,,.. / | "
/ . 、 ! .` |
!, ,!
." ゙ グローバル変数を宣言する時、ヘッダファイルでextern int hogehoge;ってするよね。
*.cからヘッダファイルをincludeすると、
extern int hogehoge;を毎回書いたのと同じ状態になるの? そうだよ
includeはファイルをそのまま展開するだけ >>60
被参照側(メイン)に int hogehoge と書く
参照側(サブ)には extern int hogehoge と書く
これが基本です、*.h を使うのなら
*.h に extern int hogehoge と書く
被参照側(メイン)に int hogehoge と書き、*.h をインクルード…@
参照側(サブ)は *.h をインクルード
@でヘッダと実体に矛盾がないかチェックします お前がC言語を 使う前に
言っておきたい 事がある
かなりきびしい話もするが
俺の本音を 聴いておけ
初期化前の変数を 使ってはいけない
gets()関数も 使ってはいけない
文字列の長さと 配列サイズは別物だ
使い終わったバッファは ゼロクリアしろ
できる範囲じゃなくて 全部やって
https://twitter.com/satoru_takeuchi/status/1176429522687676416?s=03
https://twitter.com/5chan_nel (5ch newer account) >>64
> 使い終わったバッファは ゼロクリアしろ
これは要らんやろ パスワードやらなんやらの機密情報を保存したバッファは解放前にゼロクリアしようねという話です。
任意のバッファという意味ではありません。失礼しました 物凄く初歩的な質問で申し訳ないのですが
1%5のような余剰計算をした場合解は5になるのでしょうか0になるのでしょうか それC言語固有の話じゃないし個々にやるべきかプロセス毎にやるべきかとかのポリシーもあるし >>66
元のツイートした本人か。
ここ見に来ているとは思わなかった。 ゼロクリアだとそこだけ異様にキレイなので逆に重要な値が入るものと察知される
乱数値でクリアすべき 一々乱数計算しなくても数パターン乱数表つくってメモリコピーでもいいんじゃね? そもそもゼロクリアされてるbss領域なんて重要なもの以外にも大量に存在してるので攻撃者がピンポイントで判断することなどまず不可能。
逆に綺麗すぎる乱数のほうが目立つ。 そこだけにするからバレると言うなら全部ゼロクリアすればいいってことでしょ
> 使い終わったバッファは ゼロクリアしろ
> できる範囲じゃなくて 全部やって 今の流行りは不変プログラミング
スコープが短い云々ではなく使い捨て
再利用なんてしない HDDだと少数回のゼロクリアじゃデータ復旧される可能性が残るけどメモリだったらその心配はないのかね? >>78
DRAMはリフレッシュがあるので原理的に不可能な気がする。
SRAMもフリップフロップなら不可能な気がする。 スワップされてディスクに書き込まれたら終わりなのでスワップされないようにする必要がある。 windowsの細かな動きがわからんけどスリープとかでメモリ内容を全部ディスクに保存する動きしない?
するなら言語レベルではどう頑張ってもディスクにデータを書き込まずにスルーする術なんてないんじゃなかろうか?
ということは漏洩防止目的でバッファをゼロクリアする意味は無い?
windows以外は知らん スリープ処理って関数実行中でも起きるの?
メッセージ待ちとかで起こると思ってた。 多分priemptされてたら実行状態でも普通にswap outされるだろうな。 スワップに書いてある内容がどのプロセスのものかをどうやって知るつもりなんだろう…
てかそんなのがわかる状況ならそもそもセキュリティうんぬん言ってもしょうがないと思う Linuxにはmlock()がある。
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/mlock.2.html
多分他のOSにも似たようなのはある筈。
なければ高度なセキュリティが必要なプログラムは作れない。 サスペンドでメモリ内容が全てディスクに書き込まれるような場合は暗号化サスペンドイメージを使うように予め設定しておくしかないようだ。(もはや言語の問題ではない。OSの問題)。 最終的にはOSやらハードウェアファームやらのレベルの話に行き着くんで上位レイヤーでの完全対応は無理
ならば他アプリが自アプリのバッファにアクセスできないよう下位レイヤーが保証してるならバッファクリアは不要ということになる?
そんなレベルで心配が必要なことは個人的に触ることは無いと思うけど 関数ポインタの書式と宣言方法がわからぬ(´・ω・`)
だれか助けてクレメンス ここで講義始めるわけに行かないんだからもっとspecificに頼むよ Makefileなどに書かれているCCって「C Compiler」の略でしょうか? まずは燃料投下する必要があるんじゃないかな。C言語はダメとかクソとか、あるいは引数にvoidなんて見たことないとか、そういったことを書けば火が付いて3スレぐらいあっという間に消費すると思うよ。 ■ このスレッドは過去ログ倉庫に格納されています