C语言学习笔记(简略)
1.0——C的设计
1.1 C语言的使用步骤
1.确定目标
2.设计程序
3.编写代码
4.编译
5.运行程序
6.测试和调试程序
7.维护和修改程序
1.2 执行的过程
源代码-(编译器)->目标代码--(链接器链接库代码 与 启动代码)>可执行代码
1.3 编程风格
缩进的使用
合理的给变量命名
注释的使用
空格与大括号的使用
1.3.1空格的规范使用
- 关键字后留空格。例如 const ,if ,case ,while……
- 函数名之后不要留空格,紧跟左括号。例如 cheer()
- '('后面紧跟,',' 、';'向前紧跟。例如 printf ("The number of students is %d\n", number);
- ','之后要留空格,';'如果不在行末也要留空格
- 双目运算符前后加空格,例如 +, -, *, &&……
- 单目运算符前后不加空格,例如 ++, --, &……
- 象“[] ”、“.”、“->”这类操作符前后不加空格。
- 对于表达式比较长的 for 语句和 if 语句,为了紧凑起见可以适当地去 掉一些空格,如 for (i=0; i<10; i++)和 if ((a<=b) && (c<=d))
if (det == 1) {
}
for (i=0; i<10; i++) //good!
for (i = 0; i < 10; i++) //没有必要,空格太多
1.4 C语言中的语句
标号语句
复合语句
表达式语句
选择语句
迭代语句
跳转语句
2.0——C的框架及简单概念
2.1C的框架,以hello world!为例
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
2.2 注释
注释有两种,第一种为行注释
//
第二种为块注释
/* */
/* 这是一条C语言注释 */
//这也是注释
/*
希望能运行
加油!
*/
x = 100;
y = 200;
下面为错误示范
/*
希望能运行
加油!
x = 100;
y = 200;
/* 运行成功! */
//注意,这里第四行删去了配套的*/,导致一直到找到新的*/才会取消注释,后果就是全部被注释
2.3 声明
无论是函数,还是变量,使用前都需要声明;
声明一个变量时,会为变量赋予名称并分配内存空间;
例如
#include <stdio.h>
int cheer(int a); //函数声明
int main(void)
{
int i = 0; //声明变量i
j = 1; /*此处j未进行声明,会报错*/
printf("j = %d\n",j);
cheer(i); //调用函数
}
int cheer(int a)
{
printf("cheer!\n");
}
2.4 命名
变量命名规则
- 只允许以英文字母(大小写)、下划线(_),数字 结合来命名
- 名称以 字母 或 下划线(_) 开头
- 不可以使用C语言中的关键字作为变量,例如 int, printf……
int abc;
int _c_language;
int test1;
/* 下述为无意义命名 */
int 2cat;
double tax rate;
int I'm_a_stu;
int $good;
int money-day;
给变量命名要有意义
如果变量名无法清楚的表达所需含义,需在注释中进一步说明
int Sun_flower = 50;
int stars_count = 0;
2.5 printf 的使用
注意换行符(newline character)
注意空格
占位符-->%d
printf("i am a simple ");
printf("computer.\n");
2.6 程序的调试
- 利用debug
- 适当位置插入printf
2.7 语法错误与语义错误
3.0 数据和C
3.1 数据类型关键字
int a1;
long a2;
short a3;
unsigned a4; /* unsigned 等价于 unsigned int */
char a5;
float a6;
double a7;
//C90 std
signed a8;
void a9;
//C99 ONLY
_Bool a10
_Complex a11;
_Imaginary a12;
/* _Imaginary 声明虚数类型,但使用不多
可以调用头文件 <complex.h>, 使用imaginary 代替 _Imaginary */
3.2 整数类型
整数:不含小数点和指数的数
一般一个int占用一个机器字长(现代计算机字长通常为16, 32, 64)(机器字长通常是CPU内部数据通道的宽度)
例如:对于16位CPU,可表达最大数为2^15-1 = 32767
而在目前这台电脑,最大数为2^31-1=2147483647,int占据4个字节
规定:short占用字节<=int<=long
| short / short int | <=int |
|---|---|
| long int / long | >=int |
| long long int / long long | >=long |
| unsigned int / unsigned | 无符号数,如16位的unsigned的范围0~65535 |
| unsigned long long int | |
| …… |
为了程序的可移植性,类型需要使用准确。
数据使用不当可能会产生溢出现象
例如,有的机型long比int空间大,但有的long与int空间相同。
后缀的使用:
对于long类型,可以加L/l
对于unsigned类型,可以加上U/u
后缀还可以用于八进制与十六进制
类型转换:
小转大是安全的
但是大转小可能会产生数据的丢失
int ten = 10;
int two;
long a = 2147483647L;
short a = 32768;
printf("a(d) = %d, a(hd) = %hd\n", a, a);
a--;
printf("a(d) = %d, a(hd) = %hd\n", a, a);
int b = 32768;
printf("b(d) = %d, b(hd) = %hd\n", b, b);
return 0;
/*
打印结果:
a(d) = -32768, a(hd) = -32768
a(d) = 32767, a(hd) = 32767
b(d) = 32768, b(hd) = -32768
*/
3.3 浮点数类型
浮点数:除整数之外的数
以float位例,一般占用32位,其中8位表示指数的符号和值,24位表示非指数部分(尾数/有效数)的符号和值
| float | 通常32位,至少6位有效数字,取值范围10e-37~10e+37(不是小数点后六位数字) |
|---|---|
| double | 通常64位,至少十位有效数字 |
| long double | 精度>=double |
浮点数会有精度损失(大数运算时尤其明显)
double c = 2e-8;
float a = 3E5;
/* 注意,2与e之间没有空格 */
后缀:
没有后缀的浮点型常量是double类型
加上f/F,编译器会将浮点型常量看作float类型
加上l/L,编译器会将浮点型常量看作double类型
3.4.1 C99 std
可以用十六进制表示浮点型常量
C99 std
3.4.2 上溢和下溢
无穷大:inf(infinity)
NaN(not a number)/nan
3.4 char类型
char类型用于储存字符(实际上储存的还是整数)
char类型占用一个字节
初始化:
char grade = 'A'; // a good declaration
char grade = A; //ERROR,此时编译器认为A为变量名
char grade = "A"; //ERROR,"A"是一个字符串
char grade = 65; //可以,但不好
/* 实际上,由于字母'A'在ASCII码中对应数字为65,故打印结果认为 A ,但这是不好的编程风格 */
C语言将字符常量视为int类型而非char类型。例如,在int为32位,char为8位的ASCII系统中可以这样做
char c = 'FATE';
printf("%c\n", c);
/*
打印结果位 E
可以看到,实际上只有最后8位有效
*/
/*
char c = 'LOVEU';
这样却不行,甚至不可以通过编译
例如编译结果:
严重性 代码 说明 项目 文件 行 禁止显示状态
错误 C2015 常量中的字符太多 demo_02 D:\code\Project_C\demo_02\demo_02.c 5
可以看到:ERROR,常量中的字符太多
*/
最后8位有效有时不仅仅针对字符,即使以%d输出,也是最后8位有效
char c = 'DABA';
printf("c = %c,not %d\n", c, c);
return 0;
/*
打印结果
c = A,not 65
*/
3.4.1 转义序列
| 转义序列 | 含义 |
|---|---|
| \a | 警报(ANSI C) |
| \b | 退格(backspace) |
| \f | 换页 |
| \n | 换行 |
| \r | 回车 |
| \t | 水平制表符 |
| \v | 垂直制表符(让‘\v’后面的字符从下一行开始输出,且开始的列数为“\v”前一个字符所在列后面一列。) |
| \\ | 反斜杠(\) |
| \' | 单引号 |
| \" | 双引号 |
| ? | 问号 |
| \0oo | 八进制值(oo必须是有效的八进制数,即每个o可表示0~7中的一个数) |
| \xhh | 十六进制值(oo必须是有效的十六进制数,即每个h可表示0~f中的一个数) |
在PC屏幕上,\f,\v不一定会生效
注意“数字”和“数字字符”的区别,
例如:字符’4‘对应的ASCII码为52,而不是数值4
char c = '4';
char b = 4;
printf("c = %c,b = %c\nc = %d,b = %d", c, b, c, b);
/*
打印结果:
c = 4,b =
c = 52,b = 4
*/
3.5 转换说明(%d)与printf
| printf | |
|---|---|
| %d | 十进制输出 |
| %o | 八进制输出 |
| %x / %X | 十六进制输出,小写/大写 |
| %#o | 八进制输出,加上o前缀 |
| %#x / %#X | 十六进制输出,加上ox/OX前缀 |
| %u | 打印unsigned类型 |
| %ld | 打印long类型 |
| %lx(此处只可小写) | 以十六进制打印long类型 |
| %lo(此处只可小写) | 以八进制打印long类型 |
| %hd | 以十进制打印short类型 |
| %ho | 以八进制打印short类型 |
| %lu | 打印unsigned long类型 |
| %lld | 打印long long类型 |
| %llu | 打印unsigned long long类型 |
| %c | 打印字符(char) |
| %f | 打印float/double类型 |
| %e | 打印指数计数法的浮点数 |
| %Lf/%Le | 打印long double类型 |
注意:如果printf("")中没有按照要求输出,会发生隐式类型转换
例如
long long a = 2147483468;
printf("%d\n", a);
printf("%ld\n", a);
printf("%lld\n", a);
/*
-2147483648
-2147483648
2147483648
*/
转换说明与待打印值数量需要匹配
int ten = 10;
printf("ten is %d,%d is ten.",ten, ten);
/* 打印为ten is 10,10 is ten. */
printf("ten is %d,%d is ten",ten);
/* ERROR,%d与待打印值数量不匹配 ,会出现错误
我的打印结果,ten is 10,1296228736 is ten
*/
3.6关于输出的若干疑惑
printf()中的转换说明决定了数据的显示方式,而不是数据的储存方式
为什么%d 、%ld 、%lld 、%u的输出结果不相同?
实际上在计算机内部的表示是相同的
例如:11111111 10110111 00000000 00000001
以%lld输出时会查看64位,输出时为-22 177 777
而以%ld输出时只查看32位,打印结果为1
再比如:10000000 00000001
以%d打印时,结果为-65,535
而以%u打印时,会将前面一位作为有效数字算入大小,而不是作为符号,因此结果为100 001
3.7 函数的传输
printf()也是一个函数
在传输时,一般会把小于int类型的类型(例如short)全部转换为int传输,计算结果最后再截断。因为int为传输的最高效率
而对于浮点数,会把小于double类型的全部转换为double传输,运算。这样精度会更高,但会减慢程序的运行速度。
3.8 可移值类型:stdint.h 和 inttypes.h
3.9 类型大小
3.10 转义序列示例
float salary;
printf("\aEnter your desired monthly salary:");
printf(" $_______\b\b\b\b\b\b\b");
scanf("%f", &salary);
printf("\n\t$%.2f a month is $%.2f a year.", salary,
salary * 12.0);
printf("\rGee!\n");
return 0;

浙公网安备 33010602011771号