前々から、C言語のポインタで不思議だったこと。

最適化C 言語 より
http://www.imit.chiba-u.ac.jp/new-system/sr/man_hitachi_c/MAN/3000/03C3100D/C310057.HTM
>単項&演算子をアドレス演算子といい,&の後に続くオペランドのポインタ(アドレス)を表します。
>(3) 記述例
>int a , *p ;
>p = &a ;
>    解説
>        &aはaのアドレスを表し,ポインタpにaのアドレスを代入する式です。

こういうのを見て、アドレス演算子をつければ、
その変数のアドレスが分かるって理解しちゃうと不思議なことが起きます。

例えば、

#include <stdio.h>
main() {
	int target;
	int x = &target + 1;
	int y = &target;y += 1;
	printf("x = %d\ny = %d\n",x,y);
}

のようなコード。xとyが同じ値になりません。

友人に色々教えてもらい分かったことなのですが、
数値とアドレスは違うもの。&をつけるとポインタ型になる。」ということ。
考えれば、普通は変数にアドレス演算子をつけたものは、ポインタ型にエラーなく代入してますよね。
つまり、アドレスの型は、ポインタ型なのです。

なお、ポインタ型同士の加算は出来ないです。

&target + &target ←エラー

実際の計算的には

int x = &target + n;
→
int x = (int)&target + sizeof(target) * n;

X型のポインタ型に、数値を加算する場合に、自動でsizeof(X)を数値に掛け算してくれます。
数値ではなく、ポインタ型の場合はエラー。

HSPをやっていると、varptr函数でアドレスが分かるのですが、

アドレス演算子は、それと同じようなものだと思っていたわけですが、こんな違いがあったのですね。
あとあと、教科書やサイトとかで、ポインタ型を%pではなく整数型を表示させる%dで表示するもんだから、
なんか、「アドレスと整数は同じなんだ。アドレスって数値だし納得!」みたいな錯覚するというか。

後で調べたのですが、ポインタに関して、
苦しんで覚えるC言語アドレスを記憶する変数 がつっこんだところまで解説していて分かりやすいです。

まあそれはおいておいて、友人が書いたサンプル。

#include <stdio.h>
main() {
	int x = 1,y[] = {0,100};
	printf("%d\n",x[y]);
}

という書き方のほうが驚いた。
y[2] が *(y+2) に対応しているから、こういう書き方できるそうです。
C言語は奥が深いです。

いろいろ教えてくださって、ありがとうございます。m(_ _)m

ポインタ型同士の加算・ポインタ型に数値の掛算・割算はエラー

#include <stdio.h>
main() {
	int* target;
	target = (int *)1 + (int *)2;
	target = (int *)1 * 1;
	target = (int *)1 / 1;
}

以上のことが分かると、次のようなネタコードが書けます。

ビットシフト無しで1バイトずつ取り出す。(1回の加算と1回のビット論理和)

#include <stdio.h>
#define GET(T,N) ((int)*((char*)(&T)+(int)(N)))
main() {
	int i,target = 0×11223344;
	for(i=0;i
(すみません。ブログの仕様変更で消えてしまった!)

加算のみで5の倍数を表示する(3回の加算)

#include <stdio.h>
#define GET(T,N) (int)((T*)0+(int)(N))
main() {
	int X = 8;
	printf("%d\n",GET(long,X)+GET(char,X));
}

関連記事

  • HSPで高DPI対応ソフトを作ろうHSPで高DPI対応ソフトを作ろう こんにちは! 久しぶりにHSPの記事を書きたいと思います! 今回は、HSPの高DPI対応です。 はじめに 高DPIとはなんぞや、という説明をします。 昔のディスプレイは、1ドットのサイズが細かくないため、 1ピクセル=1ドットのような設計がほとんどでした。 そして、1ピクセルの大きさも、どのディスプレイもだいたい同じようなサイズ(96dpi)でし […] Posted in プログラミング
  • Bresenhamアルゴリズムで線分の計算は早いのかなBresenhamアルゴリズムで線分の計算は早いのかな 以前、直線を描くのにこんなのを作った。 特に工夫点もない、素直な方法である。 #module "linem" #deffunc line2 int line_x1,int line_y1,int line_x2,int line_y2 line_xabs = abs(line_x1-line_x2) line_yabs = […] Posted in アルゴリズム
  • Linuxで動作するCプログラムのデバッグ環境構築2Linuxで動作するCプログラムのデバッグ環境構築2 前回の「Linuxで動作するCプログラムのデバッグ環境構築1」から引き続きます。 今回は、Eclipseを使って、Cのプロジェクトを作ってコンパイルしてみるところまで行ってみたいと思います。 では、さっそく解説をはじめます。 今回は図をふんだんに使って分かりやすく説明します! プロジェクトを作成しよう 1 Eclipseを開きましたら、左のプロジェクトの部分で右クリッ […] Posted in Linux
  • Linuxで動作するCプログラムのデバッグ環境構築1Linuxで動作するCプログラムのデバッグ環境構築1 こんにちはー! 今回は、Linuxで動作するCのデバッグ環境の整え方をお話しします。 皆さんは、Raspberry PiとかのLinux上で動作するプログラムを作るときにどうしていますか、 Raspberry Pi 上で make […] Posted in Linux
  • マップオンデマンドの地図更新でパスワードが入力できないマップオンデマンドの地図更新でパスワードが入力できない 車を購入時にカーナビとしてNSZT-W61Gを付けたのですが、 カーナビ購入してから3年間はマップ情報のバージョンアップが無料ということで、 バージョンアップをしようとしました。 バージョンアップ方法の流れ 1. 購入時についていた「マップオンデマンドセットアップディスク」のDVDでセットアップツールをインストール 2. 「GAZOO」を無料でユーザー登録(「TOYOTA […] Posted in 雑記
  • OculusRift CV1 が届いた(予約~FedEx配送~セットアップ)OculusRift CV1 が届いた(予約~FedEx配送~セットアップ) こんにてゃ! 以前から欲しかった OculusRift CV1 が本日 2016/5/14 に届きました。 欲しかった経緯を知りたい物好きな方は、2013年の「プロジェクタが欲しい」を参照してください。 横 45.5cm、奥行き 22.5cm、高さ 38.0cm の段ボールの中に、 上記の横 39.5cm、奥行き 17.0cm、高さ 31.0cm […] Posted in VR