X



C言語なら俺に聞け 143
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001デフォルトの名無しさん (ワッチョイ b375-rVGZ)
垢版 |
2017/10/27(金) 21:28:08.20ID:pAogLeJi0
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

前スレ
C言語なら俺に聞け 142
http://mevius.2ch.net/test/read.cgi/tech/1502364083/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:----: EXT was configured
0853デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/15(金) 07:02:18.81ID:yuhdgz4g0
>>848
セグメントフォルト、バスエラーは同期例外だ
非同期(タイムアウト)でバスエラーなんか起きたら困る

知ったか乙
0854デフォルトの名無しさん (スップ Sd52-cDjN)
垢版 |
2017/12/15(金) 07:14:46.17ID:soFbbFtpd
C言語じゃないけど聞いて良いですか(´;ω;`)
バッチ利用して設定ファイル書き換えたい

1. ユーザーに入力してもらう
2. iniの値をそれで上書き

x.ini
AAA=1
BBB=2
CCC=3

AAA=1
BBB=192.168.0.1
CCC=3

キーはBBBで固定
設定値が少ないから一度全部読み込んで一行ずつtmpに書き込んで〜ってのも問題ない
一行ずつ読み込んで別ファイルに出力とかはできたんだけど
BBBなら〜って判別ができないです
0855デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/15(金) 07:35:31.85ID:yuhdgz4g0
>>854
>C言語じゃないけど聞いて良いですか(´;ω;`)
ダメ
0857デフォルトの名無しさん (ドコグロ MM97-jdna)
垢版 |
2017/12/15(金) 08:14:33.28ID:FCwL/bM6M
>>853
恥の上塗り乙
68Kだと普通の設計だぞ
https://www.slac.stanford.edu/BFROOT/www/Detector/DAQ/Infrastructure/Maint/177aih.pdf
あとバスエラーの定義はプロセッサによって異なるからプロセッサも限定せずに
> セグメントフォルト、バスエラーは同期例外だ
とか書くと知ったかがばれるので注意しろよ w
0858デフォルトの名無しさん (ドコグロ MM97-jdna)
垢版 |
2017/12/15(金) 08:20:34.53ID:FCwL/bM6M
>>854
C言語でやりたいならここでいいけど、バッチでやりたいならこっち
【.cmd】 バッチファイルスクリプト %12 【.bat】©2ch.net
http://mevius.2ch.net/test/read.cgi/tech/1489207631/

あとバッチはその手の文字列操作があまり得意でないので個人的にははPowerShellとか使った方が楽だと思う
【最強CUI】PowerShell -Part 2 [無断転載禁止]©2ch.net
http://mevius.2ch.net/test/read.cgi/tech/1480109402/
0859デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/15(金) 10:39:34.38ID:GBd6F7vt0
68kでのバスエラーとは/BERRがアサートされることで
何をセンスして/BERRをぶっ叩くかは基板次第だな
0862デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/15(金) 12:46:09.63ID:GBd6F7vt0
longjmpやC++のthrowのような例外と割り込みは違うが
ソフトウエア割り込みだの記憶保護例外だのは割り込みと同列なもので
CPUのマニュアルでも同じ章に書いてある
0864デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/15(金) 13:49:05.09ID:yuhdgz4g0
>>857
この文脈ではメモリアクセスに伴って発生バスエラーであり、それが非同期って事はアスセスして読めた後で、やっぱさっきのなし、ノーカン、ノーカン

