目录
●getchar\putchar
在开始之前先介绍一下 getchar\putchar ,意思与 scanf 和 printf 相近,看名字就知道。不过有所不同的是前者一次只能操作一个字符。
我们先来看一段代码:
int main()
{
char input[20] = { 0 };
printf("输入密码: ");
scanf("%s", input);
printf("请确认密码(Y/N):");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
可以看到 如果输入 abcde 会直接显示else的结果
注意:此时输入abcde后,按下回车键会输入一个\n,此时getchar却只能识别到从键盘输入的abcde,而\n却留在了缓存区,\n进入if语句直接识别为else,代码没有达到我们想要的效果。
那该怎么做呢?我们可以把\n再用一个getchar给输入,那么代码就变成了这样子:
int main()
{
char input[20] = { 0 };
printf("输入密码: ");
scanf("%s", input);
getchar();
printf("请确认密码(Y/N):");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
此时输入abcde就可以正常输出Y/N,但如果输入abcde hehe,此时一个getchar只能把空格输入,缓存区中仍然有其他的字符。
此时,我们在其中加入一个while循环,将缓存区中所有的字符都输入,一直到\n才停止。这样子就能够使不论输入什么,都能保证ch输入的都是Y/N。
int main()
{
char input[20] = { 0 };
pri*/ntf("输入密码: ");
scanf("%s", input);
int a = 0;
while ((a = getchar()) != '\n')
{
;
}
printf("请确认密码(Y/N):");
int ch = getchar();
if (ch == 'Y')
{
printf("确认成功\n");
}
else
{
printf("确认失败\n");
}
return 0;
}
whlie循环在此十分重要!!!
补充:EOF的意思是,end of file.
● for 循环
先来看最简单的for循环:
int main()
{
int i = 0;
for (i = 1;i <= 10000;i++)
{
printf("%d", i);
}
return 0;
}
可以看到 for 后面的括号中用;隔开每一个条件,这样在修改循坏的内容时会比while循环更加方便简洁。
1)for循环中break的用法:
int main()
{
int i = 0;
for (i = 1;i <= 10;i++)
{
if (5 == i)
{
break;
}
printf("%d ", i);
}
return 0;
}
可以看到打印出来只有1 2 3 4,break直接就跳出了for循环。
2)for循环中continue的用法:
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (5 == i)
{
continue;
}
printf("%d ", i);
}
return 0;
}
可以看到5==i,continue后并没有直接跳出for循环,而是跳出了if循环,再次进入for循环。
建议:1。不可在for循环体内修改循环变量,防止for循环失去控制。
2.建议for语句的循环控制变量的取值采用“前闭后开区间”写法。如i<10优于i<=9。
特殊情况:1.for的初始化,判断,调整三个部分可以省略
2.但默认三个部分都为真,构成死循环
●do while 循环
int main()
{
int i = 0;
do {
printf("%d ", i);
i++;
} while;
return 0;
}
这就是 do while 的基本形式。break和continue与用法for相似。
我们接下来看一道题目:输入一个数,打印该数的阶乘
int main()
{
int i = 0;
int ret = 1;
int n = 0;
scanf("%d", &n);
for (i = 1; i <= n; i++)//在此用了一个for循环
{
ret = ret * i;//新的ret会等于老的ret乘以i,这样就能保证得出的结果是一个阶乘
}
printf("%d\n", ret);
return 0;
}
难度升级:打印1!+2!+3!+......+9!+10!
int main()
{
int i = 0;
int ret = 1;
int n = 0;
int sum = 0;
for (n = 1; n<=3; n++)
{
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
sum =sum+ret;//这句代码等价于sum+=ret;
}
printf("%d\n", sum);
return 0;
}
结果应该是9.
为了验证代码的正误,我们先试一下打印1!+2!+3!,但是结果并不是9而是15,为什么会这样呢?我们再打开调试。
发现了什么?ret的值按理来说应该是6=3*2*1,可是这里为什么会出现12呢?我们推测是出现了12=3*4的结果,那么可以推断上一次ret的值保留到了这一次的运算中去。该如何做呢?只需要每一次重置ret的值就行了,于是我们修改成为如下代码:
int main()
{
int i = 0;
int ret = 1;
int n = 0;
int sum = 0;
for (n = 1; n<=3; n++)
{
ret = 1;
for (i = 1; i <= n; i++)
{
ret = ret * i;
}
sum =sum+ret;
}
printf("%d\n", sum);
return 0;
}
这样子,我们就能够成功的打印题目所需。
可是有人就会说了:你用了两个for循环是不是太麻烦了?
行直接放代码:
int main()
{
int i = 0;
int ret = 1;
int sum = 0;
for (i = 1; i <= 3; i++)
{
ret = ret * i;
sum += ret;
}
printf("%d", sum);
return 0;
}
大家自己理解一下哈.
●折半查找(二分查找)
二分查找难度较大!!!
一组数组,1,2,3,4,5,6,7,8,9,10,若要找出数字7的下标该如何找呢?首先要知道,数组的下标是从0开始的,如1对应数组的下标为0。
//首先先定义一组数组
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
//如果数组比较长怎样操作呢?可以采如下方法:
int sz = sizeof(arr)/sizeof(arr[0]);//其中前者是整个数组的长度,后者是一个数字的长度,两者相除就是这个数组有多少个数。
int k = 7;//先定义要找的数字为7,目标是打印7的下标6。
int left = 0;
int right = sz-1;
//这里是找出最左边的数字和最右边的数字的下标,定义为left和right。
//此时定义一个中值,为每次二分过后的值
int mid = (left + right)/2;
//此时就可以开始一步步的进行了
//if(arr[mid]<k)
//{
//left = mid+1;
//}
//
//else if(arr[mid]>k)
//{
//right = mid - 1;
//}
//
//else
//{
//printf("找到了,下标是%d\n",mid);
//}
//在这一个条件语句中,第一步就是让下标为mid的元素(arr[mid]指下标为mid的元素)跟k相比较,如果小于k,那么left就变成mid,但是mid已经比较过了所以就向右移动一个单位,即left = mid + 1,else if也同理。但如果直接就比较出来了,便执行else语句。这样子就完成了一次比较。
//要完成多次比较,那么就需要while循环(for循环也可以),此时代码就变成了如下:
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("找到了,下标是%d\n",mid);
break;
}
}
//至此,已经完成了绝大部分了。那这个代码如果找不到k的下标呢,直接加入如下代码即可:
if (left > right)
{
printf("找不到了\n");
}
return 0;
}
这就是二分法的所有过程,怎么样呢?现在理解了吗?这个算法对于新手来说还是相当有难度的,希望大家好好体会其中的精髓。