結論から言えば「ポインタは難しいという意識」が最大の原因ではないかと思います。
正確には違いますか、ポインタ=ポインタ変数としときます。
で、ポインタはただの変数なのにも関わらず特別視するがゆえに分からなくなっているように思えます。
要するに難しく考えすぎなのでは?という話です。
ポインタを教える際アドレスという概念は必要なのか
正直ポインタを使う際、メモリー構造なんて滅多に意識しないでしょう。
今まで変数はただの箱と説明してきたのだから、その箱に間接的にアクセスできるものと説明しればいいと思います。
ここがわかりにくいのかと思いましたが、この概念はC#やJavaなど、多くの言語が持ってます。
C言語特有ではありません
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test_Cs {
class Program {
class A {
public int key1;
public int key2;
}
static void Main(string[] args) {
A obj = new A();
A obj1 = obj;
obj.key1 = 100;
obj1.key2 = 200;
Console.Write("obj.key1={0}\n",obj.key1);
Console.Write("obj.key2={0}\n", obj.key2);
Console.Write("obj1.key1={0}\n", obj1.key1);
Console.Write("obj1.key2={0}\n", obj1.key2);
}
}
}
#include
typedef struct {
int key1;
int key2;
} A;
int main() {
A object;
A*obj=&object;
A*obj1=obj;
obj->key1=100;
obj1->key2=200;
printf("obj->key1=%d\n",obj->key1);
printf("obj->key2=%d\n", obj->key2);
printf("obj1->key1=%d\n", obj1->key1);
printf("obj1->key2=%d\n", obj1->key2);
return 0;
}
見てのとおりほとんど同じです。
C言語の場合ローカル変数の寿命に気を付ける必要がありますが、それはポインタの「理解」には関係のない話でしょう。
int型なども似たような感じです。
#include
int main() {
int a=10;
int*pa=&a;
*pa=20;
printf("a=%d\n",a);
printf("*pa=%d\n",*pa);
}
ポインタはただの変数
ポインタはただの変数です。
代入のシステムは普通のint型と同じく何を指しているかをコピーしています。
intとint*は全く別の型です。&演算子と*演算子によって相互に変換できるだけです。
この相互に変換できる関係をA*型はA型のポインタと呼んでいるだけです。
C#のA[]型はAの配列と同じです。これは[]で変換できますね。
ダブルポインタも特別なことはありません。int**型はint*型のポインタ型です。int型とint*型、上記のA型とA*型の関係と同じです。
+や-はintやdoubleと違います。
ですが、C#での"aaa"+"bb"と1+2は違う処理ですが同じ演算子を使ってます。
それと同様、ポインタ型に対する+-が違う処理でもおかしくはないと思います。
違う型なんですから。
ポインタと配列
ポインタの分かりにくい性質をあげるならこれになるでしょう。
しかし、普通の変数とポインタの関係と配列変数とポインタの関係を同時に使う事なんて滅多にありません。
それぞれ分けて考えるべきだと思います。
文脈によって意味が変わるなんて日本語ではよくあることでしょう。
関数名や変数名をみればどちらかなんてわかると思います。
それにポインタ演算なんて使わくても問題ないと思います。
mallocとポインタ
これに関しては簡単です。
普通の変数 配列 以上2パターンがmallocの使い方の全てといっても過言ではないと思います。
使わなくなったらfreeで解放する必要がありますが、これもポインタの理解には関係ないと思います。
総評
確かにC言語のポインタに分かりにくい要素はありますが、それはC#やJavaなどの多言語にもいえることです。
C#やJavaにはポインタがないとよく聞きますが、似たようなものがある以上かなり語弊のある言い方な気がします。
追記
すみませんC#にポインタがあるのを忘れてました。