開発
学校では教えてくれないC言語! 修飾子編
Takeyuki Sato
c言語、IT関係の学校ならどこでも授業がありますよね!? しかし、カリキュラム上どうしても教えていられないところもあるのは事実ですね。なんて言ったてあの歴史あるc言語ですから一年ぐらいで解説できるわけありません。今回はc言語の修飾子についてです。c言語の修飾子は、const,unsigned,signed,long,shortなどあります。型名の前につけてあげます。これらとポインタを使うときには少々気をつけなければなりません。
次のプログラムは警告がでないでコンパイルが通ります。
———————program 1—————————
#include<stdio.h>
const char *str;
int main(void){
char *p = “hello,takeyuki”;
string = p; /*ここで、 const char型ポインタにchar型ポインタを代入しています。*/
printf(“%s”,str);
return 0;
}
————————————————————–
これは、大丈夫ですね。ここでc言語の規格書jisx3010を見ます。
規格書の6.5.16.1の単純代入のところの成立しなければならない条件で、
「両オペランドが適合する型の修飾版又は非修飾版へのポインタであり,かつ左オペランドで指される型が右オペランドで指される型の型修飾子をすべてもつ。」
と書いてあります。
つまり、string = p;の右オペランドは「何も付いていない(修飾されていない)」があります。これは左オペランドには「何も付いていない(修飾してない)」と「const」がついてありますから条件が満たされています。
ここで、これらをヒントに次のプログラムがなぜ警告が出されるのか考えてください。
————————program 2 ——————-
#include<stdio.h>
const char **str;
int main(void){
char hello[] = “hello,takeyuki”;
char **p;
*p = hello;
str = p; /* ここでconst char **型にchar **を代入しています。*/
printf(“%s”,*p);
return 0;
}
———————————————————-
const2.c:7:6: warning: assignment from incompatible pointer type [enabled by default]
str = p;
さて、やはり代入に問題があるようです。一見、大丈夫そうですが・・・
代入のとき左辺は、**strは「修飾されていない」*strのポインタであり*strは「修飾された」文字列へのポインタである。
一方右辺は、**Pは「修飾されてない」*Pへのポインタであり*Pは「修飾されてない」文字列へのポインタである。
故に、この修飾されるかされないかの組み合わせが異なるため非互換である。*Pと*strは互換である。
**str ⇒ *str(非修飾) ⇒ 文字列(修飾) <const char **str>
**p ⇒ *p(非修飾) ⇒ 文字列(非修飾) <char **p>
いかがだったでしょうか、言語仕様を見なければわからないエラーや警告って謎を解き明かすみたいでワクワクしますね。
では。アルバイト 佐藤