って事だぞ お前は班長か?
0866デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/15(金) 14:30:39.93ID:yuhdgz4g0
>>865
理解してない奴は、混乱の元だから割り込んで来ないように
0870デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/15(金) 17:25:38.74ID:GBd6F7vt0
0xffffffff番地でもいいはずだね
要は、Cで合法的に定義されたオブジェクトが決して含まないアドレスを
1つ決めごと作っておいてそれを空ポインタということにしようということと
規格合致処理系はそれを必ず決めておかなければならないということ
C以外のたとえばアセンブラで定義されたオブジェクトまでがその規則に従うとは限らないし
そういうオブジェクトをCで扱えてはならないとまでは言ってない
あくまで自己責任でやる限り余計な邪魔立てはしない
0871デフォルトの名無しさん (ドコグロ MMaf-9pXP)
垢版 |
2017/12/15(金) 20:55:15.86ID:eSUvZEm2M
ポインタはポインタであってアドレスではない
けど中途半端に知ってるとポインタとアドレスがイコールと思い込んでしまう
ヌルポインタはアドレスで説明できないポインタの例だね
0872デフォルトの名無しさん (ササクッテロル Spc7-e1v7)
垢版 |
2017/12/15(金) 20:57:06.91ID:wYljbLzIp
バスエラーってのは、あらかじめ決めた領域以外をアクセスしょうとしたら発生するのであって、読んだ後にここ読めないからなんて動作はしない。
むしろ決めて無い場合は幾らでも読み書き出来てしまう。例えそれが嘘でも虚構でもな。
後からノーカンなんてならない。
0876デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/15(金) 21:26:18.69ID:yuhdgz4g0
>>872
わかってない奴は割り込むなって言っただろ
痛々しいぞ
0877デフォルトの名無しさん (ドコグロ MM97-jdna)
垢版 |
2017/12/15(金) 21:34:47.34ID:FCwL/bM6M
>>876
お前がわかってないだけだろ w
68K の話ならデータが読めると言うのは DTACK のアサートで示される
その後に BERR をアサートしても受け付けなかったと思う
(そんなアホな設計はしたことないから本当にそうかどうかは試してないけど)
そもそも BERR は非同期じゃないからお前が初めから頓珍漢なだけ
0884デフォルトの名無しさん (ワッチョイ 1f9f-iA8U)
垢版 |
2017/12/15(金) 22:47:47.28ID:QRFEcBGB0
>>852
ゆとりマジで死ね
韓国人も死ね

お前らはそういう所がいけない。俺は逆ギレしているのではなく、単にキレてるだけだ。
お前らはそうやって常に話をすり替え、被害者ポジションを確保する癖があるが、それは根本的に間違ってる。
そもそも、ここにはお前らより知識のある奴が沢山居るんだから、お前らの聞きかじりで回答する必要はない。
話が余計におかしくなってるだろ。

話を>>841に対する回答に戻すと、841の話しぶりからして、
俺は以下を補足した方がいいと思ったから>>843を投稿したんだよ。
1. 841の言う「ヌルポ」はOSがMMUで捕まえるヌルポである。
2. >>838の言う「組み込み」はMMUがない場合を指している。
3. 838の言う「ゼロ番地付近をアクセス」はOS+MMUがない場合を想定している。
4. 従って838のケースでは841の想定するヌルポは発生しない。
というのを伝えるために書いたんだ。
それをお前は知ったかをしたくて、「MMUなら俺も知ってる!」と勝手に食いついてきただけ。
読む限り、お前は例外がどう動くのか理解できてないと分かるが、無知なままでいろ。
俺は841を助けようとしたのであって、韓国人とゆとりは死ねとしか思ってないから。

VBRを変更する場合、確かに0番地付近を構造体アクセスして転記するんだよ。
838はこれに気づいた、そしてそれを伝えた。
俺は841が「0番地アクセス=ヌルポ」と思っているっぽいので、(これは通常のOS+MMUならそうだが)
それとは違うぞと分かるように補足した。
それに知ったかゆとりが食いついてきただけ。

