記事ディレクトリ
序文
このブログは、一年生の冬休みに C 言語を独学していたときに書いたもので、学習の進捗状況を記録して整理するためのノートとして使用していました。
このブログは、プログラミングの世界を探索するための日記と見なすことができます. コードの再現性と画面キャプチャの便利さのために、学習プロセスを記録する方が便利です. 主に、注意できる詳細、いくつかの操作の記録、およびいくつかの概念の説明を記録します。
トピックは私と一緒にコーディングを学ぶというもので、仲間と一緒に学ぶ姿勢なので、教育志向でも技術志向でもなく、ゴシップもたくさんあります(笑)。
とにかく学びの旅を楽しみましょう!
こんにちは世界!
コードの詳細
#include <stdio.h>
//回车留一行空白
int main()
{
//放主程序的地方
return 0;
}
これがプログラムのフレームワークであり、現在学習しているプログラムをこのフレームワークで記述すれば十分です。以前は新しいファイルを作成した後にこれらを削除していましたが、ルームメイトに止められました(笑)が、静かに書くことができる必要があります。
覚えやすいのはもちろんですが、書道の練習の前に筆順を覚えたり、筆の持ち方を習ってから筆順を覚えたりと、細かいところはもっと標準的で綺麗に書きたいと思っています。右に開始します。
このフレームワークは Weng Kai 先生のコースウェアからコピーしたもので、教授のコードは標準的で美しいはずです。形式については、次の 2 つの側面があると思います。
- 一方、空白行とスペースがあります.たとえば、前処理ディレクティブ (# 記号) でヘッダー ファイルをインクルードする場合、インクルードとヘッダー ファイル名の間にスペースを入れることができます。 preprocessing ディレクティブと main 関数; もちろん、return と戻り値の間にはスペースが必要です。そうしないと、認識されず、コンパイル エラーが発生します。
- 一方でアラインメントですが、1つ目は中括弧の遊び方です。開始ブラケットとそれを使用するステートメントを同じ行に配置するか、別の行に配置するかは、特に強迫観念のある私にとっては問題です。コードが非常に見栄えの良いルームメイトのように、Allman 形式を使用して、Weng Kai 氏を使用することにしました。
「各中括弧は別々の行にあり、左中括弧と右中括弧の両方が、それらが使用されているステートメントに合わせて配置されています。」
return にインデントが入っていて、Tab もちゃんと打てて、main の関数名に合わせてあるので、理由がわからないので先にやってみました。Pythonではインデントがとても重要だと言われています。
プログラムの理解
実際、論理は理解しやすく、主にここにいくつかの用語を記録することで、将来的に端末が「黒い窓」と呼ばれないようにします(Weng Kai 教授)。[コンパイルして実行] をクリックすると、黒いウィンドウがポップアップ表示され、Hello World! が表示されます。これは、ターミナルまたはコンソールまたはコマンド ラインと呼ばれます。
ゼロから始めます
- # は前処理ディレクティブです。ヘッダー ファイルを含むリファレンスを次に示します。
- #include はファイル インクルード コマンドであり、ここでヘッダー ファイルをプルして使用するのと同じです。
- <stdio.h> は、C の標準ライブラリである "標準入出力" で参照したヘッダー ファイルです。ここの山括弧とダブルクォーテーションは共通(プロテストが有効)、違いはヘッダーファイルの検索パスが違うこと、ダブルクォーテーションの方が強力と言われています(これはまだよくわかりません) )、詳細については、C 言語の中国語 Web サイトでの #include の使用法を参照してください。
- int main() はメイン関数です。ファイルでは、プログラムの最初に直接入力するだけです。ただし、1 つのプロジェクトで複数のファイルがビルドされるわけではありません。最初に使った DEV C++ では感じなかったのですが、後で clion を使って同じプロジェクトの下に直接新しい練習用コード ファイルを作成したので、これは良くありませんでした。そのため、clion を使用して新しいプロジェクトを作成します。新しいプロジェクトにはコード ファイルが 1 つしかありません。これらの状況の本質は今でも理解できますし、将来マルチファイル プロジェクトを使用する場合には、自然に理解できるはずです。以前のデバッグ経験があるため、ここでは main の後に括弧を付けました。当時、私は arduionoI を使用して車をプログラムし (文法は似ています)、関数を実行するときに関数の名前を直接入力しました。とにかく、括弧内に値はなく、結果は常に報告されていました。これらの空の括弧を追加するまで、この関数のエラー。それ以来、関数名とその括弧は切り離せない印象を持っています。ここの int は main 関数の戻り値の型です(まだよくわかりません)。
開始ブラケットを開き、いよいよプログラムの作成を開始し、世界的に有名な Hello World! をゆっくりと入力します。
#include <stdio.h>
int main()
{
printf("Hello World!\n");
return 0;
}
プログラミングを学んでいるすべての友人は、この出力行を見て少し興奮すると思います。
出現した新しいシンボルのいくつかの簡単な説明
- printf は、出力したいものを端末に出力できるフォーマット済み出力関数です。
- \n は、単語の改行の機能として理解できます. hello と点線の間に空白行があることがわかります. 大きくない場合は、\n を入力する必要はありません. エスケープ用のバックスラッシュがあることに注意してください。
- また、括弧、引用符、セミコロンの位置関係にも注意してください。
この時点で、学習パスに小さな変更を加えました。この時点で、Linux オペレーティング システムを搭載した仮想マシンをインストールしたためです。私が仮想マシンでプログラミングを学ぼうと決めた理由については、第一の理由はより斬新だったからであり、第二の理由はコンピューターの大物である友人がまさにそれをやったからです。いくつかの便利な指示があると言われています。IDE を仮想マシンにインストールするとき、clion と VScode の間でしばらく苦労しましたが、最終的に後者を選択しました。しばらくclionを使っていたのですが、使い心地がいまいちで、グラフやページの見栄えが良くなったのは満足ですが、VSの機能は良くないと聞きました。比較的強力で、人工知能 ChatGPT と通信することもできます。インストールのプロセスと結果も非常にきれいで、次の調査が楽しみです。
最初に 2 つのプラグインをインストールしましたが、その機能はまだわかりません
新しいファイルを作成するときは、小さな一連の手順があります。将来的にはそれを簡素化する方法があるかもしれません。
最初に、新しいファイルを作成するディレクトリを段階的に開き、[ファイルの作成] をクリックします。拡張子を
.
スピードラン「アハC」
第1章と第2章
(コンパイラは、.C ファイルを実行可能ファイル、つまりコンピュータで直接実行できるプログラムである exe に変換できます) (Aha c コメント、ファイルの種類を理解するのに役立ちます)
以下は本の最初のサンプル プログラムです.
ははは, 最初の小さなプログラムはバグです.
chatGPT の説明を見てください.
ははは, 削除,
ここでデバッグし、chatGPT にプログラムをコンパイルして実行する方法を学習するよう依頼してください端末.
もちろん、右上隅を直接クリックすることもできます. BUG バグとグラフを実行するためのボタン
#include <stdio.h>
/*#include <stdlib.h>//这里似乎没有用*/
int main()
{
printf("ni hao\n");
return 0;
}
改行と改行の \n をつけないとこうなる、いいんだけど、前ほどじゃない
。 Linux の一部のコマンドは、win のコマンドとは異なります。
追加のコード、問題ありません:
#include <stdio.h>
int main()
{
int a,b,c;//变量类型 变量名称
a=1;
b=2;
c=a+b;
printf("%d",c);
return 0;
}
小数の処理 ((float および %f
#include <stdio.h>
int main()
{
float a,b,c;
a=1.5;
b=2.3;
c=a+b;
printf("%f",c);
return 0;
}
端末に式全体を表示します。
#include <stdio.h>
int main()
{
float a,b,c;
a=1.5;
b=2.3;
c=a+b;
printf("%f+%f=%f\n",a,b,c);
//每个%f分别从后面的一个变量里拎一个值出来显示
return 0;
}
データ入力に参加
- scanf(“%d”, &a);
- 主に & が追加されているため、printf に似ています。これは、アドレス テイカーと呼ばれるアドレス テイカーであり、その機能は、変数 a のアドレスを取得することです。
「次の式を作成してください。教室に行く場合は、教室に行く前に教室の住所を知っておく必要があります。ただし、授業が終わった場合は、教室から出る必要があります。すでに教室にいるので、この教室の住所はもう必要ありません。」
——あはC
本の紹介を読んだ後、足し算の計算機を自分でコンパイルしてみてください。
#include <stdio.h>
int main()
{
float a,b,c;
printf("please type in the two numbers which you want to add up\n");
scanf("%f %f",&a,&b);
c = a + b;
printf("%f+%f=%f",a,b,c);
return 0;
}
ターミナルに入力するときは、入力した2つの値の間にスペースを入れるだけです.
問題ないように見えますが、出力は18.210000ではなく、少し奇妙です.導入は次のとおりです:プログラムを変更し
ます次のように
#include <stdio.h>
int main()
{
double a,b,c;//用精度更高的double变量类型
printf("please type in the two numbers which you want to add up\n");
scanf("%lf %lf",&a,&b);//注意这里要用%lf
c = a + b;
printf("%f+%f=%f",a,b,c);
return 0;
}
出力結果を15ビットに変更する小さな操作があります
printf("%.15f+%.15f=%.15f",a,b,c);//%.15f,就会输出15位
今日は寝て、ようやくLinux端末でプログラムを直接実行してみました、ウーフー、スリープ
仮想マシンの環境がとても気に入ったので、構成パラメータを変更しました。メモリとプロセッサ コアの数は、物理マシンの半分に追加されます。IDEの起動速度やコンパイル速度が速くなったのは事実です。
変数を交換します。ロジックは単純で、構文について少し覚えておく必要があります。scanf 関数では、2 つの %d の間にスペースがあるかどうかは同じで、ターミナルで入力する場合は、2 つの値の間にスペースが入ります。このコードの 2 つの %ds の間にカンマを追加し、ターミナルで入力するときに 2 つの値の間にカンマを入れました。
#include <stdio.h>
//To swap the values of two variables
int main()
{
int a,b,temp;
printf("Please type in the two values you want to swap\n");
scanf("%d,%d",&a,&b);
temp = a;//Use a temporary variable
a = b;
b = temp;
printf("%d,%d\n",a,b);
return 0;
}
新しい変数なしで 2 つの値を交換してみてください
#include <stdio.h>
//To swap the values of two variables
int main()
{
int a,b;
printf("Please type in the two values you want to swap\n");
scanf("%d,%d",&a,&b);
a = b - a;//record the differerce between the two variables
b = b - a;//now the value of b is the original value of a
a = b + a;//the original value of a plus this difference is the original value of b
printf("%d,%d\n",a,b);
return 0;
}
あは先生 C は、ここでコードの可読性、単純さ、効率性、および美しさについて話しました。
これは、誰もが「エレガント」と呼ぶものです。実際、機械設計にはそのような追求があります。
うまくいけば、将来的にエレガントなものを開発できます。
以下は先生方からの提案です。
- コードは、機械だけでなく人間も理解できる必要があります。
- 4 つのスペースの代わりにタブ文字 Tab を使用します
- 一時的な削除の代わりにコメントを使用する
第三章
- 2 つの数値間の関係を判断するための 6 つの関係演算子の使用
- 等しい、より大きい、より小さい、より大きいか等しい、より小さいか等しい、等しくない
- == > < >= <= !=
正数かどうかを判定するコードを書く
#include <stdio.h>
//Determine whether a number is positive
int main()
{
printf("Please type in the number you want to determine whether it is positive.");
int a;
scanf("%d", &a);
if(a>0)
{
printf("yes");
//The Tab here indicates that printf("yes") is part of the if statement
}
if(a<=0)
{
printf("no");
}
}
5 の倍数かどうかを判断するコードを以下に記述します。
- 新しい演算子 % は剰余を取ります。使用法は次のとおりです。
#include <stdio.h>
//Determine whether a number is positive
int main()
{
printf("Please type in the number you want to determine whether it is a multiple of 5.\n");
int a;
scanf("%d", &a);
if(a%5 == 0)
{
printf("yes\n");//The Tab here indicates that printf("yes") is part of the if statement
}
if(a%5 != 0)
{
printf("no\n");
}
}
if(a%5 != 0) をelseに置き換えても結果は同じ
#include <stdio.h>
//Determine whether a number is positive
int main()
{
printf("Please type in the number you want to determine whether it is a multiple of 5.\n");
int a;
scanf("%d", &a);
if(a%5 == 0)
{
printf("yes");//The Tab here indicates that printf("yes") is part of the if statement
}
else
{
printf("no\n");
}
}
最大数を見つけて人間の思考プロセスをシミュレートするコードを書く
#include <stdio.h>
//Find out the largest number
int main()
{
int a,b,c,d;
printf("Please enter three numbers\n");
scanf("%d,%d,%d",&a,&b,&c);
d = a;//Just keep the value of d in mind
if(b>=d)
{
d=b;
}
else
{
d=d;
}
if(c>=d)
{
d=c;//Always replace the number d with the largest number I have seen
}
else
{
d=d;
}
printf("the largest number is %d\n",d);
}
ここでは、無知な分類の議論をスキップし、いくつかのアルゴリズムを直接追加し、バブル ソートを使用します。
#include <stdio.h>
//Sorting
int main()
{
int a,b,c;
printf("Please enter the three numbers you want to sort\n");
scanf("%d,%d,%d",&a,&b,&c);
int temp;//define a temperorary box, used for swap values
if(a>b)
{
temp=a;
a=b;
b=temp;
}
if(a>c)
{
temp=a;
a=c;
c=temp;
}
if(b>c)
{
temp=b;
b=c;
c=temp;
}
//the first round is to put the smallest one in the first place
//the second round is to put the second smallest one in the second place
//we don't eliminate values, we just swap values
printf("the result is %d,%d,%d\n",a,b,c);
}
if が数値の場合、それは真か偽か?
#include <stdio.h>
int main()
{
int a;
scanf("%d",&a);
if(a)
printf("yes");
else
printf("no");
}
真実は、0を除いて他のすべてが真です
中括弧なしのネストについて議論を始めましょう
#include <stdio.h>
int main()
{
int a,b,c;
scanf("%d,%d,%d",&a,&b,&c);
if(a>c)
if(a>b)
printf("%d",a);
else
printf("%d",b);
else
if(c>b)
printf("%d",c);
else
printf("%d",b);
}
if と else の対応に注意し、if-else 文の整合性に注意してください。
簡単なコマンドライン操作
コンパイルされたコードを再度実行します。/
いくつかの便利なショートカット キー
**ctrl+/** 複数行のコードを直接コメントに変換
第四章
その間
#include <stdio.h>
int main()
{
while (1)
{
printf("wa");
}
}
それは狂っている
1 から 100 までの数字を出力する
#include <stdio.h>
int main()
{
int a=1;
while (a<=100)
{
printf("%d\n",a);
a=a+1;
}
}
100 以内の 3 の倍数を出力
// printf、ここに Tab を追加して、条件が満たされた場合に実行されるステートメントを示します
#include <stdio.h>
int main()
{
int a=1;
while (a<=100)
{
if(a%3==0)
printf("%d\n",a);
a=a+1;
}
}
1 ~ 100 の合計
#include <stdio.h>
int main()
{
int sum=0,i=1;
while(i<=100)
{
sum=sum+i;
i=i+1;
}
printf("%d",sum);
}
階乗を見つける
#include <stdio.h>
int main()
{
int fac=1,i=1,a=0;
printf("please enter an integer\n");
scanf("%d",&a);
while (i<=a)
{
fac=fac*i;
i=i+1;
}
printf("%d\n",fac);
}
カウントダウンウォッチ
#include <stdio.h>
#include <unistd.h>//different from windows when using 'sleep'
int main()
{
printf("enter the minute and second repectively\n");
int min,sec;
scanf("%d,%d",&min,&sec);
while(min>=0 && sec>=0)//we dont want negtive time
{
printf("%02d:%.2d\n",min,sec);
//use formatting to print leading zeros
//two ways to do it
sleep(1);
//divide into two categories
if(sec<=0)
{
min--;
sec=59;
}
else
{
sec--;
}
}
}
a 行 b 列のアスタリスクを出力してください.
ループの入れ子を使用してください.
ここで無意識に使われている i と j は伝統にかなり沿っています.
これらの小さなものはループ変数と呼ばれます.
デフォルトでは, ijkimn は外側の層から内側の層まで使用されます. .
#include <stdio.h>
int main()
{
int a=3,b=4;//determine the numbers of rows and lines
int i=1;
while(i<=a)
{
int j=1;
while(j<=b)
{
printf("*");
j++;
}
printf("\n");
j=1;
i++;
}
}
別のループの入れ子演習
#include <stdio.h>
int main()
{
int a=6;
int i=1,j=1;
while(j<=a)
{
while(i<=j)
{
printf("%d",j);
i=i+1;
}
printf("\n");
i=1;
j=j+1;
}
}
デビューのために
最も簡単な例:
#include <stdio.h>
int main()
{
int a;
for(a=1;a<=10;a++)
{
printf("%d\n",a);
}
}
で合計
#include <stdio.h>
//caldulate the sum from 1 to a
int main()
{
int a,sum=0;
printf("please enter the value of a");
scanf("%d",&a);
int i;//use this little thing again
for(i=1;i<=a;i++)
{
sum=sum+i;
}
printf("%d",sum);
}
100までのすべての素数をリストする:
#include <stdio.h>
int main()
{
int a=100;
int prime;
for(prime=2;prime<=a;prime++)
{
int i;
int count=0;
for(i=2;i<=prime-1;i++)
{
if(prime%i==0)
count++;
}
if(count==0)
printf("%d\n",prime);
}
}
悪くない
「C 言語プログラミング」 - Weng Kai 教授
判断(if - else)
- 十分な数の人があなたのコードを理解できるコードを書きましょう。
- 2 つの値の関係を計算するため、関係演算と呼ばれます。操作の結果は期待どおりで、計算結果は 1 です。それ以外の場合は 0 です。
- 関係演算子の優先順位は低くなりますが、代入演算子よりも優先されます。
- 関係演算子 == および ! = 優先度が低い。
- if と else の後には常に括弧を付けます
- エラーは、プログラムが間違っているか、コンパイルされていないことを意味します; 警告は 100% 問題ではありませんが、「警告を尊重する必要があります」.
- 「スタイルは三景」
ブランチ
- 継続的な if else には継続的な判断が必要であり、効率的ではありません
- スイッチは、ブレークが発生するまで、対応するケースに直接ジャンプできます
#include <iostream>
using namespace std;
int main()
{
cout << "please enter a number" << endl;
int n;
cin >> n;
switch(n)
{
case 1:
cout << "morning" << endl;
break;
case 2:
cout << "afternoon" << endl;
break;
case 3:
cout << "evening" << endl;
break;
default:
cout << "what?" << endl;
break;
}
}
- カスケード if-else if は、
最初の if が満たされない場合、最初の else に入り、else の中に別の if-else のペアがあると理解できます。 - 単一の出口の方が優れています。つまり、下の図の左側は、右側の
ネストされた if-elseよりも優れています。
サイクル
ループのヒント:
回数が決まっている場合は for を使用して
少なくとも 1 回実行し、do-while を使用し
、その他は while を使用します。
do-while エクササイズ:
//Calculate the number of digits of a number.
#include <iostream>
using namespace std;
int main()
{
cout << "please enter a number" << endl;
int theNum;
cin >> theNum;
int n = 0 ;
do{
theNum /= 10;
n++;
}
while(theNum != 0);
cout << n << endl;
}
データの種類
- inf は無限大、nan は存在しないことを意味します。
//touch the boundry of numbers
#include <stdio.h>
int main()
{
printf("hello\n");
printf("%f\n",12.0/0.0);
printf("%f\n",-12.0/0.0);
printf("%f\n",0.0/0.0);
return 0;
}
hello
inf
-inf
-nan
- float1 == float2 は、
float1-float2<1e-12 の場合に失敗する可能性があります - 整数は正確でなければならず、浮動小数点数は特定の範囲内でのみ信頼できます
- 演算子の両側に矛盾する型がある場合は、より大きな型に自動的に変換されます
- (int)i などの必須の型変換。加算、減算、乗算、除算より演算の優先度が高い
関数
- コードの重複は、プログラムの品質が低いことを示しています
- return には 2 つの関数があり、1 つは実行中の関数を終了するためのもので、もう 1 つは次の値を返すためのものです (オプション)。
ポインター
- ポインタはデータのアドレスです。このアドレスは、そのデータが存在する場所を「指しています」
- このプログラムは 2 つの戻り値を取得する関数を使用します
が、return を使用すると、学校で習う関数のように 1 つの値しか返せません.
ここではポインターを使用し、この関数に 2 つのアドレスを渡します (これらを介して) two 関数の機能は
、これら 2 つのアドレスの値を変更することです.
main 関数では、これら 2 つのアドレスの値にアクセスしてから出力します, つまり、関数の処理結果を出力します.
//use one function to return more than one values
//some of the values could just be returned with the help of pointers
#include <iostream>
using namespace std;
void maxmin(int a[], int* p_max, int* p_min);//define two pointers as parameters
int main()
{
int a[] = {
1,2,3,4,5,87};
int max, min;
maxmin(a, &max, &min);
cout << max << endl << min << endl;
}
void maxmin(int a[], int* p_max, int* p_min)
{
int i;
*p_max = *p_min = a[0];//initialize the values on the two addresses
for(i=0; i<=5; i++){
if(*p_min>a[i]){
*p_min=a[i];
}
if(*p_max<a[i]){
*p_max=a[i];
}
}
}
- 関数の結果で演算状態を返し
、ポインタで演算結果を返すことで、
異常事態(除数が0など)を防ぐことができます。
#include <iostream>
using namespace std;
int get_quotient(int a, int b, double* p_c);
int main()
{
cout << "please enter the dividend and divisor repectively:\n" ;
int a, b;
cin >> a;
cin >> b;
double c;
if(get_quotient(a,b,&c)){
cout << c;
}
}
int get_quotient(int a, int b, double* p_c)
{
int ret = 1;
if(b==0){
ret=0;
}
else{
*p_c = (double)a/b; //this double is used to get a double result
// or the quotient of two integers would lead to an integer too
}
return ret;
}