記事ディレクトリ
1 つの基本データ型
C 言語では、基本的なデータ型は整数 (int)、文字 (char)、および浮動小数点 (float、double) です。32ビットシステムにおける基本的なデータ型は以下のとおりです。
タイプ | 型名 | バイト | 範囲を示します |
---|---|---|---|
整数 | 整数 | 4 | - 2 31~ 2 31 - 1 |
符号なし整数 | 符号なし整数 | 4 | 0~2 32~1 |
短い整数 | 短整数 | 2 | -2 15~ 2 15 - 1 |
unsigned short int | 符号なし短整数 | 2 | 0~2 16~1 |
長い整数 | 長整数 | 4 | - 2 31~ 2 31 - 1 |
文字 | 文字タイプ | 1 | - 2 7~ 2 7 - 1 |
符号なし文字 | 符号なし文字 | 1 | 0~2 8~1 |
浮く | 単精度浮動小数点 | 4 | 3.4E ± 38 (有効数字 7 桁) |
ダブル | 倍精度浮動小数点 | 8 | 1.7E ± 308 (有効数字 15 桁) |
ロングダブル | ロングダブル | 10 | 1.2E ± 4932 (有効数字 19 桁) |
上記以外に、8 バイトを占有し、long int よりも範囲が広い、long long int 型もあります。プログラム内で次の定義が何度も出てきます。
#define CODE 1024U
其中的“U”或者“u”,是指定为unsigned类型。
float 型の場合は「F」または「f」を、long double 型の場合は「L」または「l」を追加します。小数点の後に接尾辞がない場合は、デフォルトで double 型になります。
#define CODE 1.024 // 默认为double类型
#define CODE 1.024F // 为float类型
#define CODE 1.024L // 为long double类型
2 配列、文字配列、文字列
2.1 配列
配列は、同じデータ型の複数の要素のコレクションです。配列には1次元配列と2次元配列があります。配列メソッドを次のように定義します
数据类型 数组名[数组长度] // 一维数组
数据类型 数组名[数组行数][数组列数] // 二维数组
数组的索引(也可以叫做下标,序号)是从0开始的。比如定义数组时,数组长度为n,那么数组的索引是从0 ~ n - 1
。
配列に初期値を割り当てる場合、ビットごとにのみ割り当てることができます。
int a[4] = {
1,2,3,4}
配列の長さが指定されていないが、配列の初期値が指定されている場合。コンパイラーは、初期値の数とタイプに従って、配列の記憶域スペースを自動的に割り当てます。
可以用sizeof计算数组空间的大小,也就是字节数。进而可以求数组的长度。
たとえば、配列の長さを調べるには、
#include<stdio.h>
int main()
{
int a[4] = {
1,2,3,4};
printf ("数组a的长度为%d",sizeof(a) / sizeof(a[0]));
return 0;
}
出力は
数组a的长度为4
2.2 文字配列と文字列
要素が文字である配列を文字配列と呼びます。文字列とは、連続した文字のシーケンスです。文字列定数は、 "Welcome", のように二重引用符のペアで囲まれます编译系统自动在每一字符串常量的结尾增加“\0”结尾符
。字符串可以由任意字符组成,一个长字符串可以占两行或多行,但在最后一行之前的各行需用反斜杠结尾
。例えば
"STM32F103ZET6"
に相当
"STM\
32\
F103\
ZET6"
需要注意的是,"A"与'A'是不同的,"A"是由两个字符(字符"A"与字符"\0") 组成的字符串而后者只有一个字符。最短的字符串是空字符串"",它仅由一个结尾符"\0"组成。
3 つの列挙型
列挙型はユーザー定義のデータ型です。列挙とは、取り得る値を一つずつ列挙することです。列挙型を定義する形式は次のとおりです。
enum 枚举类型名
{
标识符1 = 整型常数1,
标识符2 = 整型常数2,
……
标识符n = 整型常数n,
};
如果在定义时没有给枚举成员赋值,编译时,编译器会自动给每一个枚举成员赋一个不同的整型值。第一个成员为0,第二个成员为1,以此类推。枚举类型的某一个成员赋值后,它后面的成员会按照依次加1的规则,确定自己的整型值。
例えば
enum temp
{
temp1 = 2,
temp2,
……
temp10 = 20,
temp11,
};
temp2 に対応する整数値は 3 です。temp11 に対応する整数値は 21 です。
4 構造体と共用体
4.1 構造
構造体タイプを使用すると、データ要素の個々の不同类型的数据
項目を全体に集約できます。構造体型の宣言形式は次のとおりです。
struct 结构体名
{
成员列表
}变量名列表;
定义结构体时,不能直接赋值。
割り当て方法はこちら
#include<stdio.h>
struct student
{
char *name;
char *number;
int age;
}student;
int main()
{
// 给结构体成员赋值
student.name = "ertu";
student.number = "20230711";
student.age = 23;
printf("**************************\n");
printf("姓名:%s\n",student.name);
printf("学号:%s\n",student.number);
printf("年龄:%d\n",student.age);
printf("**************************\n");
return 0;
}
操作の結果は次のとおりです
也可以定义结构体数组,存储多个相同结构的信息。
#include<stdio.h>
struct student
{
char *name;
char *number;
int age;
}student[10];
int main()
{
// 给结构体成员赋值
student[0].name = "ertu";
student[0].number = "20230711";
student[0].age = 23;
printf("**************************\n");
printf("姓名:%s\n",student[0].name);
printf("学号:%s\n",student[0].number);
printf("年龄:%d\n",student[0].age);
// 给结构体成员赋值
student[1].name = "yingting";
student[1].number = "20230711";
student[1].age = 20;
printf("**************************\n");
printf("姓名:%s\n",student[1].name);
printf("学号:%s\n",student[1].number);
printf("年龄:%d\n",student[1].age);
printf("**************************\n");
return 0;
}
出力は次のとおりです
4.2 結合
共用体は次のように定義されます
union 共用体名
{
成员列表
}变量名列表;
結合体は構造体と似ているため、ここでは繰り返しません。
5. 展開する
5.1 構造体のメモリ割り当て
構造体がメモリを割り当てる場合、次のルールがあります (環境によって異なる場合があります。ここでは VC6.0 のみです)。
- 構造内で最大のバイト数を占めるデータ型のバイト数を単位としてメモリを開放します。
- バイトアライメント
5.1.1 構造内で最も多くのバイトを占めるデータ型のバイト数単位でメモリを割り当てます。
つまり、構造体のサイズは、その中の最大バイト数のデータ型の整数倍になります。ここに例があります
#include<stdio.h>
struct temp
{
int i;
char j;
}temp;
int main()
{
printf("结构体所占字节数:%d\n",sizeof(temp));
printf("i的地址:%p j的地址:%p\n",&temp.i,&temp.j);
return 0;
}
出力は次のとおりです
構造内で最大のバイト数を持つデータ型は int で、4 バイトを占めます。したがって、メモリを割り当てるときは 4 バイト単位で行ってください。char 型は 1 バイトしか占有しませんが、それでも 4 バイトのメモリが割り当てられます。
如果结构体成员中出现了数组,并不把数组看作整体来计算字节数,而是看数组的数据类型。
つまり、char j[5] が定義されていても、メモリ確保時には長さ 5 バイトのデータ型とはみなされません。例を見ることができます
#include<stdio.h>
struct temp
{
short int i;
char j[5];
}temp;
int main()
{
printf("结构体所占字节数:%d\n",sizeof(temp));
printf("i的地址:%p j的地址:%p\n",&temp.i,&temp.j[0]);
return 0;
}
出力は
如果结构体成员中出现指针变量,那么会以8字节为单位,开辟内存。
例を見ることができます
#include<stdio.h>
struct temp
{
short int i;
char *j;
}temp;
int main()
{
printf("结构体所占字节数:%d\n",sizeof(temp));
printf("i的地址:%p j的地址:%p\n",&temp.i,&temp.j);
return 0;
}
出力は次のとおりです
5.1.2 バイトアラインメント
簡単に言うと、変数を格納するアドレスは、変数が占有するバイト数の倍数でなければなりません。バイト アラインメントは、空間と時間を交換する戦略であり、CPU によるデータ読み取りの効率を向上させることができます。
5.1.3 構造体内の入れ子構造
例を見てみましょう
#include<stdio.h>
struct temp1
{
char m;
char *n;
}temp1;
struct temp
{
int i;
char j;
struct temp1 k;
}temp;
int main()
{
printf("结构体temp1所占字节数:%d\n",sizeof(temp1));
printf("结构体temp所占字节数:%d\n",sizeof(temp));
printf("i的地址:%p j的地址:%p\n",&temp.i,&temp.j);
printf("m的地址:%p n的地址:%p\n",&temp1.m,&temp1.n);
return 0;
}
出力は次のとおりです
このことから、入れ子構造がある場合、2 つの構造が別々にスペースを割り当てることがわかります。領域を割り当てる単位は、それぞれに含まれる構造体メンバのうち、最も多くのバイトを占めるデータ型のバイト数です。最終的な構造体が占めるメモリ サイズは、2 つの構造体が占めるメモリ サイズの合計です。
5.2 ユニオンメモリの割り当て
メモリを割り当てる場合、共用体は構造体とは異なります共用体所占内存大小等于其成员中所占内存最大的成员的字节数
。例を見ることができます
#include<stdio.h>
union temp
{
int i;
char j;
}temp;
int main()
{
printf("结构体temp所占字节数:%d\n",sizeof(temp));
printf("i的地址:%p j的地址:%p\n",&temp.i,&temp.j);
return 0;
}
出力は
可以看到,两个成员的起始地址相同
。i と j は次のように格納されます
5.3 データ型変換
キャスト形式は、
(目标数据类型)变量/表达式
データ型の変換は、計算時のデータ型の統一だけでなく、LCD で変数を表示する際にも重要な役割を果たします。たとえば、リアルタイムの温度を LCD に表示したいとします。
温度モジュールは温度値を検出しており、データ型は float 型です。LCDに「Temper:26」と表示する必要があります。これは、「Temper:」と温度モジュールで検出した周囲温度を直接パッケージ化し、sprintf関数を使って文字列に変換してLCDに表示するものです。
unsignde char string[20];
sprintf((char*)string,"Temper:%.1f\r\n",temper);
5.4 typedef
typedef を使用してデータ型に新しい名前を付けます。たとえば、STM32 の開発時に使用した u8、u16 などはすべて typedef で定義されています。
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;