目次
配列
配列: 同じタイプのデータの線形コレクション。次の配列のテーブルは 0 からカウントを開始し、最大長は配列の数 - 1 になります。
1 次元配列: 配列内の各要素の型は同じで、メモリ アドレスは連続しており、配列の各要素には 0 から番号が付けられます。
int main()
{
//定义一个数组为qq,指定长度为12个
int qq[12], index;
for (index = 0; index < 11; index++) {
scanf("%d", &qq[index]); //逐个输入手机号
}
//输出手机号
printf("手机号是 \n");
for ( index = 0; index < 11; index++)
{
printf("%d", qq[index]);
}
return 0;
}
一维数组的3种初始化方式:
int a[3] = { 1,3,2 };//指定数组长度并把每个位置都赋值
int b[] = { 3,4,4,5 };//不指定数组长度,自动依据当前元素大小计算数组长度
int c[10] = { 12,44 };//指定数组长度,但是只把部分位置赋值,其余位置默认以0填充
2 次元配列: 特殊な 1 次元配列。各配列要素は配列です。
2 次元配列の 4 つの初期化方法:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define PI 3.1415
int main()
{
int a[2][2] = { 1,3,2 ,3};//指定数组长度并把每个位置都赋值;
int b[][2] = { 3,4,4,5 };//为每个数组赋值,省略行下标,指明列下标;
int c[2][2] = { {12,44 },{33,22} };//分行给数组元素赋值
int d[2][2];
a[0][0] = 12; //直接对数组元素赋值
a[0][1] = 19;
//遍历数组
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
printf("%d ,", a[i][j]);
}
}
return 0;
}
字符数组
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define PI 3.1415
int main()
{
char a[5]; //定义字符数组
//字符数组的几种初始化方式
a[0] = 'a';
a[1] = 'b'; //引用数组元素并给其赋值
char b[2] = { 's','s' };//逐个字符赋值给每个数组元素
char c[] = { 'q','q' };//定义数组的同时给其初始化
char d[] = { "hello" };//利用字符串赋值
//字符数组的输入和输出可以使用两种格式字符: "%c" ,"%s"
printf("%s", d); //若使用字符串给字符数组赋初值的话,可以直接使用
//若是使用数组的形式给字符数组赋值的话,那么则需要用循环的形式来遍历字符。
for (int i = 0; i < 2; i++)
{
printf("%c", b[i]);
}
//注意: 字符数组在内存中,编译系统会自动给字符数组的末尾加一个标志符号 "\0" ,所以其字符的实际长度是包含结尾标志的。
//计算字符数组的长度
int length = 0; //记录数组长度
int index; //跟踪数组下标
for (index = 0; index < a[index] != '\0'; index++)
{
length++;
}
printf("字符数组的长度是: %d ", length);
return 0;
}
配列ソートアルゴリズム
配列は、順序付けされたデータのセットの組み合わせです。ここでの順序とは、配列要素自体の順序ではなく、メモリ内の連続した順序を指します。
1. 選択方法による並べ替え
原則: 毎回ソートする配列内の最大または最小の配列要素を検索し、その値を以前にソートされていない配列要素の値と交換します。最大値から最小値への並べ替えでは最大値が検索され、最小値から最大値への並べ替えでは最小値が検索されます。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#define PI 3.1415
int main()
{
int i, j;
int a[5]; //存储用户输入的数据
int temp;//表示最小的数组元素
int pos;//表示元素的位置
printf("请输入5个数字,为数组的元素赋值:/n");
for (int i = 0; i < 5; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
//使用选择排序法对数组元素从小到大排序
for (int i = 0; i < 4; i++) //表示前4个数组元素
{
temp = a[i];//假设当前元素为最小值
pos = i;//记录最小元素的位置
for ( j = i+1; j < 5; j++) //设置内层循环为5,表示剩下的未排序数组元素部分
{
if (a[j] < temp) { //如果后续的元素中有比前面设定的最小值还小
temp = a[j]; //重新设定最小值
pos = j;//修正最小元素的位置
}
}
//将最小的数组元素和当前排序次数对应的数组元素互换
a[pos] = a[i];
a[i] = temp;
}
//输出数组排序结果
printf("排序结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
return 0;
}
- バブルソート
原則: 配列内の 2 つの隣接する配列要素の値を毎回比較し、小さい方の数字を大きい方の数字の前に配置して、配列要素を小さい方から大きい方へ並べ替えます。毎回、大きい方の数字が優先されます。数値の前に小さい順に配列すると、配列を大きい順に並べ替えることができます。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int i, j;
int a[5]; //存储用户输入的数据
int temp=0;//表示最小的数组元素
printf("请输入5个数字,为数组的元素赋值:\n");
for (int i = 0; i < 5; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
//输出数组未排序前的结果
printf("排序结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
//使用冒泡排序法对数组元素从小到大排序
for (int i = 0; i < 5; i++) //表示后4个数组元素
{
for ( j = 4; j >=i; j--) //表示从最后一个元素开始向前循环
{
if (a[j] < a[j-1]) { //如果后一个数大于前一个数
//交换两个数组元素的值,如同冒泡
temp = a[j - 1];
a[j - 1] = a[j];
a[j] = temp;
}
}
}
//输出数组排序结果
printf("排序结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
return 0;
}
3、交換方法ごとに並べ替える
原則: 各桁を後続のすべての数値と 1 つずつ比較し、条件を満たすデータが見つかった場合はデータを交換します。
まず、最初の数値と後続のすべての数値を順番に比較し、その値より大きい(小さい)数値がある場合は、2 つの数値を交換します。
最後の数値まで他の数値を逆方向に比較し続けます。次に、2 番目の数値を使用してその後の数値と比較し、その値より大きい (小さい) 数値がある場合、2 つの数値が交換されます。最後の数値が比較されるまで、他の数値を逆方向に比較し続けます。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int i, j;
int a[5]; //存储用户输入的数据
int temp=0;//表示最小的数组元素
printf("请输入5个数字,为数组的元素赋值:\n");
for (int i = 0; i < 5; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
//输出数组未排序前的结果
printf("未排序的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
printf("\n");
//使用交换法对数组元素从小到大排序
for (int i = 0; i < 4; i++) //表示前4个数组元素
{
for ( j = i+1; j <5; j++) //表示后面的待比较数组元素
{
if (a[j] < a[i]) { //如果后一个数比前一个数小
temp = a[i]; //交换两个数组元素的值,使小数前移
a[i] = a[j];
a[j] = temp;
}}}
//输出数组排序结果
printf("排序后的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
return 0;
}
4、挿入仕分け
原則: データの一部を抽出し、前のデータ内の対応する位置を見つけて挿入し、並べ替えが完了するまで次のデータに進みます。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int i, j;
int a[5]; //存储用户输入的数据
int temp=0;//表示最小的数组元素
int pos;
printf("请输入5个数字,为数组的元素赋值:\n");
for (int i = 0; i < 5; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
//输出数组未排序前的结果
printf("未排序的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
printf("\n");
//使用插入法对数组元素从小到大排序
for (int i = 0; i < 5; i++) //表示后4个数组元素
{
temp = a[i];//设置插入值
pos = i - 1;
while ((pos>=0) && (temp<a[pos])) //内层循环,寻找插入值的位置
{
a[pos + 1] = a[pos]; //插入数值
pos--;
}
a[pos + 1] = temp;
}
//输出数组排序结果
printf("排序后的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
return 0;
}
5. バイナリソート(クイックソート)
原則: 中間値を選択し (プログラム内の配列の中央の要素の値を使用します)、次に中央の値より小さい要素を左側に配置し、中央の値より大きい要素を右側に配置します (特定の実装では、両側から検索し、背面の交換を見つけて、左側と右側のそれぞれに対して途中のソート プロセスを再帰的に使用します。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void CelerityRun(int left, int right, int Array[]);//申明折半查找法函数
int main()
{
int a[5]; //存储用户输入的数据
printf("请输入5个数字,为数组的元素赋值:\n");
for (int i = 0; i < 5; i++)
{
printf("a[%d]=", i);
scanf("%d", &a[i]);
}
//输出数组未排序前的结果
printf("未排序的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
printf("\n");
//使用折半法对数组元素从小到大排序
CelerityRun(0, 4, a);
//输出数组排序结果
printf("排序后的结果如下: \n");
for (int i = 0; i < 5; i++)
{
printf("%d \t", a[i]); //用制表符分割打印后的数组
}
return 0;
}
//定义函数实现
void CelerityRun(int left, int right, int Array[]) {
int i, j, middle, temp; //变量的含义是:i, j记录下标、middle中间值、temp记录临时变量,left, right记录左右元素
i = left;
j = right;
middle = Array[(left + right) / 2];//求中间值
do
{
while ((Array[i] < middle) && (i < right))//从左查找小于中间值的数
i++;
while ((Array[j] > middle) && (j > left))//从右查找大于中间值的数
j--;
if (i<=j)//如果找到一对值
{
temp = Array[i];//交换两个值
Array[i] = Array[j];
Array[j] = temp;
i++;
j--;
}
} while (i<=j);
//如果两边的下标交错,就停止(完成一次)
if (left<j)
{
CelerityRun(left, j, Array);//递归左半边
}
if (right >i)
{
CelerityRun(i, right, Array);//递归右半边
}
}
ソートアルゴリズムの比較:
- 選択ソート: シンプルで実装が簡単で、少数のソートに適しています。
- バブルソート: 比較的安定したソート方法で、ソートされる順序が整っていれば効果が高くなります。
- Exchange メソッドの並べ替え: 順方向のシーケンスでは最も速く、逆方向のシーケンスでは最も遅く、順序付けされたデータを並べ替える場合に最も効果的です。
- 挿入ソート:元データは基本的に順序付けされており、動作速度が高速です。
- バイナリ ソート: n が大きいほど高速になります。
配列の応用
1. 文字列を反転します
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int i;
char a[7] = { "hello!" }; //定义源字符串
char b[7] = { 0 };//定义存储反转后的字符串
int size = sizeof(a);//计算源字符串长度
//循环读取字符
for (int i = 0; i < 6; i++)
{
b[size - i - 2] = a[i]; //源字符串倒序存入反转字符串中
}
printf("输出源字符串: %s \n", a);
printf("反转后的字符串: %s \n", b);
return 0;
}
2, 输出系统日期和时间
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
int main()
{
struct tm *sysTime;
time_t nowTime;
time(&nowTime);//获取系统时间
sysTime = localtime(&nowTime);//转换为系统时间
printf("系统日期: %d-%d-%d \n", 1900+sysTime->tm_year,sysTime->tm_mon+1,sysTime->tm_mday);
printf("系统时间: %d:%d:%d \n", sysTime->tm_hour,sysTime->tm_min,sysTime->tm_sec);
return 0;
}
字符串的加密和解密
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main()
{
int result = 1;
int i;
int count = 0;
char Text[128] = {'\0'}; //定义一个明文字符串
char PassWord[128] = {'\0'}; //定义一个秘文字符串
while (1)//始终保持输入状态
{
if (result==1) //如果用户输入1,则加密密文
{
printf("请输入要加密的明文:\n");//输出提示信息
scanf("%s", &Text);
count = strlen(Text); //获取字符串的长度
for ( i = 0; i < count; i++)
{
PassWord[i] = Text[i] + i + 5; //设置加密字符
}
PassWord[i] = '\0';//设置字符串结束标记
printf("加密后的密文是:%s \n", PassWord);
}
else if (result==2) //如果用户输入2,解密字符串
{
count = strlen(Text); //获取字符串的长度
for (i = 0; i < count; i++)
{
Text[i] = PassWord[i] -i - 5; //设置解密字符
}
Text[i] = '\0';//设置字符串结束标记
printf("解密后的明文是:%s \n", Text);
}
else if (result==3) //如果用户输入3,则退出系统
{
break;
}
else
{
printf("请输入命令符:\n");
}
printf("输入1加密明文,输入2解密密文,输入3退出系统 \n");
printf("请输入命令符:\n");
scanf("%d", &result);
}
return 0;
}
2つの機能
関数はプログラムの基本単位であり、関数にはプログラムの実行可能コードが含まれます。通常、プログラムは関数ごとにサブルーチンを実装し、さらにサブルーチンによってモジュール関数を実装し、それぞれのモジュール関数がプログラムを構成します。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int sum(int a,int b); //申明函数,并且有两个形参a和b
int sum(int a,int b) { //定义函数,其基本构成为: 返回值类型 函数名称 (函数参数或者为空){ 函数体 }
return a + b; //return的作用有: 退出函数并返回程序的调用处; 返回一个值供主调函数使用。
}
//定义一个内部函数:该函数只能被所在的源文件使用,内部函数又称为静态函数
//内部函数定义
static int add(int a, int b) { return a + b; }
int main()
{
//调用函数时,填入实参传递给函数
int result = sum(12, 334);
printf("%d \n", result);
/*
* 可作为函数参数的类型有:
基本类型:int,double,float, char,
数组元素:数组名称[下标],这中方式和普通的参数传递差不多
数组名称:这种方式传递的是数组中第一个元素的地址,
*
*
* 函数的嵌套调用: 在一个函数中调用另外一个函数
* 函数的递归调用: 函数自身调用自身的写法
*/
return 0;
}
外部函数的使用步骤:
1,先在demo.c源文件中定义函数 Add
#include<stdio.h>
//定义一个外部函数:可以被其他源文件调用的函数
extern int Add(int a, int b) { return a + b + 100; }
在Demo2.c中使用
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
extern int Add(int a, int b);//使用外部文件定义的函数,首先需要声明
int main()
{
printf("%d", Add(12,222));
return 0;
}
局部变量和全局变量
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//全局变量: 定义在所有函数外部的变量,全局变量不属于某个函数,而是属于整个源文件
int a = 1000;
//使用extern关键字修饰全局变量,使其他源文件也能够使用该变量
extern int b = 122;
int main()
{
//当发生局部变量重名时,内层作用域中的变量将屏蔽外层作用域中的同名变量,直到结束内层作用域为止。
int a = 10;//a为局部变量,自己距离自己最近的大括号内有效(在main函数的大括号内有效)
return 0;
}
函数应用
数学函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h> //数学计算函数头文件
int main()
{
int intABS = abs(-12); //求一个负数的绝对值
int intLabs= labs(-1223434L); //求一个长整型数的绝对值
int intFlabs = fabs(-234.22);//求实型数的绝对值
int intSin = sin(0.5);//求解正弦
int intCos = cos(0.4);//求解余弦
int intTan = tan(0.8);//求解正切
printf("%d, %d, %d , %d, %d, %d", intABS, intLabs, intFlabs, intSin, intCos, intTan);
return 0;
}
字符函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<ctype.h> //字符函数头文件
int main()
{
char c = 'h';
int alpha = isalpha(c);//判断该字符是否是字母,如果是则返回非0值
int Digit = isdigit(c);//判断该字符是否是数字,如果是则返回非0值
int num = isalnum(c);//判断是否是字母或者数字,如果是则返回非0值
printf("%d, %d, %d ", alpha, Digit, num);
return 0;
}
字符串处理函数
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h> //字符串处理头文件
int main()
{
char a[10] = { "hello" };
char b[10] = {};
strcpy(a, b);//将符串a复制到字符串b中
strcat(a, b);//将字符串a连接到字符串b的末尾
strcmp(a, b);//比较两个字符串,若相同返回0,若a>b返回值为正数,若a<b返回值则为负数
strupr(a);//小写转换为大写
strlwr(b);//将大写转换为小写
strlen(a);//获取字符串的长度
return 0;
}