0からの、超初心者C言語相談室

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2021/05/19(水) 01:34:14.03ID:OYngDuIu
何にも知らない0からの出発、超初心者のためのC言語相談室


C++は、こちら。

0からの、超初心者C++相談室
https://mevius.5ch.net/test/read.cgi/tech/1542002113/
2デフォルトの名無しさん
垢版 |
2021/05/19(水) 02:46:32.09ID:iywlut5a
糸冬
3デフォルトの名無しさん
垢版 |
2021/05/19(水) 07:05:58.55ID:arAgfqcT
#include<stdio.h>

void funcB(void)
{
int b = 20;
printf("b-address: %ld\n", (long)&b);
}

void funcA(void)
{
int a = 10;
printf("a-address: %ld\n", (long)&a);
funcB();
}

int main(void)
{
funcA();
return 0;
}

(1)変数aとbはメモリ内の特に何という領域に確保されますか。
(2)変数aとbはどちらのほうがより小さい番地にメモリが確保されましたか。
(3)(2)から(1)の領域は前と後ろのどちらの方向へ向かって利用されていくと推測できますか。

スッキリ分かるCの問題なのですが
これの(3)が意味分からないので解説してほしいです
(2)も何でそうなるのかよく分からんですが、。
4デフォルトの名無しさん
垢版 |
2021/05/19(水) 07:34:36.87ID:dkgz9ZJm
無理しないでPythonでもやっとけ
5デフォルトの名無しさん
垢版 |
2021/05/19(水) 11:41:19.87ID:psqzmlBB
&p
6デフォルトの名無しさん
垢版 |
2021/05/19(水) 11:41:41.86ID:psqzmlBB
もとい
%p
2021/05/19(水) 11:51:21.02ID:AeilwxT4
どっかの宿題か
https://brain.cc.kogakuin.ac.jp/~kanamaru/lecture/MP/final/part06/node9.html
https://www.atmarkit.co.jp/ait/articles/1703/01/news166_4.html
https://qiita.com/zacky1972/items/86741d1ac6939795784f
https://qiita.com/hiro4669/items/348ba278aa31aa58fa95
2021/05/19(水) 16:59:00.40ID:ZyjXFBY0
>>4
pythonでもid(obj)で番地見れるからおんなじだよ
変なのpythonスレに誘導するような言動は謹んで頂きたい
2021/05/19(水) 17:43:06.29ID:ONEwpJm5
>>3
(1) 一般にはスタックと呼ばれるが言語仕様にはそのような規定はないので、
  実行環境によっては違うこともあるかもね。
  (言語仕様ではオブジェクトの寿命が決められているだけ。)
(2) 主流の CPU では b の方が小さい番地の可能性が高い。
(3) スタックはメモリの上位番地から下位番地に向かって使われる。
  なんでそうなるかっていうのは結局のところそう決めたから
  そうなっているってだけなんで、逆でもかまわないし、
  実際に逆にデザインされたアーキテクチャは存在する。
  https://ja.wikipedia.org/wiki/PA-RISC

これらはコンピュータアーキテクチャの話。
言語の仕様とそれがどのように実装されているか (機械語を生成するか) は別物なんで、
そこらへんのレイヤを区別して考えないとわけわからんと思う。
2021/05/19(水) 18:47:16.00ID:SmvgsauD
>>9
ありがとうございます!
本に書いてない内容だったのでスッキリしました。
11デフォルトの名無しさん
垢版 |
2021/06/09(水) 14:13:39.99ID:3Qpbsqp/
strstr で文字列を検索出来ますが'\0'が含まれているともちろん正常に動作しませんね
メモリ中の'\0'を含むバイトパターンの現れる位置を調べる関数は何ていう名前?
2021/06/09(水) 16:35:20.50ID:Ih94CWHU
>>11
標準には無い。 POSIX にも無い。
glibc には memmem があるので場合によってはそれが使えることもあるかもね。
13デフォルトの名無しさん
垢版 |
2021/06/10(木) 10:48:32.40ID:ZbfFyHii
memchr を使って memmem 相当の関数を造りました
ありがとうございました

