C言語ノウハウ

資料を整理していたら、昔作成した某社社内のC言語の認定試験向けにまとめた
資料が出てきたので、世のため人のため自己満足のためにブログに載せてみる。

自分の場合、サンデープログラマとしてはC#、VC++、VBとかを使っているけど、本業の方は今だにC言語をバリバリ使ってます。
あと、UNIXのシェルや、PHP、JavaScriptなんかもCの文法に近いので知っておいて損は無いでしょう。

試験勉強中にまとめた資料なんで誤りもあるかも知れないんで、疑わしい部分は
調べ直してみて頂戴。
で、できればご指摘を。

・制御文
TRUE  = 0以外
FALSE = 0
NULL  = 0
EOF   = 負の整数 (通常は-1)
if文、while文等は0以外(TRUE)の時に処理が実行される。
例1:
char ch;
ch = getche();
while(ch!='q') ch = getche();
printf("qが入力されました");
例2:
if(i)
if(j) printf("iとjは真");
else printf("iは真");
/* このelse文はif(j)文に対するelse。(字下げが紛らわしいが) */
演算子の優先順位
高  ( ) [ ] -> .
↑  ! ~ + - ++ -- (型キャスト) * & sizeof
│  * / %
│  + -
│  << >>
│  < <= > >=
│  == !=
│  &
│  ^
│  |
│  &&
│  ||
│  ?:
↓  = += -= *= /= など
低  ,
・インクリメント演算子/デクリメント演算子
インクリメント
i = i + 1 を i++ と記述することができる
デクリメント
j = j - 1 を j-- と記述することができる
例1:
i = 10;
j = i++;                    /* jに代入してからインクリメントされる */
printf("i=%d j=%d",i,j);    /* 「i=11 j=10」が表示される           */
例2:
i = 10;
j = ++i;                    /* iをインクリメントしてからjに代入する */
printf("i=%d j=%d",i,j);    /* 「i=11 j=11」が表示される            */
例3:
max = 1;
count = 10 * max++;
printf("count=%d max=%d",count,max);  /*「count=10 max=2」が表示される */
・ビットごとの演算子
& … AND
| … OR
^ … XOR (排他的論理和)
~ … 1の補数 (0と1を反転)
例1:
int i = 100;
i = i ^ 21987;
printf("XORの値は%d",i);  /* 「XORの値は21895」が表示される */
/*
0101 0101 1110 0011 (10進数の21987)
^ 0000 0000 0110 0100 (10進数の100)
───────────
0101 0101 1000 0111 (10進数の21895)
*/
例2:
char ch = 'a';
ch = ~ch;     /* 1の補数(ビット反転) */
・シフト演算子
値 << ビット数
値 >> ビット数
例:
unsigned short u;
u = 45678;      /*              1011 0010 0110 1110                       */
u = u << 1;     /* 1ビット左へ  0110 0100 1101 1100 (一番左の1は削られる) */
u = u >> 1;     /* 1ビット右へ  0011 0010 0110 1110 (一番左には0が入る)   */
・条件演算子
if文の代わり"?"を使用できる。
変数 = 条件 ? 式1(真): 式2(偽);
例1:
int i = rand() % 2 ? 1 : 0;
if(i) printf("表");
else  printf("裏");
例2:
rand()%2 ? printf("表") : printf("裏");
・代入演算子
例:
i = j = k = 1; /* i,j,kに1を代入 */
a += 5;        /* a = a + 5      */
b &= c;        /* b = b & c      */
i <<= 3;       /* 2を3回掛ける   */
・代入文での型変換
例1:
int i;
char ch;
i = 1000;
ch = i;
printf("%d",ch);  /* 「-24」と表示される(下位8ビットのみコピー) */
例2:
int i;
float f;
f = 1234.0098;
i = f;
printf("%f %d",f,i);  /* 「1234.0098 1234」と表示される */
例3:
short int si;
long int li;
li = 100000;
si = li;
printf("%hd",si);     /* 「-31072」と表示される */
例4:
int i;
long double ld;
ld = 10.0;
i = ld;
printf("%d",i);  /* 「10」と表示される */
例5:
float f;
f = 10 / 3;
printf("%f",f);  /* 「3.000000」と表示される */
・カンマ演算子
例1:
for(i=0, j=0; i+j<count ; i++, j++)
例2:
value = (count , 99, 33, 100); /* 一番右の100が代入される */
例3:
char ch;
ch = getchar(),  /* ; でなく , を使用しているが、文法的には誤っていない(が、悪い書き方)*/
putchar(ch+1);
・関数
・文字列操作
strcmp( 文字列1 , 文字列2 )
文字列を比較。
同じ場合は0を返す。※0はFALSEを意味するのでif文等で使う場合は注意
・コンソール入力
scanf(const char *format, ...)
例1:
char c;
unsigned u;
long l;
short s;
scanf("%c",&c);
scanf("%u",&u);
scanf("%ld",&l);
scanf("%hd",&s);
printf("%c %u %ld %hd", c, u, l, s);
例2:
char str[80];
printf("アルファベット文字とスペースを入力してください:\n");
scanf("%[a-zA-Z]",str); /* a~z、A~Z以外の文字は返されない */
printf(str);
例3:
int first,second;
scanf("%d%*c%d",&first, &second);
/* "555-2345"と入力した場合、firstに555、secondに2345が入る */
例4:
char str[80];
scanf("%[^0123456789]",str); /* 0~9以外の文字列を読み込む */
例5:
int i,j;
scanf("%d.%d",&i,&j);  /* "12.34"と入力した場合、iに12、jに34が入る */
getchar()
1文字だけ返す。
Enterキーが押されるまで文字を返さない。
ANSI Cで規定されている関数。
例:
char ch = getchar();
printf("文字:%c",ch);
getche()
基本的にはgetchar()と同じだが、キーを押すと画面にエコーしてから
値を返す。
getch()
基本的にはgetche()と同じだが、キーを押しても画面にエコーしないで
値を返す。
gets()
配列に文字列を返す。
Enterキーが押されるまで文字を返さない。
最後のEnter(改行)はNULL文字に置き換えられる。
kbhit()
キーが押されると真(0以外)を返す。押されていない場合は偽(0)を返す。
・データ型
基本データ型  void、char、int、float、double
型修飾子      long、short、signed、unsigned
使用例:  unsigned long int i;
unsigned j;
データ型別による主な出力変換仕様
char                %c
char *              %s
short int           %hd
short               %hd
int                 %d,%i,%o(o変換),%x(x変換),%#x(表記x変換)
long int            %ld
long                %ld
unsigned int        %u
unsigned            %u
unsigned short int  %hu
unsigned long int   %lu
float               %f
double              %g,%f(f変換),%e(e変換)
long double         %Lf,%g
など
配列
多次元配列
例:
/*  {} の使われ方にも注意  */
char words[][2][40] = {
{"dog","Hund"},
{"no","nein"},
{"year","Jahr"},
{"child","Kind"},
{"I","Ich"},
{"",""}
};
printf("%s",words[3][1]);    /* 「Kind」が表示される */
・ポインタ
ポインタ演算子
&  … 変数のアドレスを返す
*  … アドレスに格納された値を返す
例1:
int *p, q;
q = 199;
p = &q;
printf("%d", *p);   /* 「199」が表示される */
例2:
int *p, q;
p = &q;
*p = 199;
printf("%d", q);    /* 「199」が表示される */
例3:
int *p;
*p = 10;            /* 間違い!! pは何も指していないので代入できない! */
例4:
int *p;
double q, temp;
temp = 1234.56;
p = &temp;
q = *p;             /* pは整数(2バイト)なのでdouble(8バイト)を転送できない! */
printf("%f",q);     /* 1234.56とは表示されない! */
例5:
*p++;   /* この場合、ポインタのアドレスをインクリメントする */
(*p)++; /* この場合、ポインタが指すオブジェクトをインクリメントする */
例6:
int a[10] = {10,20,30,40,50,60,70,80,90,100};
int *p;
p = a;
printf("%d %d %d\n",*p  ,*(p+1),*(p+2)); /* この2行は同じ値が表示される */
printf("%d %d %d\n",a[0],a[1]  ,a[2]  ); /*                             */
例7:
float balance[10][5];
float *p;
:
p = (float *)balance;
printf("%f", *(p + (3*5) + 1) ); /* barance[3][1]の値を表示 */
例8:
char str[80];
*(str+3) = 'c';
printf("%c", *(str+3) );    /* 「c」が表示される */
例9:
char str[80];
str++;  /* 間違い!! 配列名を使って生成されたポインタの値は変更不可 */
例10:
char **mp, *p, ch;
p = &ch;
mp = &p;
**mp = 'A';  /* 多重間接参照(ポインタへのポインタ)を使ってchに'A'を代入 */
・関数ポインタ
例:
int sum(int a,int b);
int main(void)
{
int (*p) (int x,int y); /*  *pは優先度が低いので()が必要  */
int result;
p = sum; /* sum()のアドレスを取得する */
result = (*p) (10,20); /* sum()を実行 */
printf("%d", result);
return 0;
}
int sum(int a, int b)
{
result a+b;
}
・マクロ関数
例1:
#define SUM(i, j) i+j
int main(void)
{
int sum;
sum = SUM(10,20);
printf("%d",sum);  /* 30 が表示される */
return 0;
}
例2:
#define MAX(i, j) i>j ? i : j
int main(void)
{
printf("%d\n", MAX(1,2));
printf("%d\n", MAX(100 && -1,0)); /* ←これは間違い (例3が正しい使い方) */
return 0;
}
例3:
/* #defineを以下のように修正すると、例2を使用できる */
#define MAX(i,j) ((i)>(j)) ? (i) : (j)
int main(void)
{
printf("%d\n", MAX(1,2));
printf("%d\n", MAX(100 && -1,0)); /* ←これは正しい */
return 0;
}
・#演算子
例:
#define MKSTRING(str) # str
int main(void)
{
int value;
value = 10;
printf("%s の値は %d です",MKSTRING(value), value);
/* 「value の値は 10 です」と表示される     */
/*  #演算子は、引用符付きの文字列に変換する */
return 0;
}
・##演算子
例:
#define output(i) printf("%d %d ", i ## 1, i ## 2)
int main(void)
{
int count1,count2;
int i1,i2;
count1 = 10;
count2 = 20;
i1 = 99;
i2 = -10;
output(count);
output(i);
/* 「10 20 99 -10」 と表示される */
return 0;
}

1 comment

  1. 清水 3月 8, 2007 3:39 pm  返信

    突然のコメント失礼いたします。アライドアーキテクツ株式会社の清水と申しま
    す。この度、エンジニア様の情報を集めたクチコミサイトのスタートに際しまし
    て、是非ともお力添えを頂きたくコメントさせて頂きました。このサイトの仕組
    みは、皆様のブログの記事の中からエンジニア様に関する記事のみをサイトに収
    集し、クチコミサイトを作るというものでございます。何卒宜しく願いいたしま
    す。
    【説明・登録ページ】http://www.edita.jp/admin/blogger_regist.php?id=1031&c=0
    【お問い合わせ】support3@edita.jp 急なコメント失礼いたしました。ご連絡が
    重なりましたら、申し訳ございません

Leave a reply to 清水 Cancel reply

メールアドレスが公開されることはありません。

CAPTCHA


*