質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.33%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

7回答

587閲覧

アドレスを1進めることの意味の確認

OhaseO

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2グッド

3クリップ

投稿2025/02/11 05:02

例えば、int foo[] = {0, 1, 2};と初期化したとき、&foo[0]は0x00E4だったとします。
その場合、&foo[1]は0x00E8と思いますが、ここがいまいち腑に落ちていません。
すなわち、アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。

そして、メモリを説明する際は、よくハコのようなイメージが使用されると思うのですが、
アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか。
すなわち、ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義しているため、アドレスとしては表示されないだけで目に見えないハコが隙間に存在しているというイメージでよろしいでしょうか。

1バイトより小さな型が存在しない?のは、アドレスの最小単位をバイトとして定義しているためでしょうか。
また、そのハコを1バイト単位ではなく1ビット単位で制御するような方法?もあったりするのでしょうか。

初歩的な質問で申し訳ございません。
また、訳の分からないことを言っているかもしれませんが、上手に調べられなかったためご教示していただけると助かります。

tatsu99, thkana👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。

違います。

メモリを説明する際は、よくハコのようなイメージが使用されると思うのですが、アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか。

違いますが 、惜しい。

アドレスを1増やすということは、ハコ1つ分進めることに相当します。
そして、そのハコのサイズは、変数の型によって違うので、実際に変化するメモリアドレスの幅は、変数の型によって変わるのです。
int が 8ビットであれば、箱のサイズは8ビットであり、ポインタは8ビット進みます。
int が32ビットであれば、32ビット進みます。

投稿2025/02/11 06:09

編集2025/02/11 06:27
TakaiY

総合スコア14039

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

すなわち、アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。

それでいいです。
が、int型の変数のサイズは、1ではありません
で、foo[0]からfoo[1]ってのは、1バイト進めるという意味でもありません

投稿2025/02/11 05:17

編集2025/02/11 05:21
y_waiwai

総合スコア88126

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

&foo[0]は0x00E4だったとします。
その場合、&foo[1]は0x00E8と思います

いまの世の中の主流はそうなのですが、必ずそうなるわけではないことに注意が必要です。いわゆる8bitとか16bitCPUと呼ばれるものでは、intは16bit, 2byteであることが多いです。C言語的には、intは少なくとも-32767~32767の値を保存できること、としか決まっていません(さすがにintが8bitというのはC言語では許されない)。

アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。

それはOKです。

アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか

これも、世の99.99999%(個人の感想です)ではよろしいですが、そうでないモノは確実に存在します。アナデバのDSP、と言って分からない人が触れる機会はないでしょうが、こいつには32bitが1byteというモードが存在します。

ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義している

物理的にはビットは存在しているけれど、アドレスが振られるのはbitではなくバイト単位で、その単位でしかアクセスする手段は用意されていないのが普通、という説明がよいのかな。アドレスを定義、というのはちょっと違う気がする。大抵は物理的にそういう構造になっているので。

ハコを1バイト単位ではなく1ビット単位で制御するような方法

構造体のビットフィールド(構造体中のmビットをグループ扱いする仕組み。m=1ももちろんあり)がそれに相当することになるかと思います。余程特殊なハードとそれ用のC言語を作成するのでない限り、アクセス自体はバイト単位で行って、内部的にビット演算によってビット単位(グループ)で操作した結果を得ることになるでしょう。もちろん、それに相当する操作を自分で行うこともできます。ビットマスクとかいう言葉で調べられるかしら。

投稿2025/02/11 13:51

thkana

総合スコア7707

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義しているため、アドレスとしては表示されないだけで目に見えないハコが隙間に存在しているというイメージでよろしいでしょうか。

そのたとえで使われた「ハコ」とはなんぞや?と言うことになるかと思います。
普通のCPUは、メモリーを1bit単位では読み書きできません。メモリー中の位置を示す「メモリーアドレス」は1byte単位です。
メモリーの中の1bitだけを書き換えたくても、それだけを変更できません。(少なくとも)1byteをメモリーから読み出して希望位置の1bitだけ書き換えて、その結果をまた同じ場所の1byteに上書きします。
機械語命令的には、①読み出し②1bit書き換え③書き込みの3命令かも知れないし、1命令で出来るCPUがあるかも知れません(実際あった)。後者の場合でも機械語で1命令でも内部的には3ステップです。

理由はメモリー周りのハードウェアがbit単位でアクセスできるようになっていないからです。
もちろん、そういうCPUとハードウェアを設計して作るのは可能だと思います。「演算処理の中で、1bit単位の演算処理が大多数で、8bit単位~64bit単位での演算は少ない」とかいうような想像しにくいケースでない限り効率が悪そうですね。

ということで、「機械語レベルでアドレスを+1する」は、「1バイト進む」です。

