C语言第四天

问题

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;
}

我们可以通过内存窗口,便捷的查看二维数组的内容变化。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值