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;
posted @ 2023-01-04 10:17  我千五可以  阅读(120)  评论(0)    收藏  举报