[toc]
问题:
1 如何定义10个整型元素的数组?
int nArr[10] = {4,3,1,4,6,7,5,4,3};
2 以下定义数组的方式对吗?
int n=10;
int a[n];
不对的,因为数组的长度必须是常量。
3 int Ar[ ] = {1,2,3,4,5};这个数组,数组长度是多少??
当定义数组的时候,不指定长度,会根据初始化的元素个数,自动推断出数组的长度。
char buf[] = “hello”; 数组长度多长???
长度是6
假如 int Arr[];这么写可以吗??
当我们定义数组省略长度的时候,必须初始化的。
4 如何能够判断一个数是否被4整除
int nNum = 0;
scanf_s(“%d”,&nNum);
if(nNum%4 == 0)
{
printf(“能够被4整除”);
}
5 常用的字符串处理函数有哪些????
strlen 求字符串长度
strcpy_s 拷贝字符串
strcat_s 拼接字符串
strcmp 比较字符串是否相等
6
char buf[20] = “hello”;
strlen(buf);得到的是字符个数,不包括0,结果是5
sizeof(buf);得到的是数据所占内寸,结果是20
_counof(buf);得到的是数组元素总个数,结果是20
int buf2[10] = {1,2,3,4,5};
strlen(buf2);错误的,strlen只能求字符个数
sizeof(buf2);是40
_countof(buf2);是10
三大循环结构:
while()
{
}
int main()
{
int counter = 0; //定义变量,相当于计数
while (counter < = 100) //判断条件
{
printf("counter = %d\n", counter);
counter++; //每执行一次循环体自加一次
}
return 0;
}
do
{
}while();
int main()
{
int counter = 0; //定义变量,相当于计数
do
{
printf("counter = %d\n", counter);
counter++; //每执行一次循环体自加一次
} while (counter <= 100); //判断条件
return 0;
}
for(;;)
{
}
for (int counter = 0; counter <= 100; counter++)
{
printf ("counter = %d\n", counter);
}
总结
1 即便你的循环体只有一句话,也要用大括号包裹起来。
错误示例:
int main()
{
int nNum = 0;
while (nNum <= 100)
printf("%d", nNum);
nNum++;
return 0;
}
2 不要在循环语句的后面加分号
int main()
{
int nNum = 0;
while (nNum <= 100);
{
printf("%d", nNum);
nNum++;
}
return 0;
}
3 while和for可以相互替换
比如while的输出0到100.
int main()
{
int nNum = 0;
while (nNum <= 100)
{
printf("%d", nNum);
nNum++;
}
return 0;
}
for模仿while
int main()
{
int nNum = 0;
for (;nNum <= 100;)
{
printf("%d", nNum);
nNum++;
}
return 0;
}
由于for语句,有第一句话,可以定义变量,第三句话,可以改变渐变量,所以一般预先知道循环次数(预先就能够用渐变量控制循环次数的时候)我们会使用for
while一般用于事先不知道循环多少次。
4 关于for语句的三句话:
for的第一句:初始化一个渐变量量
for的第二句: 循环的判断跳进啊
for的第三句:一般是,渐变量的变化。
a. for的三句话,都可以不写,不写的话,就是无限循环
b. 如何能够方便的理解3条语句的执行顺序
int main()
{
int nNum = 0;
for (printf("语句1\n"); printf("语句2\n"); printf("语句3\n"))
{
printf("循环体\n");
}
return 0;
}
练习题:
1 我有一个数组是int nArr[10] = {1,2,3,4,5,6,9,8,7,0};
请使用循环结构,输出数组中的每一个值。
int main()
{
//遍历操作,全部输出
//遍历,就是每一个元素访问一次
int nArr[10] = { 1,2,3,4,5,6,9,8,7,0 };
for (int i = 0; i < 10; i++)
{
printf("%d ", nArr[i]);
}
return 0;
}
2 请在数组中寻找7这个数值,然后输出它所在的位置
int main()
{
//遍历操作,全部输出
//遍历,就是每一个元素访问一次
int nArr[10] = { 1,2,7,4,5,6,9,8,3,0 };
for (int i = 0; i < 10; i++)
{
if (nArr[i]==7)
{
printf("7这个元素所在的位置为%d", i);
break;
}
}
return 0;
}
3 从键盘输入一个数,判断这个数在不在数组中,在的话输出yes,不在的话输出no
方法1:
int main()
{
//遍历操作,全部输出
//遍历,就是每一个元素访问一次
int nArr[10] = { 1,2,7,4,5,6,9,8,3,0 };
int nNum = 0;
printf("please input a number:");
scanf_s("%d",&nNum);
int i = 0;
//当i自增到10的时候,就说明数组中,没有这个数
//此时的条件,也不满足了,就退出循环了
for ( ;i < 10; i++)
{
if (nArr[i]== nNum)
{
break;
}
}
//i不为10就说明找到了
if (i!=10)
{
printf("yes");
}
//i为10就说明没找到
else
{
printf("no");
}
return 0;
}
方法2:
int main()
{
//遍历操作,全部输出
//遍历,就是每一个元素访问一次
int nArr[10] = { 1,2,7,4,5,6,9,8,3,0 };
int nNum = 0;
printf("please input a number:");
scanf_s("%d",&nNum);
int nFind = 0;
for (int i = 0;i < 10; i++)
{
if (nArr[i]== nNum)
{
nFind = 1;
break;
}
}
if (nFind==1)
{
printf("yes");
}
else
{
printf("no");
}
return 0;
}
关于循环结构的调试问题:
在循环结构中,由于循环的次数有可能会很多,那么调试就不方便,使用条件断点能够比较快速的找到错误的位置。
练习:打印这个图形
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
int main()
{
//1
//1 2
//1 2 3
//1 2 3 4
//1 2 3 4 5
//1 2 3 4 5 6
//1 2 3 4 5 6 7
//1 2 3 4 5 6 7 8
//1 2 3 4 5 6 7 8 9
//for (int i = 1; i < 2; i++)
//{
// printf("%d ", i);
//}
//printf("\n");
////...
//for (int i = 1; i < 8; i++)
//{
// printf("%d ", i);
//}
//printf("\n");
//for (int i = 1; i < 9; i++)
//{
// printf("%d ", i);
//}
//printf("\n");
//for (int i = 1; i < 10; i++)
//{
// printf("%d ", i);
//}
//printf("\n");
for (int n = 2; n <= 10; n++)
{
for (int i = 1; i < n; i++)
{
printf("%d ", i);
}
printf("\n");
}
//int n = 1;
//while (n<10)
//{
// printf("%d ", n);
// n++;
//}
//int n = 1;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
//n++;
//printf("%d ", n);
return 0;
}
int main()
{
//for (int i = 1; i <= 8; i++)
//{
// printf("%d*%d=%d ", i, 8, i * 8);
//}
//printf("\n");
//for (int i = 1; i <= 8; i++)
//{
// printf("%d*%d=%d ", i, 8, i * 8);
//}
//printf("\n");
//for (int i = 1; i <= 9; i++)
//{
// printf("%d*%d=%d ",i, 9, i * 9);
//}
//printf("\n");
for (int n = 1; n <=9; n++)
{
for (int i = 1; i <= n; i++)
{
printf("%d*%d=%d ", i, n, i * n);
}
printf("\n");
}
}
鸡兔同笼的问题:
问:有一群鸡和一群兔子在一个笼子里,总共有脚110个,头40个,请问鸡和兔子分别多少只。
int main()
{
int nCount = 0;
//假设鸡是i只
//假设兔子是j只
for (int i = 0; i < 40; i++)
{
for (int j = 0; j < 40; j++)
{
if (i+j==40&&2*i+4*j == 110)
{
printf("鸡是%d只 兔子是%d只\n", i, j);
}
nCount++;
}
}
printf("我们循环了%d次解决了这个问题\n",nCount);
return 0;
}
我们也可也通过break降低循环次数
int main()
{
int nCount = 0;
//假设鸡是i只
//假设兔子是j只
int nFind = 0;
for (int i = 0; i < 40; i++)
{
for (int j = 0; j < 40; j++)
{
if (i+j==40&&2*i+4*j == 110)
{
printf("鸡是%d只 兔子是%d只\n", i, j);
nFind = 1;
break;
}
nCount++;
}
if (nFind==1)
{
break;
}
}
printf("我们循环了%d次解决了这个问题\n",nCount);
return 0;
}
我们可以使用1重循环解决这个问题
因为如果鸡有i只,那么兔子就是40-i
如果兔子有i只,那么鸡就是40-i
int main()
{
int nCount = 0;
//假设鸡是i只
//假设兔子是j只
for (int j = 0; j < 27; j++)
{
if (j*4+(40-j)*2==110)
{
printf("鸡是%d只 兔子是%d只\n", 40-j,j);
break;
}
nCount++;
}
printf("我们循环了%d次解决了这个问题\n",nCount);
return 0;
}
编译预处理
以#开头的命令,称之为编译预处理命令。
我们这次课程,讲两个预处理:
include
有两种用法:
include < 头文件名> :找文件的方式,去系统目录中寻找
include “头文件名”:找文件的方式,先在本工程目录中寻找,找不到,去系统目录寻找
一般系统的头文件,比如stdio.h stdlib.h conio.h 用<>。
一般自己写的头文件,用””去包含。
#define
也称之为宏
宏有两种用法:有参宏和无参宏
先说无参宏
#define A 10
int main()
{
//A = 11; 不可以的,A是常量
int m = 0;
m = A;
printf("%d", A);
return 0;
}
我们为什么要用无参宏:
好处1:便于修改
好处2:提高程序的可读性
#define PI 3.1415926
int main()
{
double r;
printf("请输入一个半径");
scanf_s("%lf",&r);
//假设有1000个地方用到了3.14这个常量
printf("周长为:%lf", 2 * PI*r);
//十万行代码
printf("面积为:%lf", PI*r*r);
//
//....
return 0;
}
有参宏
#define PI 3.14
#define GETL(m) 2*PI*m
int main()
{
double r=10.0;
printf("请输入一个半径");
//scanf_s("%lf",&r);
//假设有1000个地方用到了3.14这个常量
//printf("周长为:%lf", 2 * PI*r);
printf("周长为:%lf", GETL(r) );// 2*PI*r
//十万行代码
printf("面积为:%lf", PI*r*r);
//
//....
return 0;
}
好处1:精简了代码,也会便于修改
好处2:提高了可读性
有参宏中的一个坑:
#define PI 3
#define GETL(m) 2*PI*m
int main()
{
double r=10.0;
printf("请输入一个半径");
//scanf_s("%lf",&r);
//假设有1000个地方用到了3.14这个常量
//printf("周长为:%lf", 2 * PI*r);
printf("周长为:%lf", GETL(r+1) );//按照我们的想法应该是2*PI*11,但并不是
//2 * PI*r + 1 得到的结果是61
//十万行代码
//
//....
return 0;
}
define M(x) x*x
printf(“%d”,M(8));
printf(“%d”,M(4+4));//4+4*4+4 结果是24
二维数组:
定义:
int main()
{
int nArr1[3][4] = { 1,2,3,4,5,6,7,8,9 };
//1,2,3,4
//5,6,7,8
//9,0,0,0
int nArr2[3][4] = { {1,2,3},{4,5,6,7},{8,9} };
//1, 2, 3, 0
//4, 5, 6, 7
//8, 9, 0, 0
int nArr3[][4] = { 1,2,3,4,5,6,7,8,9 };
//1,2,3,4
//5,6,7,8
//9,0,0,0
printf("%d", nArr3[1][2]);//输出7
scanf_s("%d", &nArr3[0][3]);//向下标为0 3的元素输入数据
return 0;
}
int main()
{
int nArr1[3][4] = { 1,2,3,4,5,6,7,8,9 };
int nArr2[12] = { 1,2,3,4,5,6,7,8,9 };
return 0;
}
左边是一维数组的内存,右边是二维数组的内存。
我们通过观察,可以发现他们是一样的。
我们什么时候会使用一维数组??
当我们存储的大量数据,需要分组的时候。
比如存储100个人的年龄。这一组数据存储的都是年龄
我们什么时候要使用二维数组呢???
就是数据在分组的同时,又需要分组
int nAge[3][100];
nAge[0][0~100]; 保存的都是小孩
nAge[1][0~100]; 保存的都是青年
nAge[2][0~100]; 保存的都是老年
地图
x,y
打印杨辉三角
int main()
{
int Arr[10][10] = { 0 };
//第0列都设置为1,斜着的都设置为1
for (int i = 0; i < 10; i++)
{
Arr[i][0] = 1;
Arr[i][i] = 1;
}
//给每一额元素赋值
for (int i = 2; i < 10; i++)
{
for (int j = 1; j < 10; j++)
{
Arr[i][j] = Arr[i-1][j] + Arr[i-1][j-1];
}
}
//遍历输出一下
for (int i = 0; i < 10; i++)
{
for (int j = 0; j <= i; j++)
{
printf("%5d", Arr[i][j]);
}
printf("\n");
}
return 0;
}
我们可以通过内存窗口,便捷的查看二维数组的内容变化。