C语言自学笔记
一、预备知识汇总
1.什么是变量?
变量的本质就是内存中的一段储存空间
2.变量为什么要初始化?
1.软件在运行前需要向操作系统申请存储空间,在内存空闲空间足够时,操作系统将分配一段内存空间并将外存中软件拷贝一份存入该内存空间中,并启动该软件的运行!
2.在软件运行期间,该软件所占内存空间不再分配给其他软件。
3.软件运行完毕后,操作系统将回收该软件占用的内存空间(注意:操作系统并不清空该内存空间中遗留下来的数据),以便再次分配给其他软件使用。
综上所述,一个软件所分配到的空间中极可能存在着以前其他软件使用过后的残留数据,这些数据被称之为垃圾数据。所以通常情况下我们为一个变量,为一个数组,分配好存储空间之后都要对该内存空间初始化!
3.如何定义变量?
数据类型 变量名 = 要赋的值
等价于
数据类型 变量名;
变量名 = 要赋的值;
举例子:
int i = 3; 等价于 int i ;i = 3;
int i,j; 等价于 int i ;int j;
int i = 3,j = 5; 等价于 int i ;int j ;i = 3; j = 5;
int i,j; i = j = 5; 等价于 int i ,j ;i = 5; j = 5;
4.什么是字节?
字节就是存储数据的单位,并且是硬件所能访问的最小单位
1字节 = 8位
1K = 1024 字节
1M = 1024k
1G = 1024M
5.负数在计算机是以补码的形式表示的
6.进制转化
什么叫进制
- 进制就是逢几进一
- 我们说N进制实际就是指逢N进一
注:计算机只识别二进制
C语言规定八进制前要加0(注意是零,不是字母o),十六进制前要加0x或0X,十进制前什么都不加
不同数制数的表示
在汇编中:在数字后
-
加字母B表示二进制数 加字母O表示八进制数 加字母D表示十进制数 加字母H表示十六进制数
例:
1011B为二进制数1011,也记为(1011)2
13570为八进制数1357,也记为 (1357)8
2049D为十进制数2049,也记为 (2049)10
3FB9H为十六进制数3FB9,也记为(3FB9)16
常用计数制对照表
八进制(0) | 十六进制(H) |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
10 | 8 |
11 | 9 |
12 | a |
13 | b |
14 | c |
15 | d |
16 | e |
17 | f |
十进制(D) | 二进制(B) |
---|---|
0 | 0 |
1 | 1 |
2 | 10 |
3 | 11 |
4 | 100 |
5 | 101 |
6 | 110 |
7 | 111 |
8 | 1000 |
9 | 1001 |
10 | 1010 |
11 | 1011 |
12 | 1100 |
13 | 1101 |
14 | 1110 |
15 | 1111 |
C语言中进制的转化
# include <stdio.h>
int main (void)
{
int i = 0x32c;
printf ("i = %x\n",i);
/*
printf的用法
%d表示以十进制输出
%x或%X表示以十六进制输出
%0表示以八进制输出
*/
return 0;
}
7.常量在C语言中是如何表示的?
整数
- 十进制: 传统的写法(即数字前面什么都不用加)
- 十六进制: 前面加0x或0X
- 八进制: 前面加0(注意是数字零,不是字母o)
#include <stdio.h>
int main (void)
{
int i = 015 ; //八进制前面加零
printf("%d\n",i);
return 0;
}
浮点数
- 传统的写法
float x = 3.2 ; //传统 - 科学计数法
float x = 3.2e3; //x的值是3200
float x = 123.45e-2; //x的值是1.2345
字符
单个字符用单引号括起来
字符串用双引号括起来
例:’A‘表示字符A
’AB‘错误
“AB”正确
“A”正确,因为“A"代表了‘A’、‘\0’的组合
8. 常量以什么样的二进制代码存储在计算机中?
整数是以补码的形式转化为二进制代码存储在计算机中的
实数是以IEEE754标准转化为二进制代码存储在计算机中的
字符的本质实际也是与整数的存储方式相同
# include <stdio.h>
int main(void)
{
char ch ='A' //(4行) OK 等价 char ch;ch ='A';
//char ch = "AB"; //error 因为"AB”是字符串,我们不能把字符串赋给单个字符
//char ch = "A";//error
//char ch ='AB'; //'AB'是错误的
//char ch ='B'; //error,因为ch变量已经在4行定义了, 这样会导致变量名被重复定义
ch='C';
ch ='D';
printf("%c\n",ch);
return 0;
}
9.什么是ASCII
ASCII不是一个值,而是一种规定
ASCII规定了不同的字符是使用哪个整数值去表示
10.代码规范化
代码规范化可以使代码的可读性更强(自己和别人能够更清楚地看懂程序)
也可以使程序更不容易出错
11.基本的输入和输出函数的用法
输入 函数 | 输出函数 |
---|---|
scanf() | printf() |
1. printf的四种用法
1.printf(“字符串”)
2.printf(“输出控制符”,输出参数);
3.printf(”输出控制符1 输出控制符2…”,输出参数1,输出控制符和输出参数的个数必须一一对应)
4.printf(“输出控制符 非输出控制符”,输出参数)
数字控制符有:
%d
%ld
%c
%f
%lf
%x(或者%X或者%#X)
%o
%s
/*
目的:
测试%x %X %#x %#X的用法
*/
#include <stdio.h>
int main(void)
{
int x = 47 ;//d是十进制
printf("%x\n", x);//输出结果是: 2f
printf("%X\n", x);//输出结果是: 2F
printf("%#X\n", x);//输出结果是: 0X2F 推荐使用%#X
printf("%#x\n", x);//输出结果是: 0x2f
//\n表示换行
return 0 ;
}
# include <stdio.h>
int main (void)
{
int i ;
scanf("%d",&i);//&i表示i的地址,&是一个取地址符
peintf("i = %d\n", i);
return 0;
}
# include <stdio.h>
int main (void)
{
int i;
scanf ("m%d", &i);//m123 是正确的输入, 123 是非法的输入
printf("i = %d\n", i);
return 0;
}
2. scanf的两种用法
- 用法一:scanf(“输入控制符”,输入参数)
功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中 - 用法二:scanf(“非输入控制符 输入控制符”,输入参数)
功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,然后存入以输入参数的值为地址的变量中。
非输入控制符必须原样输入
# include <stdio.h>
int main(void)
{
int i;
scanf("%d\n", &i);//非常不好的格式,不要加\n
printf("i = %d\n", i);
return 0;
}
如何使用scanf编写出高质量代码
- 使用scanf之前最好先使用printf提示用户以什么样的方式来输入
- scanf中尽量不要使用非输入控制符,尤其是不要用\n
- 应该编写代码对用户的非法输入做适当的处理【非重点】
while ( (ch=getchar ()) ! = '\n)
continue;
12.运算符
附录的一些琐碎的运算符知识:
自增 自减 三目运算符 逗号表达式
自增自减:
# include <stdio.h>
int main(void)
{
int i;
int j;
int k;
int m;
i = j = 3;//等价于 i = 3, j = 3;
k = i++;
m = ++j;
printf("i = %d, j = %d, k = %d,m = %d\n",i,j,k,m);
}
&&左边的表达式为假 右边的表达式肯定不会执行
II左边的表达式为假 右边的表达式肯定不会执行
C语言对真假的处理:
非零是真
零是假
真是1表示
假是0表示
13.流程控制(重点)
什么是流程控制
程序代码执行的顺序
程序流程的分类
- 顺序
- 选择
- 循环
二、循环
1.循环的定义
某些代码会被重复执行
为什么需要循环的例子
/*
计算1+2+3+...+100
*/
# include < stdio.h >
int main (void)
{
int i;
int sum = 0;
for (i=1; i<=100; ++i)
sum = sum + i ;//先执行i=1(i=1在整个流程中只需要执行这一次),再执行i<=100,再执行sum=sum+1,最后执行++i。执行完++i意味着一次循环结束。再执行i<=100,如果满足该条件则再次进入循环。不满足则会直接输出。
printf ("sum = %d\n",sum );
return 0;
}
++i表示在表达式计算之前先给i加1
i++表示在表达式计算完之后再给i加1
2.循环的分类
1.for
格式:
for (1; 2; 3)
语句A;
顺序:1–2–A–3–2
(1只用进行开头的这一次,3为一次完整循环的最后一步,3后一定接2,2是判断是否进入下一个循环的语句)
多个for循环的嵌套使用:
for (1; 2; 3)
for (4; 5; 6)
A;
B;
for循环举例
/*
求1到100的奇数和
*/
# include <stido.h>
int main (void)
{
int i
int sum = 0;
for (i=1; i<10; i+=2) //i+=2; 等价于 i=i+2
{
sum = sum +1;
printf("今天我很高兴!\n");//此句用来判断循环的次数:此句在终端显示的次数代表循环的次数
}
printf("i = %d\n", i);
printf("sum = %d\n", sum);
return 0;
}
# include <stdio.h>
int main(void)
{
int i;
float sum = 0;
for (i=1; i<=100; ++i)
{
sum = sum + 1 / (float)(i); //强制类型转化,这样写是ok的
//sum = sum + (float)(1/i); 这样写是不对的
//更简单的写法是: sum = sum + 1.0/i;
}
printf("sum = %f\n", sum); //float必须用%f输出
return 0;
}
强制类型转化
格式:
(数据类型)(表达式)
功能:
把表达式的值强制转化为前面所执行的数据类型
例子:
(int)(4.5+2.2) 最终值是6
(float)(5) 最终值是5.000000
浮点数的存错所带来的问题
存错原因:float和double都不能保证可以精确的存储一个小数
举例:
有一个浮点型变量x,如何判断x的值是否为零?
if (|x-0.000001| <= 0.000001)
是
else
不是
为什么循环中更新的变量不能定义成浮点型:因为浮点数不能精确存储
for和if的嵌套使用举例
/*
求1到100之间所有的能被3整除的数字之和
*/
# include <stdio.h>
int main(void)
{
int i;
int sum = 0;
for(i=3; i<=100; ++i)
{
if (i%3 == 0)//如果i能被3整除
sum = sum + i;
}
printf ("sum = %d\n", sum);
return 0;
}
2. while
3.do…while
3.break和continue
三、进制