warning: cast from ‘char *’ to ‘int *’ increases required alignment from 1 to 4
警告:整数を扱うならば素直にint型を使おう
[-Wcast-align]
■1.扱う数値で型を色々使うのは避けよう
#include <stdio.h>
int main(void) {
char c;
scanf("%d",(int *)&c);
printf("コーヒーはコンビニで%d円で買える\n",c);
short s;
scanf("%d",(int *)&s);
printf("一か月の小遣いは%d円\n",s);
int i;
scanf("%d",(int *)&i);
printf("サラリーマンの生涯収入%d円",i);
}
コーヒーはコンビニで100円なのでchar型で表現可能。
月の小遣いは3万円以下なのでshort型で表現可能。
と、
最大値に応じて型をchar/short/intと様々な型を使うのは
止めましょう。
整数を扱うならば基本は int 型です。
最大値に応じて型を分けるのは無意味に几帳面でハイリスクです。
上記のコードでは”%d”書式に対応する変数はint型(4byte)必要ですがcharは1byte、shortは2byteしかありません。
1byteや2byteしかない領域に4byte書き込むのでメモリ破壊が発生してプログラムが異常終了する場合があります。
現代の32/64bitのコンパイラでは int 型は 2147483647≒21億まで表現できます。
「最大値をchar/shortで表現可能だからchar/shortを使う」と言った
貧乏くさい発想は止めましょう。
整数を扱うならば 基本は int 型を使用して
符号拡張、データ欠損、メモリ破壊といった事故を回避しましょう。
■2.整数を扱うならば基本は int 型を使う
#include <stdio.h>
int main(void) {
int c;
scanf("%d",&c);
printf("コーヒーはコンビニで%d円で買える\n",c);
int s;
scanf("%d",&s);
printf("一か月の小遣いは%d円\n",s);
int i;
scanf("%d",&i);
printf("サラリーマンの生涯収入%d円",i);
}
整数はint型が基本,無駄なキャストも削除
■3.除夜の鐘を数える型を検討してください
#include <stdio.h>
#include <stdint.h>
#include <stdint.h>
#if TYPE==11
//メモリの1バイトは血の一滴
//除夜の鐘は108より大きくならないのでchar型で足りる
#define TYPE_X char
#elif TYPE==12
//符号付きを明示する
#define TYPE_X signed char
#elif TYPE==13
//符号無しを明示する
#define TYPE_X unsigned char
#elif TYPE==14
#define TYPE_X int8_t
#elif TYPE==15
#define TYPE_X uint8_t
#elif TYPE==16
//基本型はtypedefする(MISRA-C 4.6)
typedef unsigned char UB;
#define TYPE_X UB
#elif TYPE==41
//除夜の鐘は負値にならない
#define TYPE_X unsigned int
#elif TYPE==42
#define TYPE_X int32_t
#elif TYPE==43
#define TYPE_X uint32_t
#elif TYPE==44
#define TYPE_X size_t
#else
//整数を扱うのに最も自然な型を使う
#define TYPE_X int
#endif
int main(void){
for(TYPE_X i = 108;i >= 0 ;i--){
printf("除夜の鐘残り%d突き\n",i);
}
}
符号無し系は無限ループして面倒な事になるし、
int より狭い型は符号拡張して面倒な事になるので
筆者は最も自然な int 型を推奨します。
参考: