一.用循环语句写一个数组
例:6.1
#include <stdio.h>
int main()
{
//0--9
int arr[10]; //没有初始化的数组元素自动赋值为0
int i = 0;
for (i = 9; i >= 0; i--) //从9——0
{
arr[i] = i;
}
for (i = 9; i >= 0; i--)
{
printf("%d\n", arr[i]);
}
return 0;
}
运行结果:
注:
1.数组的元素编号问题
数组的元素编号是从0开始的
例:arr[3] = {1, 2, 3}
第0个元素值为1,第1个元素值为2,第三个元素值为3
二.用数组和循环写一个斐波那契数列
例:6.2
//1 1 2 3 5 8 13 21...
#include <stdio.h>
int main()
{
int fib[20] = {1, 1};
int i = 0;
for (i = 1; i <= 18; i++) //这里需要注意的是数组是从 0 开始的 fib[0]
{
fib[i + 2] = fib[i + 1] + fib[i]; //第三项等于前两项之和
}
for (i = 1; i <= 20; i++) //遍历打印前20项
{
printf("%d\n", fib[i]);
}
return 0;
}
运行结果:
//这里可以看到,由于循环条件出错,前两项出错,后18项不对
代码逻辑:
1.初始化一个数组,元素个数定为20,但只初始化0、1两个元素 且都为1
2.利用for循环,省去依次定义的麻烦。数组的优势正是在于随时可以调用
3.for (i = 1; i <= 18; i++) //这里需要注意的是数组是从 0 开始的 fib[0]
写循环时,为了方便看。我直接 i = 1; i <= 18 以此来循环后18个数组元素,但是由于数组元素是从0开始的,导致出错。
具体细节是:i = 1 fib[i + 2] = fib[i + 1] + fib[i]; // i 应该从 第0个元素开始
当 i = 1时 fib[1] = 1;
fib[2] = 0; //数组越界,fib[2] = 0(系统默认)
fib[i + 2] = fib[i + 1] + fib[i]; fib[3] = fib[2] + fib[1];
fib[3] = 0 + 1 =1
标准代码:
#include <stdio.h>
int main()
{
int fib[20] = {1, 1};
int i = 0;
for (i = 0; i < 18; i++) //这里需要注意的是数组是从 0 开始的 fib[0]
{
fib[i + 2] = fib[i + 1] + fib[i]; //第三项等于前两项之和
}
for (i = 0; i < 20; i++)
{
printf("%d\n", fib[i]);
}
return 0;
}
运行结果:
//打印的时候也要从 第0个元素开始打印
注:
不止是循环,打印的时候也要从 第0个元素开始打印
三.冒泡排序
例:6.3
#include <stdio.h>
int main()
{
int arr[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
int i = 0;
int j = 0;
int temp = 0;
for (i = 0; i < 9; i++) //确定冒泡排序的趟数
{
//一趟冒泡排序的过程
for (j = 0; j < 9 - i; j++) //确定一趟冒泡排序比较的对数
{
if (arr[j] > arr[j + 1]) //如果前一项大于后一项,交换次序
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
printf("一共比较了%d次\n", n);
for (i = 0; i < 10; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}
运行结果:
代码逻辑:
1.外层循环先确定比较的趟数 //for (i = 0; i < 9; i++)
2.一趟冒泡排序的过程,确定一趟冒泡排序比较的对数 //for (j = 0; j < 9 - i; j++)
3.如果前一项大于后一项,交换次序
if (arr[j] > arr[j + 1])
{
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
三.数组的地址与存储方式
#include <stdio.h>
int main()
{
int arr[10] = { 0 }; //以一维数组为例
int i = 0;
for (i = 0; i < 10; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0;
}
运行结果:
注:
1.数组的存储方式
&arr[2] = 000000CF5B2FFAC0(十六进制)
&arr[3] = 000000CF5B2FFAC4
&arr[4] = 000000CF5B2FFAC8
可以看出 08 0C 10 之间差值都为 4(int 类型)
因此数组在内存中的存储方式 是 连续存放
四.矩阵的转置
例:6.2
#include <stdio.h>
int main()
{
int a[2][3] = { 1, 2, 3, 4, 5, 6 }; //以2*3 转置 3*2 的矩阵为例
int b[3][2] = { 0 };
int i = 0;
int j = 0;
for (i = 0; i < 2; i++)
{
for (j = 0; j < 3; j++)
{
b[j][i] = a[i][j]; //交换行与列
}
}
for (i = 0; i < 3; i++)
{
for (j = 0; j < 2; j++)
{
printf("%d ", b[i][j]);
}
printf("\n"); //在每次行打印结束跳出循环时,打印一个换行符
}
return 0;
}
运行结果:
代码逻辑:
1.交换 行 和 列 // b[j][i] = a[i][j];
b[0][0] = a[0][0]
b[1][0] = a[0][1]
b[2][0] = a[0][2]
五.求出矩阵中值最大的元素的值,以及其所在的行号和列号
例:6.3
#include <stdio.h>
int main()
{
int arr[3][4] = { 0 };
int i = 0;
int j = 0;
int x = 0;
int y = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
scanf("%d", &arr[i][j]);
}
}
int max = arr[0][0]; //设定一个最大值
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
if (arr[i][j] > max) //迭代
{
max = arr[i][j];
x = i;
y = j;
}
}
}
printf("max = %d\nx = %d\ny = %d", max, x, y);
return 0;
}
代码逻辑:
一.遍历所输入的矩阵,将它与设定的最大值作比较,从而迭代最大值
1.输入问题
scanf("%d", &arr[i][j]);
2.迭代问题
if (arr[i][j] > max) //比较遍历的值与设定最大值的大小
{
max = arr[i][j]; //如果遍历的值比设定的值大,那么替换它
x = i; //并交换下标
y = j;
注:
六.字符与字符串结束标志
#include <stdio.h>
#include <string.h>
int main()
{
char arr1[] = { '7', 'b','\0' ,'c' }; //%s打印字符串
char arr2[] = "abc\0de";
int len1 = strlen(arr1); //strlen()函数用于计算给定的字符或字符串
int len2 = strlen(arr2);
printf("%d\n", len1); //打印长度
printf("%d\n", len2);
printf("%s\n", arr1); //打印字符串
printf("%s\n", arr2);
return 0;
}
运行结果:
注:
1.%s打印字符串
2. \0 作为结束标志
想用字符数组来实现与字符串数组相同的功能,需要在最后面加上 '\0' 作为结束标志,但“\0”本身不占数组的内存
3.strlen()函数用于计算给定的字符或字符串的长度
需要调用 #include <string.h> 库
七.数组中的一些常用的函数
gets——输入字符串函数
puts——输出字符串函数
strcat——连接字符串函数
strcpy——复制字符串函数
strncpy——复制字符串函数(限制字符个数)
strcmp——字符串比较函数
strlen——字符串长度测定函数
strlwr(转小写)、strupr(转大写) ——字符串大小写转换函数
1.scanf与get的异同
运行结果 :
注:
1.scanf检测到空格自动结束,而gets不会
2.strcat——连接字符串函数
运行结果:
注:
1.strcat()函数的作用
arr1 = arr1 + arr2
arr1最后的 \0 被strcat()函数自动省略了
具体情况:
Hello\0World\0 //HelloWorld\0
2.使用strcat()函数的要求
arr1的空间足够大
3.字符串复制函数
3.1 strcpy——字符串复制函数
运行结果:
注:
1.strcpy函数的作用
strcpy(字符串1,字符串2) //将字符串2 复制 到字符串1中
3.2 strncpy——字符串复制函数(限定长度)
运行结果:
注:strncpy函数的作用
能够指定复制的字符个数
World——Wollo //指定两位,从前往后复制
4.strcmp——字符串比较函数
运行结果:
注:
1.比较的结果判定(1、0、-1)
两个数组的比较是根据字母的ASILL值
arr1和arr2的比较为例子
abcae abce
1.abc = abc //从第一个字符开始比较ASILL值的大小
2.a < e
arr1 < arr2 结果为 -1
同理:arr3 = arr4,结果为0
5.strlen——字符串长度测定函数
运行结果:
6.strlwr(转小写)、strupr(转大写) ——字符串大小写转换函数
运行结果:
注:
1.编译器的不同可能导致库函数的实现不同
课本给出strlwr、strupr两个函数并且需要调用#include <string.h>库
但在visual中_strlwr、_strupr才是可用的函数,并且不需要调用#include <string.h>库
八.数组例子
例6.8:输入一行字符,统计其中有多少个单词,单词之间用空格分隔开
#include <stdio.h>
int main()
{
char arr[] = "i am a student";
int word = 0;
int i = 0;
int num = 0;
//gets(arr); //也可用gets函数读入数组元素
for (i = 0; arr[i] != '\0'; i++) //遍历arr[i],直至遇到\0结束
{
if (arr[i] == ' ') //如果遇见空格,那么标记word = 0
{
word = 0;
}
else if (word == 0) //如果没遇见空格,且word = 0,word = 1,num++
{
word = 1;
num++;
}
}
printf("%d", num);
return 0;
}
运行结果:
代码逻辑:
一.通过遍历数组arr中的所有元素构成外循环,当遍历到\0时,结束循环
for (i = 0; arr[i] != '\0'; i++)
二.如果遇见空格,那么标记 word = 0
if (arr[i] == ' ') //判断条件一
{
word = 0;
}
三.如果i对应的元素不是空格,且word = 0,那么令 word = 1,num++
else if (word == 0) //判断条件二
{
word = 1;
num++;
}
注:
1.在第一次循环中,直接进入else if,word = 1,直至第一个空格的出现
2.如果i对应的是一个字母,那么判断条件一将不会执行,因为此时word的值一直为1,直到遇见下一个空格word重新赋值为0,再次循环判断,直至遍历到\0,结束循环
例6.9:有三个字符串,找出其中的“最大”者
#include <stdio.h>
#include <string.h>
int main()
{
char arr[3][20];
char str[20];
int i = 0;
for (i = 0; i < 3; i++)
{
gets(arr[i]);
}
if (strcmp(arr[0], arr[1]) > 0) //比较第一行和第二行
strcpy(str, arr[0]); //如果第一行大于第二行,用str存储第一行
else //否则用str存储第二行
strcpy(str, arr[1]);
if (strcmp(arr[2], str) > 0)
strcpy(str, arr[2]);
printf("max = %s", str);
return 0;
}
运行结果:
代码逻辑:
一.通过函数比较大小和复制函数来迭代最大值