> プログラミング初心者です (>>835)
という点からしても、838で当たりだろう。
VBRを変更するならかなり初期で対応するので、初心者でも目に付く場所に記述される。
0885デフォルトの名無しさん (ワッチョイ ef9f-v37J)
垢版 |
2017/12/15(金) 23:13:36.36ID:i/+5VHc30
>>835
それをコンパイルするコンパイラの仕様とそれを実行するマシンアーキテクチャによって変わる。
0886デフォルトの名無しさん (ワッチョイ ef9f-v37J)
垢版 |
2017/12/15(金) 23:15:47.32ID:i/+5VHc30
OSによっても変わるかな。
まあしかしOSそのもののソースコードならそう書いて正常動作したとしても特におかしくないかな。
0895デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/16(土) 05:42:42.76ID:V7dZrSJp0
1点、気になるのがNULLと書いていたことだ
0番地にアクセスすることを意図しているコードは
struct hoge *tmp = NULL; ではなく
struct hoge *tmp = (struct hoge *)0; と書くだろう
思うに、単にtmpへの代入を忘れただけではないか?
そういうポカミスを多発するどんくさいやつほど
「変数は必ず初期化」に固執する
0897デフォルトの名無しさん (ワッチョイ 1f9f-iA8U)
垢版 |
2017/12/16(土) 08:59:26.34ID:TBmZZU6f0
>>893
ゆとり死ね
韓国人死ね

俺が読めといっているのは>>884のことだ馬鹿タレ
どうせお前らは日本語が不自由で3行以上は読めないから意味が分からないのだろうが
お前らが迷惑行為を働くことに対して俺はキレてるんだよ


>>895
環境によってはwarningが出る。VC++とか。
個人的には意味ないとも思うが。
0908デフォルトの名無しさん (ワッチョイ ef9f-mLIQ)
垢版 |
2017/12/16(土) 14:30:30.83ID:+Cq6iaDY0
>>906
つまりこうであると。

#include <stdio.h>

int main(int argc, char *argv[])
{
 int i, j;
 for (i = 0; i < 2; i++) {
  for (j = 0; j < 2; j++)
   fputs("おっぱい", stdout);
  for (j = 0; j < 2; j++)
   fputs("ぽよん", stdout);
  putchar('\n');
 }
 return 0;
}
0909デフォルトの名無しさん (ワッチョイ ef9f-mLIQ)
垢版 |
2017/12/16(土) 14:32:07.96ID:+Cq6iaDY0
そういや古いソースには char *p なのに if (*p == NULL) みたいに書いてあるのがあって、今時のコンパイラだと警告出しまくりになるんだよなあ。
0910片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd32-wvVH)
垢版 |
2017/12/16(土) 15:55:35.27ID:2NfYNG63d
>>908
こう書いてもいいね。
#include <stdio.h>
int main(void) {
int i;
for (i = 0; i < 8; i++) {
if (i % 4 < 2) fputs("おっぱい", stdout);
else fputs("ぽよん", stdout);
if (i % 4 == 3) putchar('\n');
}
return 0;
}
0913デフォルトの名無しさん (ワッチョイ ef9f-mLIQ)
垢版 |
2017/12/16(土) 17:23:42.81ID:+Cq6iaDY0
>>910
なるほど。

ちょっと変形してビット演算でも行けるな。

#include <stdio.h>
int main(void) {
 int i;
 for (i = 0; i < 8; i++) {
  fputs(i & 2 ? "ぽよん" : "おっぱい", stdout);
  if ((i & 3) == 3) putchar('\n');
 }
 return 0;
}
0914デフォルトの名無しさん (ワッチョイ 92e1-kSiG)
垢版 |
2017/12/16(土) 19:24:56.53ID:lAe10LAt0
#include <stdio.h>
#include <stdlib.h>
void o(){ fputs("おっぱい", stdout); }
void p(){ fputs("ぽよん", stdout); }
void r(){ puts(""); }
void e(){ exit(0); }
void (*a[])() = { o,o,p,p,r,o,o,p,p,r,e };
int main(){ void (**x)()=a; while(1) (*x++)(); }
0915デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/16(土) 20:18:31.50ID:ftZRkd7o0
>>877
>struct hoge *tmp = (struct hoge *)0; と書くだろう

