1.编译器会将头文件(如 #include <stdio.h>)全部展开,因此,在写代码时不要乱加头文件,不然会降低编译效率。
2.何为变量?
变量代表内存中具有特定属性的一个存储单元,它用来存放数据,这就是变量的值,在程序运行期间,这些值是可以改变的。
(即:变量是内存中的一个存储单元,存放在其中的数据是变量的值)
3.左值:可修改的值
#define PI 3 则PI不为左值
#include <stdio.h>
#define PI 3 + 2
int main() {
int b = 4;
int c = PI * b;
printf("c = %d\n", c);// 3 + 2*4 = 11 不要误认为c = 5 * 4 = 20
int d = PI * PI;
printf("d = %d\n", d);// 3 + 2 * 3 + 2 = 11 不要误认为d = 5 * 5 = 25
}
4. 单位换算:
1 GB = 1024 MB
1 MB = 1024 KB
1 KB = 1024 B(字节/Byte)
1 字节 = 8 位(bit)
生活中的坑:
1G硬盘的实际大小其实是 1 G = 1000 * 1000 * 1000 B(字节)
中国电信的百兆带宽是以 bit 为单位 Mb ,因此真实速度要除以 8
5.'a' 是字符常量,"a"是字符串常量,二者不同。char c; c = "a"为非法操作
结论:不能把一个字符串常量赋给一个字符变量。
下面程序可以判断一个字符是否大写:
#include <stdio.h>
int main() {
char c = 'G';
//判断一个字符是否是大写字符
if (c >= 'A' && c <= 'Z')
{
printf("isUppercaseLetter");
}
else
{
printf("isLowercaseLetter");
}
}
6.强制类型转换:
#include <stdio.h>
int main() {
int a = 5;
float f1;
float f2;
//a为int类型,则a/2仍然为int类型,然后再将这个int类型的数据赋给f
f1 = a / 2;
//强制类型转换的优先级比/高,因此先将a转换成float类型,再/2
f2 = (float)a / 2;
printf("f1 = %f\n", f1);
printf("f2 = %f\n", f2);
}
7.C中的缓冲:
8.scanf的注意事项:
控制台输入123,其实是包括四个字符 -- 123\n,因此第一次scanf执行成功,第二次scanf接收了123之后的\n,故不能阻塞等待程序员输入
(本人使用的是vs2019版本,里面的scanf要用scanf_s替代)
#include <stdio.h>
int main() {
int i;
char c;
//执行到scanf则阻塞,等待输入
scanf_s("%d", &i);
printf("i = %d\n", i);
//期待阻塞,实则不阻塞,因为"i = %d"只接受int类型,因此123后面的\n被scanf接受
scanf_s("%c", &c);
printf("c = %c\n", c);
}
%d和%f忽略\n和空格,利用这个特性,只需要将第二个scanf修改为接收%d,他就自动将存放在标准输入缓冲区stdin中的第一个123后面的\n抹掉,这样就可以再次输入了,代码演示如下:
#include <stdio.h>
int main() {
int a;
int b;
//执行到scanf则阻塞,等待输入
scanf_s("%d", &a);
printf("a = %d\n", a);
scanf_s("%d", &b);
printf("b = %d\n", b);
}
9.循环读取:
补充:在C语言中,定义了一个宏EOF -- #define EOF (-1)
#include <stdio.h>
int main() {
int i;
while (scanf_s("%d", &i) != EOF)
{
printf("i = %d\n", i);
}
}
control + z + enter即可结束程序
注意:当输入的不是整数而是字符串时,程序会陷入死循环疯狂打印,如图:
理由如下:scanf的返回值是其匹配成功的数量,若输入了一个字符,意味着匹配失败,返回0,(0) != (-1)成立,陷入死循环
若想输入字符串之后仍然可以继续输入,则用rewind/fflush即可:
#include <stdio.h>
int main() {
int i;
int ret;
//rewind(stdin)清空缓冲区
while (rewind(stdin),(ret = scanf_s("%d", &i)) != EOF)
{
printf("i = %d\n", i);
}
}
10.scanf循环读取字符串:
#include <stdio.h>
int main() {
char c;
int ret;
while (ret = (scanf_s("%c",&c)) != EOF) {
printf("%c", c);
}
}
思考:若在循环接收字符串的时候,加上清空缓冲区stdin,会怎么样呢?
#include <stdio.h>
int main() {
char c;
int ret;
while (rewind(stdin), ret = (scanf_s("%c",&c)) != EOF) {
printf("%c", c);
}
}
输入abc,结果如下:
执行过程:①程序首先执行到while循环,清空上一次输入遗留的字符(假设有),再用scanf接收到字符a,将a打印出来
②打印出a后,继续while循环,又清空了stdin,即清空了bc,因此,只输出a