コンテンツ
1つ:揮発性キーワード
constのようなvolatileキーワードは型修飾子であり、それが変更する変数は、オペレーティングシステム、ハードウェア、その他のスレッドなど、コンパイラーが知らないいくつかの要因によって変更される可能性があります。このキーワードで宣言された変数に遭遇すると、コンパイラーは変数にアクセスするコードを最適化しなくなり、特別なアドレスへの安定したアクセスを提供します。
例えば:
この例には揮発性物質はありません。これは、最適化できることを意味します
#include<stdio.h>
int pass = 1;
int main()
{
while (pass)
{
//思考一下,这个代码有哪些地方,编译器是可以优化的。
}
return 0;
}
最適化プロセス全体を具体的に説明するには、分解を確認する必要があります。!!
揮発性物質を追加する場合:最適化できないことを意味します
#include<stdio.h>
volatile int pass = 1; //加上volatile
int main()
{
while (pass)
{
}
return 0;
}
逆アセンブルをもう一度見てみましょう。最適化されていないことを確認するには、次のようにします。
結論:volatileはコンパイラの最適化を無視し、メモリの可視性を維持します。
その他の質問:
const volatile int a = 10;
//vs2013とgcc4.8の両方でコンパイルできます
//constはコンパイル中に使用されます
// volatileは主にコンパイル中にコンパイラに影響を与え、最適化されていないコードを形成します。これは次に操作に影響を与えるため、コンパイルと操作の両方が効果的です。
constはあなたがそれを書かないことを要求します。揮発性とは、読み取るときに毎回メモリから読み取る必要があることを意味します。2つは競合しません。
volatileはvolatileキーワードと呼ばれますが、これは、変更する変数が変更される可能性があることを説明するためだけのものです。コンパイラーはそれに注意を払う必要があり、対応する変数を変更する必要はありません。これには特に注意してください。
2:externキーワード
役割:変数または関数の宣言。
正式な説明の前に、コンパイラで複数のファイルを作成し、test.cでロジックを実装し、main.cでロジックを呼び出し、test.hで関連するヘッダーファイルと関連する変数/関数の宣言を担当する必要があります。
例:
1つ:erxternは変数を宣言します:
test.cファイルで変数intx=1234を定義するとします。
main.cファイルでアクセスしたい場合。最初にtest.hファイルで変数を宣言する必要があります。
ただし、宣言時にxを再度割り当てることはできません(extern int x = 1234; // err)。これは、宣言によってスペースが開かれないためです。つまり、現時点での宣言には、そのようなデータを保存するスペースがありません。
2:外部宣言関数:
プロセスは上記と同様で、すべての関数はtest.cファイルで定義され、main.cファイルでアクセスする必要があり、test.hファイルで宣言する必要があります。次のようになります。
変数はexternを使用して宣言する必要があり、関数はexternを使用せずに宣言できます。しかし、優れたコーディング習慣を身に付けるには、externを導入するのが最善です。
3:structキーワード
なぜ構造体を定義するのですか?
計算するシーンでは構造を定義する必要があります。生徒を説明し、コンピュータを使用して生徒の情報を保存する場合は、構造を使用して生徒を説明する必要があります。
構造体の使い方は?
コードを見てください:
#include<stdio.h>
#define NUM 64
struct stu
{
char name[NUM / 2];
int age;
char sex;
char addr[NUM];
};
int main()
{
struct stu zhangsan;
struct stu lisi;
return 0;
}
ここでは、構造体タイプstruct stuを定義します。このタイプに含まれる属性は、通常、自然界で説明する管理対象オブジェクトを表します。たとえば、学生を管理する場合は、このようにすべての学生を使用して説明します。 。次のように定義することもできます。structstucls[30]; 30人でクラスを定義するのと同じです。各クラスメートは、名前、年齢、性別、住所などの同じ属性を持ちますが、属性の内容は異なります。の。
結論:構造の定義は本質的に本番タイプです。
struct stu
{
char name[NUM / 2]; int age; char sex; char addr[NUM];
}a, b, c;
// 等价于
int a, b, c;
int* p;
構造エッセンス:同じまたは異なる要素を持つコレクション。
構造の初期化:
#include<stdio.h>
struct stu
{
char name[NUM / 2];
int age;
char sex;
char addr[NUM];
};
int main()
{
// 初始化
struct stu x = { "zhangsan",19,'w',"地球" };
return 0;
}
構造が初期化されるとき、中括弧{}は配列と同じように使用され、{}内に配置される値は属性と1対1で対応している必要があります。
構造は全体としてのみ初期化でき、直接割り当てることはできません。!!
struct stu x;
x = { "zhangsan",19,'w',"地球" }; // err
ただし、値を割り当てる必要がある場合は、次のようにすることができます。
struct stu x;
//x.name="张三"; //err 对于数组赋值的时候,它和结构体类似不能直接被赋值,需要用到字符串拷贝strcpy
strcpy(x.name, "张三");
x.age = 18;
構造物へのアクセス:(例として名前と年齢を取り上げます)
int main()
{
struct stu x;
strcpy(x.name, "张三");
x.age = 18;
struct stu* p = &x;
printf("%s\n", x.name); // 张三
printf("%s\n", (*p).name); // 张三
printf("%s\n", p->name); // 张三
printf("%d\n", p->age); // 18
return 0;
}
上記のアクセスプロセスには、ポインティング演算子であるメソッド->があります。これは、ポインタースキームを介してC言語の構造体メンバーにアクセスするための便利な方法です。
構造物アクセスに2つのアクセス方法があるのはなぜですか?
構造は、定義されたときにアクセスされるため、を使用する方が便利です。
パラメータを渡す場合は、ポインタ演算子を使用する方が便利です。
構造体が複数の関数を実行する可能性があるという理由だけで、コードの記述を容易にするために、構造体に個別のアクセスメソッドを設定する必要があります。
空の構造体の大きさはどれくらいですか?
結論:それはプラットフォームに関連しています。VSコンパイラでは編集できません。Linuxでは、空の構造体のサイズは0です。
柔軟なアレイ:
柔軟な配列の定義:
柔軟な配列は構造体内に配置する必要があります!!!
#include<stdio.h>
struct stu
{
int arr[0];
};
int main()
{
struct stu zhangsan;
return 0;
}
知らせ!!!
通常、構造には柔軟な配列が含まれているため、最初の要素はこの配列であってはなりません。つまり、最初の要素は有効な要素である必要があり、他の要素も存在する可能性がありますが、最後の要素は柔軟な配列です。
struct stu
{
char name[20];
//......
int arr[0];
};
柔軟なアレイの使い方は?
柔軟な配列は、可変長配列を形成するためによく使用されます。malloc(ヒープスペースにメモリを生成する関数)を使用するには
柔軟な配列はスペースサイズを占有しません。
#include<stdio.h>
struct data
{
int num;
int arr[0];
};
int main()
{
printf("%d\n", sizeof(struct data)); // 4
return 0;
}
使用プロセスのコードを参照してください。
#include<stdio.h>
struct data
{
int num;
int arr[0];
};
int main()
{
struct data* p = malloc(sizeof(struct data)) + sizeof(int) * 10;
p->num = 10;
for (int i = 0; i < p->num; i++)
{
p->arr[i] = i;
}
free(p);
return 0;
}