このように書いても*正しく*NULLポインタが代入される
char zero[(struct hoge *)] = {0};
memcpy(tmp, zero, sizeof zero);
としないとダメ

逆によく見かけるポインタを含む構造体をmemcpyで0に初期化するのも正しく無い
0916デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/16(土) 20:46:52.08ID:V7dZrSJp0
>>915
それがわからんやつが、ここに、いや世界にいると思っているのか?
俺のはコードに意図を残すという論旨だったが、それがわからんやつがおまえさんか

ア ホ か
0917デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/16(土) 21:04:20.92ID:ftZRkd7o0
意図を残すために間違ったコードを書くとは理解に苦しむ
コメントで残した方が数百倍マシ
0918デフォルトの名無しさん (ワッチョイ 926e-zS+j)
垢版 |
2017/12/16(土) 21:54:17.26ID:V7dZrSJp0
ほほう、どう間違ったと言うのかね?
0922デフォルトの名無しさん (ワッチョイ 5e8a-F+rF)
垢版 |
2017/12/17(日) 04:55:34.79ID:vowUucL80
>>919
>>895と間違えてたな

>>921
memcpy(&tmp, zero, sizeof zero);
こうだね
0925デフォルトの名無しさん (ワッチョイ ef9f-v37J)
垢版 |
2017/12/19(火) 08:30:52.67ID:SEIe84in0
お、収まったか・・・
0926デフォルトの名無しさん (ワッチョイ 12b0-+NpI)
垢版 |
2017/12/19(火) 21:03:25.54ID:6p/5Z93J0
完全初心者です。文字列の性質について質問させてもらいます。

柴田望洋著 「ポインタ完全攻略」という書籍にて次のような内容の記載があります。

・文字列リテラルは変数ではないが記憶域を占有する
・文字列リテラルはcharの配列である

そして次のページに、
・このような文字列リテラルは、整数にいいかえると「定数」に相当するものであるから、自由に取り扱うためには
 変数に格納する必要性がある
・そこで利用されるのがcharの配列である

ここでわかりかねるのが、文字列リテラルというのはそもそも定義自体が「charの配列」であるはずなのに、
これをまた「charの配列」に格納するの??と、疑問に思ってしまったわけです。

これはいったいどういうことでしょうか。
0928片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd32-wvVH)
垢版 |
2017/12/19(火) 21:18:36.23ID:3xf/peDqd
"This is C string literal."
これが文字列リテラルね。参照すると文字列定数になる。
char s[] = "This is character array.";
これが文字の配列の変数sの宣言と初期化ね。sはヌル文字を含めた文字列データ先頭を参照する。sizeof(s)は、ヌル文字を含めたデータのサイズになる。
const char *p = "This is pointer to characters.";
これは文字列の先頭へのポインタになる。サイズはアドレスのサイズ。データは変更できない。
0929 ◆QZaw55cn4c (ワッチョイ b260-4mDj)
垢版 |
2017/12/19(火) 21:19:44.32ID:U2jplJ2K0
>>926
ちょっと進んだ知識になるのですが。

プログラムがコンパイルされたのち、プログラムの実行の段階にはいったとき、コードや変数領域やその他もろもろがメモリ上に展開されるわけですが、
文字リテラルは、場合によってはメモリ上の書き込み不可能の場所に置かれます。たとえば ROM メモリとか。
もし、その文字リテラルを適宜書き換えて使いたいのならば、書き込み可能な場所にコピーして使うでしょう、それが、変数であり配列でありするわけです。

