アカウント名:
パスワード:
世の中はCでできている。WindowsだってLinuxだってアメンボだって、みんなみんなCでできている。
プログラミング言語だってCでできている。PythonだってRubyだってオケラだって、みんなCでできている友達なんだ。
アメンボとオケラのCは炭素では?
Cの難易度が誇張されているように思うのだが。Javaより難しい?
世の中にはポインタの加算でなにが起きるか理解できてないのが結構いますから。
同じ型なら引き算は通る(比較も通るけど)。結果は「(ポインタ-ポインタ)/型サイズ」だったような。
ポインタの型って指している先が何であるかを示すヒントでしかなく、実態はしょせん(通常)4バイトの整数型なんだから型に寄らず演算はできると思った。。。
いや、Cのポインタにおいて、型のサイズは重要ですよ。ヒントどころじゃない。たとえば、int *ptr1,*ptr2、sizeof(int)==4なら、
ptr2=ptr1+1;
としたときに、アドレスで見るとptr2はptr1に4バイト足した位置を指すようになるわけです。
ここから、逆に、ptr2-ptr1==1 になるようになっていて、演算の対称性が保証されている。つまり、ポインタ同士の引き算は「(ポインタ-ポインタ)/型サイズ」 [srad.jp]となる。
このようなサイズ情報込みで考えると、「ポインタと整数の加減算」および「ポインタ同士の減算」は定義できても、「ポインタ同士の加算」は定義できません。(ポインタと整数の加算は交換則が成り立つようになっていて「ポインタ+整数」「整数+ポインタ」どちらも結果はポインタ。「ポインタ+ポインタ」を、「ポインタと整数の加算」と見なすには、どちらを整数と見なすかという情報が無いし、ポインタのサイズによっては、どちらを整数と見なすかで結果が変わります。)
#Cの配列アクセス「array[index]」は、「*(array+index)」のシンタックスシュガーなので、「整数+ポインタ」という順番での加算計算できるってことは、「index[array]」って書いても問題ないんですよね。#「data = 5[ptr]; 」みたいなコードを書くと、「data=*(5+ptr);」と解釈され正しく動作するけど混乱の元。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
Stableって古いって意味だっけ? -- Debian初級
CはCでも・・・ (スコア:5, おもしろおかしい)
世の中はCでできている。WindowsだってLinuxだってアメンボだって、みんなみんなCでできている。
プログラミング言語だってCでできている。PythonだってRubyだってオケラだって、みんなCでできている友達なんだ。
アメンボとオケラのCは炭素では?
Re: (スコア:0)
Cの難易度が誇張されているように思うのだが。
Javaより難しい?
Re: (スコア:1, すばらしい洞察)
世の中にはポインタの加算でなにが起きるか理解できてないのが結構いますから。
Re: (スコア:0)
Re: (スコア:0)
Re:CはCでも・・・ (スコア:1)
同じ型なら引き算は通る(比較も通るけど)。結果は「(ポインタ-ポインタ)/型サイズ」だったような。
Re:CはCでも・・・ (スコア:1)
と書きたかったのかな?その理解で問題ないですが、C(++)は一応「高級」言語なのでアセンブリレベルで理解しなくとも、その型の変数が間に何個入るかという理解もできます。
template<typename T>
....
T array[100];
T *p = array +10, *q = &array[55];
int x = q-p;
これで x には 45が入るという寸法です。
Best regards, でぃーすけ
Re: (スコア:0)
「実装でどうなってるかわからないな」と目星をつけてもらいたいところ。
「そらわからんな」がこういうわからなさを指しているとは思えないけど。
Re: (スコア:0)
ポインタの型って指している先が何であるかを示すヒントでしかなく、実態はしょせん(通常)4バイトの整数型なんだから型に寄らず演算はできると思った。。。
Re: (スコア:0)
Re:CはCでも・・・ (スコア:1)
いや、Cのポインタにおいて、型のサイズは重要ですよ。ヒントどころじゃない。
たとえば、int *ptr1,*ptr2、sizeof(int)==4なら、
ptr2=ptr1+1;
としたときに、アドレスで見るとptr2はptr1に4バイト足した位置を指すようになるわけです。
ここから、逆に、ptr2-ptr1==1 になるようになっていて、演算の対称性が保証されている。
つまり、ポインタ同士の引き算は「(ポインタ-ポインタ)/型サイズ」 [srad.jp]となる。
このようなサイズ情報込みで考えると、「ポインタと整数の加減算」および「ポインタ同士の減算」は定義できても、「ポインタ同士の加算」は定義できません。
(ポインタと整数の加算は交換則が成り立つようになっていて「ポインタ+整数」「整数+ポインタ」どちらも結果はポインタ。
「ポインタ+ポインタ」を、「ポインタと整数の加算」と見なすには、どちらを整数と見なすかという情報が無いし、
ポインタのサイズによっては、どちらを整数と見なすかで結果が変わります。)
#Cの配列アクセス「array[index]」は、「*(array+index)」のシンタックスシュガーなので、「整数+ポインタ」という順番での加算計算できるってことは、「index[array]」って書いても問題ないんですよね。
#「data = 5[ptr]; 」みたいなコードを書くと、「data=*(5+ptr);」と解釈され正しく動作するけど混乱の元。
Re: (スコア:0)
C言語のポインタごときで躓く人は適性がないから、そこで脱落したほうが幸せなので、わざと放置するが、
いまでは、ポインタはハンドルとしての使い方だけで十分なので、そう教えると簡単だよ。
ポインタに関する、使いもしないテクニックなんか習得しても無駄だし、そこで引っかかって立ち止まるのはアホらしい。
いまどきのコンパイラなら、配列の添え字を使っても速度に大差ないし。