[C言語-C言語の最初の理解(4)]


序文

上記の内容を続けて、この記事はまだ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つの使用法があります。

  1. 装飾されたローカル変数-静的ローカル変数と呼ばれます
  2. 装飾されたグローバル変数-静的グローバル変数と呼ばれます
  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的地址
	//这里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 = &num;//地址传给指针p,  

#include <stdio.h>
int main()
{
    
    
	int num = 10;
	//pa是用来存放地址的变量,所以pa为指针变量
	int *p = &num;
	//*是解引用操作,*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++を学ぶために続きます。

おすすめ

転載: blog.csdn.net/taibudong1991/article/details/123714121