ただし文字リテラルを書き換えることが可能な環境では、それを見越して、文字リテラルを書き換えて対応する、という手がないわけではありません。
まあ一般的には行儀が悪いと思われています。それに文字リテラルを途中で長くしたい、とかは不可能ですし。
0930デフォルトの名無しさん (ワッチョイ af36-zS+j)
垢版 |
2017/12/19(火) 21:21:47.79ID:MoA6J0CR0
>>926
おまえさんが疑問に思っているのはこういうことか?
puts("aho"); で済むのを、わざわざ
static const char array[] = "aho";
puts(array); としなければならないのかと
0932デフォルトの名無しさん (ワッチョイ 12b0-+NpI)
垢版 |
2017/12/19(火) 22:51:39.70ID:6p/5Z93J0
>>927
>>928
>>929
>>930
>>931

みなさんお騒がせいたしました。みなさんから頂いたアドバイスを参考にさせていただいて、
よく考えてみたところ、あまり深く気にするべきではないように感じてきました。
先ほどの本の「配列による文字列」「ポインタによる文字列」という箇所を読み込んだところ、
「配列による文字列」はcharの配列を宣言して文字列を用いる場合で、「ポインタによる文字列」
は「char p* = "ABC"」のように、ポインタchar *を宣言してなんらかの文字列リテラルで初期化する
手法であるとのことです。

おそらく・・・よくわかりませんが、直観的に私が当初感じていた疑問点というのはここら辺の部分に帰結
する話だと思われます。

現段階での私の理解
・文字列はそもそも配列?などということは気にしなくてもよい。
・文字列を配列charに格納してからポインタで操作する方法がある。この場合は当然配列の規則に従う
 ので代入とかはできない
・char * = "ABC" のようにchar[]を宣言せずに文字列をポインタで操作する方法もあり。
 この場合は p = "SEX" のような代入ができる。
0934デフォルトの名無しさん (ワッチョイ 12b0-+NpI)
垢版 |
2017/12/19(火) 23:01:45.80ID:6p/5Z93J0
>>933
const
中身を変えられないとかいう…。
ありがとうございます。勉強になります。
0935デフォルトの名無しさん (ワッチョイ 1680-zkGJ)
垢版 |
2017/12/19(火) 23:37:54.35ID:jfHXMkXp0
immutable・不変かどうかの区別。
不変オブジェクトは、メモリ内の読み込み専用エリアに置けるので、最適化しやすいから、
できる限り、不変が望ましい

Ruby, JavaScript では、文字列は可変オブジェクトだが、freeze すると更新できない

s = "hello"
s.freeze

よく覚えていないけど、この本が良かった気がする。
詳説 Cポインタ、オライリー、2013
0936デフォルトの名無しさん (ワッチョイ ef9f-mLIQ)
垢版 |
2017/12/19(火) 23:44:08.13ID:SEIe84in0
char *s = "abc";
と初期化した場合は
s[1] = '\0';
のようなことをすると Segmentation fault になったが、
char s[] = "abc";
の場合は
s[1] = '\0';
が問題なくできた。その後 puts(s) をすると a だけが出た。
OS は Linux でコンパイラは gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16) だ。
-S でアセンブラの出力をさせるとどちらも "abc" をリードオンリーの領域に配置させているが
char s[] と書いた場合は関数の初めでスタックに領域を確保してそこにコピーしてからアクセスしていた。
char *s の方は単に先頭アドレスを使うようになるだけ。(そしてリードオンリーの領域に書いて死亡)。

man gcc を見ると -traditional や -fwritable-strings で文字列リテラルに書き込めるようにできるとは
書いてあるが、この man page 自体が古く、4.8.5 では既にこのオプションは使えなくなっていた。
0937デフォルトの名無しさん (ワッチョイ 1f9f-iA8U)
垢版 |
2017/12/20(水) 00:00:34.09ID:FD+Ux1Ht0
>>932
> 現段階での私の理解
だいぶ間違っているが、ド初心者ならあまり細かく考えずに進めてもいい。
(プログラミング自体の初心者なら、最初の段階で重要なのはそこではないから)
キッチリやりたいのなら、メモリを確認しながら進めた方がいい。
IDE等使えば簡単に見えるし、何を間違っているかすぐに理解できると思う。


