看这样一段代码
int main()
{
char passw[20] = {0};
int qr;
printf("请输入密码:");
scanf("%s", passw);
printf("请确认(Y/N);");
qr = getchar();
if (qr == 'Y')
{
printf("确认无误");
}
else
{
printf("确认失败");
}
return 0;
这段代码的本意是用户输入一个密码,然后再次确认,但是输出结果如下
可见未执行‘用户确认’这一语句
原因是在执行scanf("%s", passw);后,用户按下回车使代码继续,此时按回车继续运行,由于回车即换行符‘\n’对应的ASCII码为10,缓冲区留下的这个10会被getchar读走,判断并输出“确认失败”
int main(){
char passw[20] = {0};
int qr;
int sx;
printf("请输入密码:");
scanf("%s", passw);
while ((sx = getchar()) != '\n')
{
;
}
printf("请确认(Y/N);");
qr = getchar();
if (qr == 'Y')
{
printf("确认无误");
}
else
{
printf("确认失败");
}
return 0;
}
可以选择加入一个while()循环,让getchar不停的读取用户输入的字符,知道读到‘\n’结束循环;使用while循环读取也可以避免输入空格后(ASCII:32)提前结束读取,让缓冲区停留的字符被下一个getchar()读取。
- 注,scanf()函数接收数据时不一定需要&,目标数据为数据,则需要&“ scanf(“%s”,&a)”;目标为地址则不需要“scanf(“%s”,arr)”---arr为数组名
int main(){int a = 0;
while ((a = getchar()) != EOF)
{
if (a < '0' || a>'9')
{
continue;
}
putchar(a);
}
return 0;
}
可以通过上述代码过滤掉非数字字符,若输入数字字符,则会重复输出一次数字字符。
for循环语法
for(表达式1;表达式2;表达式3)
循环语句
表达式1 为初始化部分,初始化循环变量
表达式2为判断条件,判断循环终止时间
表达式3为调整部分,用于循环条件调整
用for循环输出0-10;
int main(){int i;
for (i=0;i<=10;i++)
{
printf("%d\n", i);
}
return 0;
}
break和continue在for循环中的应用
int main(){int i;
for (i=0;i<=10;i++)
{
if (5 == i)
{
break;
}
printf("%d\n", i);
}
return 0;
}
输出结果0 1 2 3 4
int main(){int i;
for (i=0;i<=10;i++)
{
if (5 == i)
{
continue;
}
printf("%d\n", i);
}
return 0;
}
输出结果 0 1 2 3 4 6 7 8 9 10
break直接结束所有循环
比较while语句中的类似continue用法,while中continue结束本次循环后下一次循环i的值仍然为5,判断结果并无改变,所以会出现死循环;for中的continue结束本次循环后利用调整部分使得i=6,不会进入到if判断当中,不会发生死循环
建议:1不可以在for循环内修改循环变量,防止for循环失去控制
2建议for语句的循环控制变量的取值采用前闭后开区间写法
int main(){int arr[9] = { 1,2,3,4,5,6,7,8,9 };int i = 0;
for (i = 0; i < 9; i++)//这里代表将循环九次,前闭后开可以更加清晰的表达如循环次数,打印次数,元素个数等
{
printf("%d", arr[i]);
}
return 0;
}
前闭后开写法并不能应用在所有情况
int main(){for (;;)
{
printf("1");
}
return 0;
}
for循环的初始化、判断、调整 ,都可以省略,但是判断条件被省略,则判断条件恒为正
初始化省略:
int main(){int i = 0;int j = 0;
for (; i < 10; i++)//i循环10次,最终为10
{
for (; j < 10; j++)//j循环10次,最终为10
{
printf("01\n");
}
}
return 0;
}
无初始化后,j在i循环结束前一直保持为10,不会继续打印
练习题:
int main(){int x;int y;
for (x = 0, y = 0; y = 0; x++, y++)
{
y++;
printf("%d\n", y);
}
return 0;
}
该代码循环0次。原因:判断语句部分为赋值语句‘y=0’,即判断条件为0,无法进入循环;如果改为非0,则改代码进入死循环
do...whlie()循环
语法:
do
循环语句;
while(表达式);
int main(){int i = 1;do
{
printf("%d\n", i);
i++;
}
while (i < 10);
return 0;
}
输出结果1-9;当打印完9后,i的值为10,判断为假,结束循环
break 和continue 在do..while中的应用
int main(){int i = 1;do
{
if (i == 5)
continue;
printf("%d\n", i);
i++;
}
while (i < 10);
return 0;
}
输出1,2,3,4后进入死循环
int main(){int i = 1;do
{
if (i == 5)
break;
printf("%d\n", i);
i++;
}
while (i < 10);
return 0;
}
输出1,2,3,4后结束循环
do语句至少会循环一次
练习题
题目:求n的阶乘
(自写)
int main(){int n;int i;
int a;
int b;
int c ;
scanf("%d", &n);
a=n;
for (i = n; i >1; i--)
{
b = i - 1;
a *= b;
}
printf("%d\n", a);
return 0;
}
题目:求1-10的阶乘的和
(自写)
int main(){int a,c=0;int b,i,j;
int n = 10;
for(j=0;j<10;j++)
{
b = n;
for (i = n; i > 1; i--)
{
a = i - 1;
b *= a;
}
c =c+b ;
n--;
}
printf("%d\n", c);
return 0;
}
(改进)
int main(){int i, n, a, b;n = 10;
a = 1;
b = 0;
for (i = 1; i <= n; i++)
{
a *= i;
b += a; //1+1x1+1x2+1x2x3
}
printf("%d\n", b);
return 0;
}
从1开始,将每个数字的阶乘相加
折半查找算法,二分查找算法:
题目:在一个数组有序数组当中查找某一个数字n
int main()
{
int arr[] = { 1,2,3,4,6,7,8,9,10,11 };
int k = 0;
int size = sizeof(arr) / sizeof(arr[0]);
int left = 0;//左下标
int right = size - 1;//右下标
while (left<=right)
{
int mid = (right + left) / 2;
if (arr[mid] > k)
{
right = mid - 1;
}
else if (arr[mid] < k)
{
left = mid + 1;
}
else
{
printf("已找到,位置:%d", mid);
break;
}
}
if (left > right)
{
printf("查询无果");
}
return 0;
}
数组中的每一个元素都对应着一个下标,先找到当前数组的中间下标,当前中间下标mid对应的元素与要查找的元素n对比,若n位于中间元素左侧,则右下标跟新为mid-1,(位于右侧同理),再重复上述步骤,直到元素相等,即找到n,跳出循环。或者下标交换左右的情况,即无法找到n,退出循环。
对于数组arr=[1,2,3,4,5,6,7,8,9,0]找最右侧坐标可以采用(数组长度/元素长度-1)来找。
对于数组arr=“abcdefgh”,找到最右侧坐标要采用(数组长度/元素长度-2)来找。因为字符串后面会默认有一个'\0',实际长度比所需长度大1
题目
演示多个字符从两端移动向中间汇聚
int main(){char arr1[] = "###########" ;char arr2[] = "AAAAAAAAAAA" ;
printf("%s\n", arr1);
Sleep(1000);
system("cls");
int left = 0;
int right = strlen(arr1)-1;
while (left <= right)
{
arr1[left] = arr2[left];
arr1[right] = arr2[right];
printf("%s\n", arr1);
left++;
right--;
Sleep(500);//休眠0.5秒
system("cls");//执行系统命令-----cls:清空屏幕
}
printf("%s\n", arr1);
return 0;
}
获取数组最右侧位置可以使用strlen(),遇到‘\0’自动停止
Sleep(),需要引入头文件#include
system(),需要引入头文件#include
题目:
要求用户有三次输入密码的机会
int main()
{
char psw[] = "asdfghjkl";
char input[20] = {0};
int i = 0,j=0;
printf("请输入密码:");
for(i;i<3;i++)
{
scanf("%s", &input);
printf("%s\n", input);
if (strcmp(input,psw)==0)//不能用==比较两个字符串是否相等,应该使用库函数strcmp()
{
printf("登录成功\n");
break;
}
if(i<2
)
{
printf("请重新输入:");
}
if (3 == i)
{
printf("登录失败\n");
}
return 0;
}
strcmp(),函数内填写对比的两个字符串,相等返回0,前大于后,返回一个大于0的数字,前小于后,返回一个小于0的数字