Cのポインターや配列添え字の場合だと、+1 は 「その型の1つ分のバイト数だけ進む」、つまりintが4byteだとint型へのポインターを+1すると、機械語レベルでは+4されます。

そのたとえで使われた「ハコ」とはなんぞや?と言うことになるかと思います。

の続きを書くと、「(今の一般的な)コンピューターのメモリーの説明」で使われたのなら1byteとか4byteとかの「1byteの整数倍」の大きさのハコになると思います。そうではなくて、「抽象的なデータの保管の仕方の説明」で使われたのなら「1bitの整数倍」のハコもあり得るかと思います。「真偽値の保管には1bitあれば十分ですよね?」は「はい」です。
ただし、メモリーの話と絡めると、Cだとstructでビット単位で定義できるのはご存じかと思いますが、struct { unsigned char a:1; } X;と宣言した変数Xはメモリー上で1byteの場所を取ります。

投稿2025/02/11 12:34

otn

総合スコア86160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

OhaseO

2025/02/11 16:31

回答ありがとうございます。 みなさんの回答も確認した上での判断にはなってしまいますが、最もしっくりくるように感じましたので、ベストアンサーとさせていただきます。 ハードに関する知識不足ゆえの今回の質問とも感じていますので、それらの勉強も同時に進めていこうと思います。 その他のみなさんも回答ありがとうございました。 私の言葉の使い方が誤っていたためか一部誤解を与えてしまっていたようで申し訳ございません。 回答は全て読ませていただき、理解が深まりました。 また機会がありましたら、よろしくお願いいたします。
guest

0

アドレスの計算は内部的にはデータサイズに対する掛け算で表されます
intのデータサイズは4byteなので、例えばint配列の場合、今回のfooのケースではfoo[0]->foo[2]の移動量が4*2=8byteとなります

またC++ではインスタンスのメンバとして1byte以下のサイズのフィールド領域を定義できます

#include<stdio.h> struct A{ unsigned char c:3=0; //3bit領域 }; int main(void){ printf("%lld,sizeof(A)); }
1

データサイズはbit単位では表されないため、メモリ管理の都合からプログラム上ではこのクラスのデータサイズは1byteとなりますが、内部のメンバには1byte以下のサイズが割り当てられます
このように、ユーザー定義型によってbit単位のデータサイズを考えられます
最もC++以外で同様の操作が可能な言語があるかは判りません

ちなみに、1byte=8bitは慣例的な取り決めであって絶対ではありません
8bitというサイズにはオクテッド(octed)という単位が与えられています
よって厳密には1byte≒1octed=8bitとなります

またアドレスも同様に1アドレス=1byteとは限りません
かつて情報処理技術者試験用に制定されたCOMETという仮想的なマシンでは1アドレス=16bitと定義されていました

このように厳密な定義には齟齬があるものの、現代のコンピュータでは1アドレス=1byte=8bitがほぼ当たり前となっています

なのでこれらを知っておく必要はありませんがアドレスの足し引きとはデータサイズの掛け算であることは意識しておくと良いでしょう

投稿2025/02/11 10:11

編集2025/02/11 10:25
Manabu

総合スコア93

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C言語で決まっているのは、charが1byteのみです。あとは環境依存です。
質問者さんの環境ではintが4byteなので、&foo[0]のアドレスが0x00E4なら、&foo[1]のアドレスは4足した0x00E8になります。
アドレスはbyte単位なので、1byte=1個の箱で表現します。

これに対して、ビット演算の際は、1bit=1個の箱で表現します。

両者が混在した絵を描く場面は、考えづらいですね。
なので「目に見えないハコが隙間に存在している」なんて考えなくてよいと思います。

投稿2025/02/11 08:36

hiroki-o

総合スコア1255

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

バイトとかビットとか、メモリサイズが依存しているのは型の方です。
intが4バイトなら次のアドレスは元のアドレスに4バイト足した値になります。
charが1バイトなら、次のアドレスとしては元のアドレスに1バイト足した値になります。

C言語のポインタが喜ばれるのは、機械語の時はこのなんバイト進めたところを次の領域とするのかをプログラマが指定したところを型という制約により、ある種自動的に指定できるところらしいです。

ハコの認識としては正しそうに見えますが、
正直いってExcelのセルをイメージした方が理解が容易だと思います。
1つのセルが1ビットだとしたら、そこに0or1しか入らないので、これが8個連続していたら2の8乗だけのデータが格納でき、その中身によってそれがなんであるか?を2の8乗分だけ表せます。

C言語に1バイトより小さい型が存在しない理由はよく知りませんが、
概念的には1ビット型で0 or 1だけを示すことも可能でしょう。

投稿2025/02/11 06:25

編集2025/02/11 06:26
utm.

総合スコア524

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.33%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問