書き出し
printf("%d", i_num);printf("%f", d_num);
printf("%f", f_num);
printf("%c", 1_moji);
読み込み
scanf("%d", &i_nmu);scanf("%f", &f_mum);
scanf("%lf", &d_num);
scanf("%c", 1_moji;
scanf("%s", str);
%c 文字
%d 符号付10進整数
%i 指数部付表記(小文字e)
%e 指数部付表記(大文字E)
%f 10進数の浮動小数
%g %eと%fのいずれか短い方
%G %Eと%fのいずれか短い方
%s 文字列
//////////////////
%o 符号なし8進数
%u 符号なし16進整数(小文字)
%x 符号なし16進整数(大文字)
%p ポインタを表示
/////////
フォーマットの指定
[-][最小フィールド幅][.][精度]フォーマット指定子.//-を付けると左づめになる.
%15.2f //15フィールド幅に右づめで小数点以下を2桁として出力
>>_________100.35
コメント
///* */
関数
戻り値の型 関数名(){};
int func(){
return 10;
};
戻り値の型を設定しなければデフォルトでintになる.なので上述は, 関数名(){
};
int func(){
return 10;
};
と同じ.
引数
呼び出すときに関数に渡す値.int main(void)
{
sum(1,20);
return 0;
}
void sum(int x, int y){
printf("%d", x + y);
}
if
if(式)文;
else
文;
///////////////
文が2行以上の場合
if(式){
文;
文;
文;
}
else{ 文;
文;
文;
}
論理演算子
これを使えば, if文の重複が防げることがある.&& //AND
|| //OR
!() //NOT
理論演算子は真の時1, 偽の時0を返す
for
for(i=0;i< 10;i++){}
他の言語ではサポートされていないが, C言語では, インクリメント部以外の部分で行える.
for(i=0;i< 10;){
i++
}
while
while () {}do {}while ();
break
for,while,doはいずれもbreak文を使うことができる.breakは1つのループから抜けるだけで, ネストしてあっても1つのループから抜ける.
for(i=1;i< 100;i++){
if(i==10)
break; //ループから抜ける.
}
return 0;
}
if文
if(){}if文の()内の条件は1以外の時は実行されない.
if(!(i % 6)){}
6で割ったあまりが0ならその!により1なる. つまり6の倍数なら実行される.
continue文
continue文があるとそこから後の処理は飛ばされ, 次の繰り返しに進むswitch
switch(値){case 定数1;
文1;
文2;
break;
case 定数2;
文1;
default;
break;
}
一致する定数が見つからなかった場合には, defaultの一連の文が実行される.
breakを毎回書かないといけない
swhich文の中のcaseに対応する一連の文はコードブロックではないので中括弧{}は必要ない.
キャスト
一時的に型を変える.double d;
printf("%d", (int)d);
文字列
cahr str[80];gets(str);
printf(str);
この場合定義した80文字を越えるとクラッシュするが, gets()に変わる便利な方法は他にない
printr()の第一引数として使用できる.
string.h
strcpy(ターゲット,ソース); //ターゲットをソースにコピーする.strcat(); //ソースの内容をターゲットに付加する.
strcpm(文字列1,文字列2); //文字列の比較. 一致していれば, 0を返す. なのでif(!(strcpm(文字列1,文字列2))がよく使われる.
strlen(文字列); //文字列の長さ
///////////////////
十分な長さがあれば, str2をstr1に連結する.
char str1[80],str2[80];
if((strlen(str1)+strlen(str2)< 80 ) {
strcat(str1, str2);
printf("%s\n", str1);
}
多次元配列
初期化int sqr[3][3] ={ {1,2,3}, {4,5,6}, {7,8,9} };
文字テーブル
char names[10][40]; //40文字以内の文字列10個gets(names[2]); //3番目の文字列に格納
printf(names[0]); //最初の文字列出力
char animals[3][5][80];
ポインタ
int *p,q;q=199;
p= &q;
printf("%d",*p); //ポインタを使ってqの値を表示する.
&は「〜のアドレス」と読む.
*は「アドレス」と読む.
p=&q;
*p=199; //ポインタを使ってqに値を代入する
ポインタは連結リストやバイナリツリーなどをサポートするために使われる
ポインタは加算と減算のみで, 掛け算,割り算はできない.
int *p;
p=p+200;//もともとさしていた整数から, 200番目の整数を指す
(*p)++;//pがさしている値がインクリメントされる.
///////////
int narray[]={1,20,300};
*p++;
printf("%d\n",*p);//20と表示される.
(*p)++;
printf("%d\n",*p);//21と表示される.
配列とポインタ
Cでは配列を関数に渡すことができないので, 配列のポインタを渡す.float balance[10][5];
float *p;
p=(float *) balance;
*(p + (3 * 5) +1) //balance[3][1]
/////////
int *p,q;
p=&q;
q=1;
printf("%p",p); //アドレスが表示される.
printf("%d",q); //1が表示される
char *p ="ひつつ ふたつ みっつ";
printf("%s",p); //ひつつ ふたつ みっつと表示される
///////////////////////////
char *p[][2]={ {"レッドデリシャス", "赤"}, {"ゴッドデリシャス", "黄色"}, {"",""} //ヌル文字で終わらせている. }; int i; char apple[80]; gets(apple); for(i=0;*p[i][0];i++) { if(!strcmp(apple,p[i][0])) printf("%sは%sです\n", apple,p[i][1]); }
値渡しと参照渡し(関数とポインタ)
値渡しでは関数側で値を変えても, 呼び出し側の引数は影響を受けない.参照渡しでは引数のアドレスが仮引数にコピーされる. 関数側で仮引数に変更を加えると呼び出し側の引数が影響を受ける.
Cは普通は値渡しで因数を渡す.
ポインタを引数として渡すとその変更が関数外でも反映される.
main関数の引数
int argc //コマンドライン上の引数の個数を保持する.int argv //コマンドライン上の文字列のポインタ配列
数値データ
プログラムに数値データを渡してもプログラムはそれを文字列の形式で受け取るため, 変換する必要がある.atoi();//char→int
atof();//char→double
////////
int main(int argc,char *argv[])
{
double pounds;
if(argc!=2){
printf("使用法: [プログラム名] [ファイル名] ([コピー先ファイル名])");
printf("もう一度やり直してください.");
exit(1); //プログラムを終了する.//stdlib.hを使う必要あり
}
pounds=atof(argv[1])/16.0; printf("%fポンド",ponds);
return 0;
}
ファイルの読み込み
stdio.h,stdlib.hint main(int argc,char *argv[]){
FILE *fp;
char ch;
//コマンドライン引数の値が正しいか調べる.
if(argc !=2){
printf("Usege プログラム名 ファイル名");
exit(1);
}
if((fp=fopen(argv[1],"r"))==NULL){
printf("ファイルを開くことができません\n");
exit(1);
}
//文字列書き出す.
while((ch = fgetc(fp)) != EOF)
printf("%c",ch);
fclose(fp);
return 0;
ファイルのコピー
stdio.h,string.h,stdlib.hint main(int argc,char *argv[]){
FILE *from,*to;
char ch;
//コマンドライン引数の値が正しいか調べる.
if(argc !=2 && argc !=3){
printf("Usege: プログラム名 ファイル名 コピー先\n");
exit(1);
}
//コピー元のファイルを開く.
if((from=fopen(argv[1],"rb"))==NULL){//バイナリでも可
printf("ファイルを開くことができません\n");
exit(1);
}
//コピー先のファイルを開く.
char outfilename[80];
if(argc==3){
strcpy(outfilename,argv[2]);
}
//デフォルトファイル名cp_ファイル名
if(argc==2){
strcpy(outfilename,"cp_");
strcat(outfilename,argv[1]);
}
if((to =fopen(outfilename,"wb"))==NULL){
printf("コピー先のファイルを開くことができません.");
exit(1);
}
//ファイルをコピーする.
while(!feof(from)){
ch=fgetc(from);
if(ferror(from)){
printf("コピー元のファイルの読み込みエラー\n");
exit(1);
}
if(!feof(from))
fputc(ch,to);
if(ferror(to)){
printf("コピー先ファイルの書き込みエラー\n");
exit(1);
}
}
if(fclose(from)==EOF){
printf("コピー元ファイルを閉じる際のエラー\n");
exit(1);
}
if(fclose(to)==EOF){
printf("コピー先のファイルを閉じ際のエラー\n");
exit(1);
}
return 0;
}
高レベルテキスト関数
fputs(str,fp); fgets(str,数値,fp);//1行取り込む. 数値-1個分の文字を読み込むか, 改行に出会うまで続けられる. fprintf(fp,"%f",d_num);//printfと使い方は同じ fscanf(fp,"%f",d_num);//scanfと使い方は同じ 実行の時にcommand < commandを使えばfscanfは使いやすくなる構造体
struct 構造体名{int i;
double d;
char str[80];
}s,*p;
p=&s;
p->i=1;//ポインタを介して要素にアクセスするときは, *p.sではなくアロー演算子->jを用いる.
関数に構造体を渡すときは, ポインタを渡すのが基本.
カレンダー
stdio.h,time.hint main(void){
struct tm *systime;
time_t t;
t=time(NULL);
systime=localtime(&t);
printf("時刻: %.2d:%.2d:%.2d\n", systime->tm_hour,
systime->tm_min,systime->tm_sec);
printf("日付: %.2d/%.2d/%.2d\n",systime->tm_mon+1,
systime->tm_mday,systime->tm_year+1900);
return 0;
}
ビットフィールド
struct b_typw{unsigned instock: 1; //1: 在庫あり, 0:未納
}s[100];
if(!s[1].instock) printf("在庫切れ"); else printr("在庫あり"); ブール値(真/偽)の時は1バイトだけ使うとメモリを節約できる.
構造体は配列も使える.
for文の高速化
register int j; for(j=0;j< 3200;j++); const int i=10;//変更できなくする三項演算子
変数=条件 ? 式1: 式2;これはif文で表すと
if(条件)
変数=式1;
else
変数=式2;
i=rand()%2?1:0;
カンマ演算子
for(i=0,j=0;i < j;i++,j--)#define
関数も定義できる.#define MAX(i,j) i>j?i:j
標準ライブラリ
string.g
strcat(char *str1,char *str2);//str1の後ろにstr2をつける.strcpy(char *str1,cahr *str2);//str1にstr2の内容をコピー
strlen(char *str);//strの長さ. ただし, 末尾のヌル文字は数えない
char *strstr(char *str1,char *str2)//str1内でstr2を探し, 最初に見つかった位置へポインタを返す.
例) p=strstr("that is a test", "is");
printf(p);
>>is a test
///////////////////
math.h
acosasin
atan
ceil(double num);//numを下回らない最小の整数をdoubleで返す. 例)1.02→2.0, 2.3→3.0
floor//numを上回らない最大の整数をdoubleで返す.
cos
cosh
exp(double x);//e^x
fabs//絶対値
log
log10
pow(double a, double b);//a^b
sin
sinh
sqrt
tan
tanh
time.h
clock();//現在のプログラムが実行を開始してからその時までに経過した時間.difftime(time1, time2);//time1とtime2の時間差
例)
time_t start, end;
long usingned int t;
start=time(NULL);
for(t=0;t< 5000000L; t++)
printf("\r");
end=time(NULL);
printf("ループには%f秒かかりました. \n",difftime(end,start));
return 0;
stdlib.h
abs(int num);//numの絶対値atof
atoi
atol//long intに変換
クイックソート
整数のリストをソートして結果を表示
int comp(const void *i,const void *j);
int num[10]={
1,3,4,5,8,7,9,6,2,0};
int main(void)
{
qsort(num,10,sizeof(int),comp);
printf("ソート済みの配列:\n");
for(int i=0; i< 10; i++)
printf("%d",num[i]);
return 0;
}
int comp(const void *i,const void *j)
{
return *(int *i)- *(int *j);
}
stdlib.h
srand()にシステムの時刻を指定することで, rand()関数を無作為に初期化するlong ltime= time(NULL);
int utime=(usingned int) ltime/2:
srand(utime);
rand();//前の3行を書けば初期化されている.
gnuplotを使う.
#include < stdio.h>#include< time.h>
#include < math.h>
#include < stdlib.h>
#include < unistd.h> //gnuplot
void fputstate();
int main(void){
#define DATFILE "sin.dat" //datafilename
#define GNUPLOT "/usr/local/bin/gnuplot" //path of gnuplot
#define RANGE 10 //range of gnuplot out
FILE *gnuplot ; //gnuplot file
if((gnuplot=popen(GNUPLOT " -persist", "w"))==NULL){
printf("gnuplotファイルがひらけない.\n");
exit(1) ;
}
fputstate();//write data in datfile
fprintf(gnuplot, "plot \"" DATFILE "\"with points pt 4\n" ) ;
return 0;
}
void fputstate()
{
int i;
FILE *fp; //pointa of datfile
//open dat file
if((fp=fopen(DATFILE, "w"))==NULL){
fprintf(stderr, "データファイルがひらけません\n") ;
exit(1) ;
}
//dat file colmun x and y
double x,y;
for(i=0; i< 1000; i++)
{
x=i*0.01;y=sin(i*0.01);
fprintf(fp, "%f %f\n" , x, y) ;
}
fclose(fp) ;//close dat file
}
ポインタ
