C言語の基本的な準備
序文
上記の内容を続けて、この記事はまだC言語の基本的な内容の準備知識です。
11.一般的なキーワード
上記は一般的なキーワードです。最初に次のキーワードを紹介します。
11.1キーワードtypedef
名前が示すように、typedefは型定義であり、型の名前変更として理解する必要があります。たとえば、unsigned intの名前をuint_32に変更すると、uint_32も型名になります。num1とnum2を確認すると、これら2つの変数の型は同じです。 。
//将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
typedef unsigned int uint_32;
int main()
{
//观察num1和num2,这两个变量的类型是一样的
unsigned int num1 = 0;
uint_32 num2 = 0;
return 0;
}
11.2キーワードstatic
C言語では、staticは変数と関数を変更するために使用され、次の3つの使用法があります。
- 装飾されたローカル変数-静的ローカル変数と呼ばれます
- 装飾されたグローバル変数-静的グローバル変数と呼ばれます
- 装飾された関数-静的関数と呼ばれます
11.2.1ローカル変数の装飾
静的は、アクション期間を延長するためにローカル変数を変更します。
コード1とコード2の効果を比較して、ローカル変数の静的変更の意味を理解します。
コード1のプリント:1 1 1 1 1 1 1 1 1 1
コード2のプリント: 1 2 3 4 5 6 7 8 9 10
コード1では、ローカル変数iはtest()関数にあります。関数が終了すると、iの値はなくなり、変数iのメモリスペースが解放されます。次回関数test()が呼び出されると、変数iが再初期化され、値0が割り当てられます。
そのアクションの範囲: test()関数では、関数値が破棄されます。
アクション期間:、関数は、関数呼び出しの最後まで呼び出され始めます。
コード2では、ローカル変数iの静的変更、test()関数で、関数が終了しても、iの値はまだ存在し、変数iのメモリスペースは解放されません。次回関数test()が呼び出されたときに、静的ローカル変数iを0に再割り当てする必要はありません。このコードは期限切れになり、変数iは最後のコードを保持し、ステートメントはこれに基づいて実行されます。
そのアクションの範囲: test()関数の外では、値はまだ存在します;
アクション期間:、プロジェクト全体の終了時。
//代码1
#include <stdio.h>
void test()
{
int i = 0;
i++;
printf("%d ", i);//输出10个1
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();
}
return 0;
}
//代码2
void test()
{
//static修饰局部变量
static int i = 0;
i++;
printf("%d ", i);
}
int main()
{
int i = 0;
for(i=0; i<10; i++)
{
test();//输出1-10
}
return 0;
}
結論:
ローカル変数の静的変更は変数のライフサイクルを変更する
ため、静的ローカル変数はスコープ外に存在し、ライフサイクルはプログラムが終了するまで終了しません。
11.2.2グローバル変数の装飾
コード1は正常ですが、コード2はコンパイル時に接続エラーが発生します。
結論:
グローバル変数は静的によって変更されるため、このグローバル変数はこのソースファイルでのみ使用でき、他のソースファイルでは使用できません。
//代码1
//add.c
int g_val = 2018;//函数定义在add.c的源文件中
//test.c
int main()//主函数在test.c的源文件中
{
printf("%d\n", g_val);
return 0;
}
//代码2
//add.c
static int g_val = 2018;//函数定义在add.c的源文件中
//test.c
int main()//主函数在test.c的源文件中
{
printf("%d\n", g_val);
return 0;
}
//代码3
//extern 是用来声明外部符号的
extern int global;//在add源文件中定义的全局变量可以在test中使用
int main()
{
printf("%d\n", global);
return 0;
}
11.2.3装飾された機能
コード1は正常であり、コード2はコンパイル時に接続エラーが発生します。
結論:
関数は静的に変更されるため、この関数はこのソースファイルでのみ使用でき、他のソースファイルでは使用できません。
//代码1
//add.c
int Add(int x, int y)
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//代码2
//add.c
static int Add(int x, int y)//只能在本源文件中使用
{
return c+y;
}
//test.c
int main()
{
printf("%d\n", Add(2, 3));
return 0;
}
//代码3
//将在其他源文件定义的函数,经过声明以后可以在本源文件中直接使用
extern int add(int x, int y);
int main()
{
int num1 = 9;
int num2 = 5;
int sum = 0;
sum = add(num1, num2);
printf("%d\n", sum);
return 0;
}
12. #defineは、定数とマクロを定義します
マクロ定義、名前は通常すべて大文字です
//define定义标识符常量
#define MAX 1000
#define STR "hello bit"//字符串直接用双引号
//define定义宏
#define ADD(x, y) ((x)+(y))
#include <stdio.h>
int main()
{
int sum = ADD(2, 3);
printf("sum = %d\n", sum);
sum = 10*ADD(2, 3);
printf("sum = %d\n", sum);
return 0;
}
13.ポインタ
13.1メモリ
メモリはコンピュータ上で特に重要なメモリであり、コンピュータ内のプログラムの操作はメモリ内で実行されます。
したがって、メモリを効率的に使用するために、メモリは小さなメモリユニットに分割され、各メモリユニットのサイズは1バイトになります。
メモリの各ユニットに効果的にアクセスするために、メモリユニットには番号が付けられ、これらの番号はメモリユニットのアドレスと呼ばれます。
変数はメモリ内に作成され(スペースはメモリに割り当てられます)、各メモリユニットにはアドレスがあるため、変数にもアドレスがあります。次のように変数アドレスを取り出します。
int main()
{
int num = 10;
#//取出num的地址
//这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
printf("%p\n", &num);//打印地址,%p是以地址的形式打印
return 0;
}
アドレスの保存方法、ポインタ変数を定義する必要があり、ポインタはアドレスです。
メモリユニットには番号があり、この番号がアドレスであり、このアドレスをポインタと呼びます。
//内存单元都有编号,这个编号就是地址,我们把这个地址也叫指针
int main()
{
int a = 10;
//%p取地址操作,存放变量a数值的地址
printf("%p\n", &a);
return 0;
}
int num = 10;
int *p;//p为一个整形指针变量
p = #//地址传给指针p,
#include <stdio.h>
int main()
{
int num = 10;
//pa是用来存放地址的变量,所以pa为指针变量
int *p = #
//*是解引用操作,*pa,就是将pa存放的地址所对应的值取出来
//*pa原来对应的值是10,现在重新赋值,就是20了
*p = 20;//重新给地址存放的变量赋值
printf("%d\n", a);
return 0;
}
ポインタを使用した文字の例:
int main()
{
char ch = 'w';
char* pc = &ch;
*pc = 'q';
printf("%c\n", ch);
return 0;
}
13.2ポインタ変数のサイズ
ポインタ変数のサイズは、アドレスのサイズによって異なります
.32ビットプラットフォームでのアドレスは32ビット(つまり、4バイト)
であり、64ビットプラットフォームでのアドレスは64ビット(つまり、8)です。バイト)
//指针变量的大小取决于地址的大小
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
printf("%d\n", sizeof(char *));
printf("%d\n", sizeof(short *));
printf("%d\n", sizeof(int *));
printf("%d\n", sizeof(double *));
return 0;
}
次の例では、文字のアドレスは4バイトを占め、整数配列も4バイトであり、両方の出力結果は4です。
ポインタサイズは固定4バイトです。アドレスのサイズは、アドレスに格納されている数値タイプとは関係ありません。
int main()
{
char ch = 'w'; //0x0012ff48
int a = 10;//0x0012ff40
int * pa = &a;
char * pc = &ch;
printf("%d\n", sizeof(pa));//地址占4个字节
printf("%d\n", sizeof(pc));
//两个输出结果都是4,指针大小就是固定的4个字节
//大小和地址存放的数值类型没有任何关系
//32位平台就是x86, 指针大小是4个字节
//64位平台就是x64, 指针大小是4个字节
return 0;
}
14.構造
演算子->は構造体メンバーアクセス演算子であり、使用法は次のとおりです。
構造体ポインター->構造体メンバー
演算子。これは構造体メンバーアクセス演算子であり、使用法は次のとおりです。
構造体変数。構造体メンバー
//结构体变量
struct stu
{
char name[20];
int age;
char sex[5];
char id[20];
};
int main()
{
struct stu s = {
"张三",20,"男", "20180101" };
struct stu s2 = {
"李四",19,"女", "20180102" };
//printf("name=%s age=%d sex=%s id=%s\n", s.name, s.age, s.sex, s.id);
printf("%s %d %s %s\n", s.name, s.age, s.sex, s.id);
struct stu *ps = &s2;
printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->id);
return 0;
}
typedefを使用して、構造体の名前を短縮します
。stuはstructstuです。
typedef struct stu
{
char name[20];
int age;
char sex[5];
char id[20];
}stu;
void print(struct stu* ps)//结构体类型的指针变量
{
//printf("%s %d %s %s\n", (*s3).name,(*s3).age, (*s3).sex, (*s3).id);
printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->id);
//-> 结构成员访问操作符
//结构体指针->结构体成员
};
int main()
{
//结构体的初始化
struct stu s1 = {
"张三",20,"男", "20180101" };
struct stu s2 = {
"周六",21,"女", "20180103" };
stu s3 = {
0 };//这是使用typedef的效果
//stu就是struct stu
输入结构体数据 name是数组名,就是首地址,age是整数,必须取地址
scanf("%s %d %s %s", s1.name, &(s1.age), s1.sex, s1.id);
//直接打印的
printf("%s %d %s %s\n", s1.name, s1.age, s1.sex, s1.id);
//. 结构成员访问操作符
结构体变量.结构体成员
//使用函数打印
print(&s2);//传入地址,则函数定义必须使用指针了
return 0;
}
要約する
この記事は、最初のC言語シリーズの最後のポイントです。現在、C言語のほとんどのコンテンツのクイックプレビューであり、C言語の基本的なコンテンツの準備知識と見なすことができます。次に、 C言語の基本段階に入ります。ブログの更新内容は、ステーションBの学習ビデオを完全に参照しています。
その後、C言語学習の高度な段階が続き、最後に主要なデータ構造とアルゴリズムの内容が続きます。これでC言語の段階が完了します。フォローアップはC++を学ぶために続きます。