ところで memmem の引数や戻り値ってどうして void * なんですか?
char * になってないと使いにくくないですか?
memory 用だからですか?
void * の場合 size_t が各要素の size の倍数なのか char の size の倍数なのか
特別考慮してくれる訳でもないですよね?
2021/06/10(木) 14:11:49.95ID:MOYAWABe
>>13
> memory 用だからですか?

そう。 バイト列を扱う場合というのは色んな型のメモリブロックである可能性がある。
`void*` の特徴として、他のポインタとの間で暗黙の型変換の対象になるという特別扱いがある。
(C++ ではこの特徴は廃止されているので注意!)

だから

int a=114514;
unsigned char b=0xbf;

memmem(&a, sizeof(a), &b, 1);

といったように何のポインタを渡した場合でも型が違うとかいったエラーにはならない。
いちいちキャストしなくてよいから楽だからこうなってる。
2021/06/10(木) 14:20:26.59ID:MOYAWABe
ちょっと間違えた。
C++ でも void* への暗黙の型変換はアリだけど
void* からの暗黙の型変換はないんだった。
16デフォルトの名無しさん
垢版 |
2021/06/11(金) 16:56:51.54ID:hP01Bt9y
環境
unix系でxterm系のコンソール

less vi emacs等の
現在のプロンプト位置でプログラムを実行し(全画面表示し)終了すると
元のプロンプト位置(の次の行)に戻ってくる処理をできる限りの低レベルで知りたい

例えば
3行目でvi起動
編集
終了
プロンプトが4行目に復帰する
起動時のコマンドが直上にある状態

エスケープシーケンスでのクリアは内部的に
エコーしないで改行してるだけ?なのかそのまま空行が出来てしまう
17デフォルトの名無しさん
垢版 |
2021/06/20(日) 10:08:07.54ID:vSSpHRy4
char a[4]; で確保したときって
strncpy(a, "abc", sizeof(a)); で良いんですか?
char a[4+1]; で確保する書き方もあれば
strncpy(a, "abc", sizeof(a) - 1); で少なめに指定する書き方もあるようですが
どちらが一般的ですか?
strncpy(a, "abcd", sizeof(a)); ならメモリ壊れますか?
2021/06/20(日) 18:24:48.63ID:a10qQPc9
char s[4]
strncpy(a, "abcd", sizeof(s));
はnul文字がコピーされないし

strncpy(a, "abc", sizoef(s)-1);
もnul文字がコピーされない

唯一動作するのは
strncpy(a, "abc", sizeof(s));
だがこれも abc が abcd になったらnul文字がコピーされなくなる

結論:strncpyは使うな
2021/06/20(日) 19:07:42.24ID:Q3V/e/tw
×使うな
◯仕様を理解して適切な場面で適切に使え
2021/06/21(月) 00:42:00.03ID:zJyyyGxF
正直標準ライブラリは諦めた方がいいと思うんだが

安全な文字列や数値型ライブラリはあるけど、特にどれがメジャーというわけでもないから、チームでやると最大公約数の標準ライブラリ使わざるを得ないっていう
2021/06/26(土) 05:41:35.82ID:64gC9b2h
>>16
printf("\e[?1049h"); // これで代替スクリーンバッファを有効にする
printf("\e[?1049l"); // これで代替スクリーンバッファを無効にする
22デフォルトの名無しさん
垢版 |
2021/06/29(火) 14:18:16.44ID:q4QzgdjF
default:
https://www.mbs.jp/news/kansainews/20210628/GE00038998.shtml
■「日本が財政破綻する確率は100%」と大前研一氏。
私に言わせれば、税金を払える生産年齢人口が減り続けている以上、破綻確率は「100%」である。
今の日本は、いわば“裸の王様”のようなもので、すでに国の財政は破綻している状態だから、いつ国債が暴落して債務不履行になってもおかしくない。
ただ、それは1年後かもしれないし、10年後かもしれない、という話なのである。
そういう事態が起きないように財政運営戦略を作っていくのが、国を預かる為政者がやるべきことだ。

ところが日本は、日本銀行が「異次元金融緩和」を8年以上も継続して財務省が紙幣を刷りまくり、大量発行する国債の消化資金を民間金融機関に提供してきた。
そして、その国債を日銀が民間金融機関から買い取って自ら貯め込み、“禁じ手”とされている事実上の財政ファイナンス(中央銀行が通貨を発行して国債を直接引き受けること)を続けている。
2021/06/29(火) 14:18:32.64ID:q4QzgdjF
FRBやECBも日銀と同じように金融緩和を行なっているが、むしろ日銀を先行指標として注視している。

