分支与循环初阶
大半个月过去,对C语言有了更多的认识,写本篇博客以记录一些学习过程中的细节。重点在于分支和循环语句的语法和使用场景。
零散知识点
1、C语言需要通过编译器进行编译,将文本代码转换成二进制的可执行exe文件。
2、程序在运行时,都要先被加载到内存。
3、变量是在内存中被定义的,因此需要开辟内存空间。
4、若全局变量和局部变量重名,就近选择局部变量。
5、作用域->作用范围;生命周期->存在时间。
6、C语言中的字符串默认以"\0"(看作1个字符)结尾。
7、C中的数据类型分为整形和浮点型,char本质是整形。
8、标准手册:cplusplus.com
9、strlen:求有效元素个数,不包括/0;
sizeof:求占据空间大小,包括/0。
10、非0为真,0为假。
11、变量的命名遵循驼峰原则(大驼峰小驼峰)。
12、C语言函数的默认返回值类型是整形,但最好不要忽略不写。
13、形参实例化→实参拷贝一份传进函数。
14、使用sizeof(arr)/sizeof(arr[0])动态求数组内元素个数。
15、sizeof 不是函数,而是 单目运算符,例子:sizeof a 。
16、&&->逻辑与,&->按位与。
17、static修饰局部变量的时候,有如下两个作用:
a、作用域:在本代码块中有效,用 static修饰,这个作用不变。
b、生命周期:该变量的生命周期变成全局属性。
即:变量的生命周期编程全局的,作用域依旧只在本函数内有效(在函数体外面不能访问)!static修饰的全局变量或函数,该变量或函数只能在本文件内使用!
注意:若变量初始化结束后没有被释放,则初始化语句只会被执行一次。
18、变量有四大要素:名称、空间、地址、内容。
19、全局变量一般可以跨文件使用,函数也可以跨文件使用。例如:extern int g_val //声明变量
20、为了方便查找,我们给内存每个字节都带上了编号(地址),提高查找效率。一般的地址,具有明显的指向性,我们一般把地址叫作指针。 指针就是地址。
21、指针解引用代表的是指针所指向的“目标”, 如:
int a = 0;
int *p =&a;
那么解引用时,*p 就是 a 。
22、不带花括号时,else采用和相邻的if匹配(就近原则)。
23、循环变量命名一般用i,j,k。
24、continue结束本轮循环,break结束整个循环。
25、int getchar返回整数,是为了更好地表示异常情况(宏定义EOF,通常为-1)。
26、Ctrl+Z代表输入结束。
27、代码中使用变量表示小数时,优先考虑使用double。很少使用float。
28、区间大概率前闭后开->业界通用的规范。
分支与循环
1、分支语句if(){},先识别()里的表达式,得到真假,然后再判定。
2、循环语句:条件设置、条件判定、条件更新。
代码
近期编写的代码如下:
求最大公约数、求闰年
#include <stdio.h>
#include <windows.h>
#pragma warning(disable:4996)
int main(){
//最大公约数
int a, b, min, result;
printf("请输入两个整数#");
scanf("%d %d",&a,&b);
if (a > b){
min = b;
}
else
min = a;
for (; min >= 1; min--){
if (a%min == 0 && b%min == 0){
result = min;
break;
}
}
printf("最大公约数是:%d\n",result);
//闰年
int year = 1000;
for (; year <= 2000; year++){
if (year % 4 == 0 && year % 100 != 0){
printf("%d\n", year);
}
}
system("pause");
return 0;
}
阶乘求和函数
int Fact(int num){
int result = 1;
for (; num >= 1;num--){
result *= num;
}
return result;
}
int FactSum(num){
int result = 1;
for (;num>=1;num--){
result += Fact(num);
}
return result;
}
二分查找函数
#include <stdio.h>
#include <windows.h>
#pragma warning(disable:4996)
#define NOT_FOUND -1
int BinSearch(int arr[], int num, int target){
int left = 0;
int right = num - 1;
while (left <= right){
int mid = (left + right) / 2;
if (target < arr[mid]){
right = mid - 1;
}
else if (target > arr[mid]){
left = mid + 1;
}
else
return mid;
}
printf("没找到\n");
return NOT_FOUND;
}
int main(){
int arr[] = { 11, 22, 33, 44, 55, 66, 77, 88, 99, 100 };
int num = sizeof(arr) / sizeof(arr[0]);
int index = NOT_FOUND;
int val;
printf("请输入要查找的值# ");
scanf("%d", &val);
index = BinSearch(arr, num, val);
if (index !=NOT_FOUND)
printf("找到元素下标为:%d\n", index);
system("pause");
return 0;
}
字符汇聚效果
char content[] = "hello world,hello mate";
char label[] = "######################";
int start = 0;
int end = strlen(label)-1;
printf("%s\r", label);
for (; start <= end; start++,end--){
label[start] = content[start];
label[end] = content[end];
printf("%s\r", label);
Sleep(300);
}
printf("\n");
进度条效果
int perc = 0;
while (perc<=100){
if (perc<10)
printf("\b#%d",perc);
else
printf("\b\b#%d", perc);
perc++;
Sleep(200);
}
printf("\n");
登录界面
输入正确用户名和密码后附带转圈加载效果,输错3次锁5秒倒计时。
#include <stdio.h>
#include <windows.h>
#pragma warning(disable:4996)
#define NAME "TOM"
#define PASSWD "1234"
void Spinning(){ //旋转效果
char sign[] = "|/-\\";
int i = 0;
while (i<=3){
printf("%c\r", sign[i]);
i++;
Sleep(300);
}
}
int main(){
char name[64];
char passwd[64];
int num = 3;
int count = 5;
while (1){
printf("请输入用户名# ");
scanf("%s", name);
printf("请输入密码# ", passwd);
scanf("%s", passwd);
num--;
if (strcmp(name, NAME) == 0 && strcmp(passwd, PASSWD) == 0){
Spinning();
printf("\r登录成功!\n");
break;
}
else{
if (num != 0){
printf("你还剩%d次机会!\n\n", num);
}
else{
num = 1;
for (; count >= 0; count--){
printf("%d秒后重新尝试登录!\r", count);
Sleep(1000);
}
printf("\n\n");
count = 5;
}
}
}
}
问题与解决
编程过程中难免遇到一些问题,在此记录一下并且附上解决办法以备不时之需。
1、
1>c:\users\thistle\documents\visual studio 2013\projects\10.12\10.12\10.12.c(137): error C4996: ‘scanf’: This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\stdio.h(283) : 参见“scanf”的声明
解决办法:
#pragma warning(disable:4996)
或者
#define _CRT_SECURE_NO_WARNINGS
2、在自定义函数内使用sizeof(arr)/sizeof(arr[0])时,无法正确计算出数组元素个数。
解决办法:函数形参里的数组会退化成指针,因此动态求数组内元素个数的方法不能用于自定义函数内。