>>935
JavaScriptのstringはインミュータブルだ馬鹿タレ
0938デフォルトの名無しさん (ワッチョイ 92e3-4pIx)
垢版 |
2017/12/20(水) 01:15:20.03ID:52iYTq0Y0
>>932
よく言われることだけど、cに文字列型はない
cで文字列という時は必ず文字の配列のこと

char * p = "ABC";

char x[] = { 'A', 'B', 'C', 0};
char * p = x;
って書くのを少し楽に書けるようにしてくれてるだけ

プログラミング自体の初心者なら、cで文字列を扱うこと自体を後回しにした方がいいと思う
0939デフォルトの名無しさん (ワッチョイ af36-zS+j)
垢版 |
2017/12/20(水) 06:46:09.98ID:63AN+5MK0
> cで文字列を扱うこと自体を後回し

俺もそう思う
ど初心者にはちとキツい
0942デフォルトの名無しさん (ワッチョイ 92a6-ak+6)
垢版 |
2017/12/20(水) 09:01:12.50ID:RLul2dZl0
const教は良い教義だと思うけどな。
0945デフォルトの名無しさん (ワッチョイ af36-zS+j)
垢版 |
2017/12/20(水) 10:35:07.90ID:63AN+5MK0
C++にconstexprがあるのはconstの設計ミス
0946デフォルトの名無しさん (ササクッテロレ Spc7-e1v7)
垢版 |
2017/12/20(水) 11:33:29.38ID:9SrStGF7p
>>944
いや、const無くても文字リテラル自身はROMに書かれてるんだけど、デフォルトはそれをわざわざ初期化の時にRAMに展開して書き換えられてもいいように準備して待ってるんだよな。
それがもったないからconst付けるんだ。
0947デフォルトの名無しさん (アウアウカー Sa6f-kaKc)
垢版 |
2017/12/20(水) 11:48:57.84ID:g9yiCifSa
>>946
ところが chrar * 変数に対する初期化に文字列リテラル使うと>>936のようにエラーも警告も出さずにコンパイルが成功してリードオンリーの領域に書き込みアクセスするプログラムができてしまうと。
0949デフォルトの名無しさん (ワッチョイ af36-zS+j)
垢版 |
2017/12/20(水) 13:49:50.09ID:63AN+5MK0
constつーか__attribute__((section(".rodata")))だろ
0950デフォルトの名無しさん (ワッチョイ 12b0-+NpI)
垢版 |
2017/12/20(水) 20:21:08.31ID:ap2qT8fO0
>>932です。
みなさんありがとうございます。
C言語では文字列を扱うのは難しいようですね。
しかし使うだけであれば「なんとなく感覚的」に可能か?と思われます。

ところで、ネットや本でC言語の難所はポインタだ!とよく書いてますが、この文字列の部分というは正に
ややこしい部分ではないでしょうか?
ポインタと配列の関係性の理解だけでも一山あります。
それが文字列となると、ポインタ+配列+文字列の知識の理解、となってしまって。
構造体を勉強するのが先でしょうか。
0951片山博文MZ ◆T6xkBnTXz7B0 (スフッ Sd32-wvVH)
垢版 |
2017/12/20(水) 20:43:26.94ID:hN2yOtWhd
>>950
この程度で難しいというなら、あきらめてJavaに行った方が身のためだ。
plain Cは時代遅れで、そのまま使うとセキュリティに穴があるシステムを量産してしまう。
Cはロボットにまかせて、人間はC++みたいな高度なプログラムを使うことが望ましい。
0952デフォルトの名無しさん (ワッチョイ af36-zS+j)
垢版 |
2017/12/20(水) 20:47:28.16ID:63AN+5MK0
>>951
それを言うなら静かに自力で解決するやつ以外すべて足切り点未満だろ
plain Cで隙だらけのコードを量産するおまえさんが体現しているようにw
レス数が950を超えています。1000を超えると書き込みができなくなります。

ニューススポーツなんでも実況