一方、日本人の多くは、自分は国債と関係ないと思っている。
だが実際は、郵便貯金や銀行預金が金融機関を通じて国債に流れ、さらに日銀とGPIFという「2頭の鯨」が国債と株を爆買いしている。
つまり、個人金融資産は国債に化け、年金積立金も国債と株に形を変えているわけで、政府が財政破綻したら国民も一蓮托生なのだ。

だが、今の日本は政治家に政府債務に対する危機感がなく、今後も少子化と生産年齢人口の減少が続く。GAFAMのような巨大IT企業もなければ、アメリカや中国などで続々と誕生しているユニコーンも全く出てこない。このような状況では、巨額の政府債務を返せるわけがない。

では、国民はどうすればよいのか? 
資金に余裕があれば、政府が財政破綻しても影響が少ない「不動産」や「金」を買っておいたほうがよいだろう。
利息が付く預貯金は元本1000万円までとその利息しか保護されないし、「株」や「投資信託」や「債券」も国が破綻すれば「国債」と同じく紙屑同然になるからだ。

ただし、最も有効な対策は、自分に投資して世界のどこに行っても稼げる人間になることだ。
もし日本が破綻したとしても、世界のどこかに繁栄しているところはあるはずだから、そこで稼げる力を磨いておくことが唯一の安全・安心・有望な投資先なのである。
2021/07/05(月) 11:47:38.56ID:c503ASju
4899774451
4899775067
4046019557
489977463X
25デフォルトの名無しさん
垢版 |
2021/09/12(日) 04:36:58.26ID:a7tYNi4V
#include<stdio.h>

#include<string.h>
int main()

{

char str1[] = "Pointers are fun to use.";

char str2[80], * p1, * p2;
p1 = str1 + strlen(str1) - 1;
p2 = str2;
while (p1 >= str1)

*p2++ = *p1--;
*p2 = '\0';

printf("%s %s", str1, str2);

}
2021/09/12(日) 04:40:02.79ID:a7tYNi4V
p1 = str1 + strlen(str1) - 1;の部分と*p2++ = *p1--;この部分の意味がよく分かってない可能性が高いので解説してほしいです

str1の先頭アドレス+str1の文字数-1…でつまり何処をさしてるのでしょうか?
p1 >= str1は先頭アドレスより大きい間はって意味ですか?
2021/09/12(日) 05:25:12.94ID:cHe5vqGk
>str1の先頭アドレス+str1の文字数-1…でつまり何処をさしてるのでしょうか?
str1の最後の文字(0終端の一個前)

>p1 >= str1は先頭アドレスより大きい間はって意味ですか?
惜しい
「より大きい」ではなく「以上」、=があるから

VisualStudio等のIDEのデバッガでステップ実行して、
各変数の変化・ポインタの指す先を見てればすぐわかるよ
2021/09/12(日) 07:15:26.26ID:jZMYjdNi
*p2++ = *p1--

こういのは、意味が分からないしバグるから、MISRA-C で禁止している

Ruby には、++/-- 演算子はない。
Go では単独文扱いで、他の式と組み合わせることは出来ない

MISRA-C でも同様
29デフォルトの名無しさん
垢版 |
2021/09/12(日) 09:32:13.18ID:x3+6FKDq
>意味が分からないしバグる

馬鹿自慢乙
2021/09/12(日) 19:32:07.65ID:0tQ1ubt9
*p2++=*p1--
これは参照してるオブジェクトの値に化けてからアドレスを進めてるんですね。
なんとなく分かりました。ありがとうございます!

>>p1 = str1 + strlen(str1) - 1;
ここがなんかモヤモヤするんですけど
数字で表すとどんな感じになってるか教えてほしいです。お願いします。
2021/09/12(日) 19:38:22.89ID:G4gOb8CM
str1が文字列の戦闘アドレスを刺している。それに文字列の長さマイナスいちを足すと文字列の最後の文字へのアドレスが得られる。
2021/09/12(日) 20:18:52.41ID:0tQ1ubt9
>>31
0+25-1って感じでしょうか?今回のケースの場合
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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