C语言基础学习(Day12)
笔者有话说:
从Day1到Day12跟着笔者每天打卡到的朋友们,恭喜你们超前完成了C语言学习任务!🎉大家没有看错!虽然原计划是在15天内带领大家学完C语言,但是,我们在12天内,在不经意间,学完了C语言。为避免部分朋友认为来回翻阅较为麻烦,笔者在Day12为大家精心准备了这段时期以来所有的C语言笔记,本篇内容为完结篇,语言通俗易懂,小白也能学会!祝愿大家认真阅读Day12的内容,更好地掌握C语言,打卡第十二天!
文章目录
-
- C语言基础学习(Day12)
- 一、C语言学习预备知识
- 1、C语言的优缺点
- 2、数据类型
- 3、变量
- 4、进制(计算机只能识别二进制)
- 5、常量在C语言中是如何表示的
- 6、常量以什么样的二进制代码存储在计算机中
- 7、代码规范化
- 8、字节
- 9、ASCII码
- 二、C语言基础知识
- 1、基本输入与输出函数的用法
- 2、运算符
- 3、运算符补充
- 4、标识符(有名有姓的C)
- 5、枚举
- 6、冒泡排序
- 7、进制转换
- 8、 * 的含义
- 9、补码
- 10、算法
- 11、位运算符
- 12、NULL
- 13、数组
- 三、C语言重点难点
- 1、流程控制
- 2、选择——选择执行
- 3、循环
- 4、函数(C语言的第二个重点)
- 四、C语言的灵魂——指针
- 1、指针基础知识
- 2、指针的分类
- 3、专题:动态内存分配(重点难点)
一、C语言学习预备知识
1、C语言的优缺点
(1)优点:代码量小、速度快、功能强大
(2)缺点:危险性高、开发周期长、可移植性不强
2、数据类型
(1)基本数据类型
整型:int(4个字节) , short int(2个字节) , long int(8个字节)——%d输出
实数:float(4个字节) , double(8个字节)——%f输出
单个字符:char(占1个字节)——%c输出
(2)复合数据类型(由基本类型构成,后续深入学习)
结构体
枚举
共用体
3、变量
(1)变量的本质:内存中的一段存储空间
(2)变量的作用:利用变量可以方便我们对于数据的存储
#include <stdio.h>
int main(void)
{
int i; //定义变量i
i = 3; //3是存放在内存中,程序终止之后3所占用的空间被释放
printf("i = %d", i);
return 0;
}
说明:
int i;
——在内存条中找到一个空闲的、没有被其他单元占用的空间,分配给变量i使用,即把该单元地址与变量i产生一种关联。
i = 3;
——将3存储到变量i所对应的存储单元中
(3)变量为什么必须初始化?——所谓初始化就是赋值的意思
①必须初始化,只是编译器有时代替人工初始化而已。
②当全局变量没有初始化时,系统会自动初始化。(正常情况下)
③局部变量没有初始化时,系统会报错。
(4)软件运行与内存关系(垃圾数据)——内存是在操作系统的统一管理下使用的!
①软件在运行前需要向操作系统申请存储空间,在内存空间足够时 ,操作系统将分配一段内存空间,并将外存中的软件拷贝一份存入该内存中,并启动该软件的运行;
②在软件运行期间,该软件所占用的内存空间不再分配给其他软件;
③当软件运行完毕后,操作系统将回收该内存空间(注意:操作系统并不清空该内存空间遗留下来的数据),以便再次分配给其他软件使用。
总结:综上所述,一个软件所分配到的空间中极可能存在着以前其他软件使用后的残留数据,这些数据称为垃圾数据。所以通常情况下,我们为一个变量、一个数组分配好存储空间之后,都要对该内存空间初始化。
(5)如何定义变量
数据类型 变量名 = 要赋的值;
等价于:
数据类型 变量名;
变量名 = 要赋的值;
举例:
int i = 3; <=> int i; i=3;
int i, j; <=> int i; int j;
int i, j=3; <=> int i; int j; j=3;
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)举例:
十进制:逢十进一
二进制:逢二进一
(2)进制转化
Tip1:C语言规定八进制前要加0(注意是数字0,不是字母O),十六进制前要加0x或0X,十进制前不用加。
例如:
int 3;
——表示十进制
int 05;
——表示八进制
int 0x8;
——表示十六进制
Tip2:汇编语言中,数字后加字母B表示二进制数,加字母O表示八进制数,加字母D表示十进制数,加字母H表示十六进制数。
八进制:1~7
十六进制:1~9 A~F
Tip3:C语言代码实现
#include <stdio.h>
int mian(void)
{
//int i = 88;
int i = 0x32C; //注意:前面是数字0不是字母O
printf("i = %d\n", i);
printf("i = %o\n", i);
printf("i = %x\n", i);
printf("i = %X\n", i); //多行注释用:/*......*/
return 0;
}
(3)注意:
①区分单行注释与多行注释使用方法
②printf的用法:
%d表示以十进制输出
%o表示以八进制输出(o是小写字母)
%x或%X表示以十六进制输出
5、常量在C语言中是如何表示的
(1)整数:
十进制:传统写法
八进制:前面加0(数字0)
十六进制:前面加0x或0X(数字0)
(2)浮点数:
传统的写法
float = 3.2;
科学计数法
float x = 3.2e3; //x的值为3200
float x = 123.45e-2; //x的值为1.2345
e3表示10^3, e-2表示10^(-2)
对于代码:“float x = 123.45e-2;”, 若在程序运行中提示警告,表示数字123.45e-2默认为double类型(实数在C语言中默认为double类型)。
解决方法:①忽视警告,继续运行;②在数字后添加字母"F",即写为:“float x = 123.45e-2F;”,将其当作float处理。
(3)字符:
单个字符用单引号括起来
‘A’表示字符A,"A"也正确,"A"代表了’A’与’0’的组合
字符串用双引号括起来
"AB"正确,'AB’错误
6、常量以什么样的二进制代码存储在计算机中
(1)整数以补码的形式转化为二进制代码存储在计算机中;
(2)实数以IEEE754标准转化为二进制代码存储在计算机中;
(3)字符的本质实际也是与整数的存储方式相同。
7、代码规范化
(1)整齐,便于自己与他人检查观看
(2)不容易出错
int main(void)
{
//定义变量
//对变量进行操作
//输出值
}
规范化参考书籍:《高质量C/C++》——林瑞
8、字节
字节是存储数据的单位,并且是硬件所能访问的最小单位,CPU只能控制到字节,通过位运算符才能控制到位。
1个字节 = 8位
1K = 1024字节
1M = 1024K字节
1G = 1024M字节
1T = 1024G字节
注意:C语言中char占1个字节,在Java中字符占两个字节。
9、ASCII码
ASCII不是一个值,而是一种规定,ASCII码规定了不同的字符使用哪个整数值表示。
规定:
‘A’——65
‘B’——66
‘C’——67
‘a’——97
‘b’——98
‘0’——48
代码实现:
#include <stdio.h>
int main(void)
{
char ch = 'A';
ch = 'C';
printf("ch = %c", ch);
return 0;
}
输出结果:ch = 67
(1)单独定义
char ch = ‘A’; //√
char ch = “AB”; //× error 因为"AB"是字符串,不能把字符串赋给单个字符
char ch = “A” ; //× "A"代表’A’与’\0’两个字符的组合,不能把字符串赋给单个字符。
char ch = ‘AB’; //× 单引号只能括单个字符
(2)同时定义
char ch = ‘A’;
char ch = ‘B’;
× error,因为ch变量已经定义过,这样会导致变量名被重新定义
char ch = ‘A’; //等价于char ch; ch = ‘A’;
ch = ‘C’;
√ ch为变量,第一行定义单个字符变量ch,并将其赋值为’A’,可以对变量反复赋值
代码实现:
#include <stdio.h>
int main(void)
{
char ch = 'A';
ch = 'C';
printf("ch = %c", ch);
return 0;
}
输出结果:ch = C
(3)字符的存储
字符的存储本质上与整数的存储方式相同
二、C语言基础知识
1、基本输入与输出函数的用法
(1)输出——printf()——将变量的内容输出到显示器上
四种用法:
①printf(“字符串\n”);
#include<stdio.h>
int main(void)
{
printf("Hello!\n"); //"\n"——转义字符,表示换行
return 0;
}
②printf(“输出控制符”, 输出参数);
#include<stdio.h>
int main(void)
{
int i = 10;
printf("%d\n",i); //%d是输出控制符,i为输出参数
return 0;
}
Tip:d代表以十进制输出
③printf(“输出控制符1 输出控制符2 …”, 输出参数1, 输出参数2, …);
#include<stdio.h>
int main(void)
{
int i = 2;
int j = 4;
printf("%d %d\n", i, j); //%d是输出控制符,i为输出参数
return 0;
}
Tip:输出控制符与输出参数的个数必须一一对应
④printf(“输出控制符 非输出控制符”, 输出参数);
输出控制符包含如下:%d %ld %c %f %lf %x 或 %X 或 %#X %o
另外:%x在调试中的使用较为重要,因此需要掌握printf中%x及其相关的用法
int x = 47; //100前没有加0、0x或0X,表示100为十进制
#include<stdio.h>
int main(void)
{
int x = 47;
printf("%x\n", x); //输出结果为2f
printf("%X\n", x); //输出结果为2F
printf("%#x\n", x); //输出结果为0x2f
printf("%#X\n", x); //输出结果为0X2F
return 0;
}
Tip:%#X推荐使用!——可以一目了然看出输出结果为十六进制
输出控制符把参数以其规定的格式输出,而非输出控制符则以原样输出
例如:
#include<stdio.h>
int main(void)
{
int i = 4;
int j = 9;
printf("i = %d, j = %d/n", i, j);
return 0;
}
输出结果:i = 4, j = 9
说明:为什么需要输出控制符?
①0、1组成的代码可以表示数据也可以表示指令
②如果0、1组成的代码表示的是数据,同样的0、1代码组合以不同的输出格式输出,会有不同的输出结果
(2)输入——scanf()——通过键盘将数据输入到变量中
①scanf(“输入控制符”, 输入参数);
功能:将从键盘输入的字符转化为输入控制符所规定格式的数据,存入以输入参数的值为地址的变量中。
举例:
#include <stdio.h>
int main(void)
{
int i;
scanf("%d", &i);
printf("i = %d\n", i); //&i表示i的地址,&表示取地址符
return 0;
}
②scanf(“非输入控制符 输入控制符”, 输入参数);
Tip:非输入控制符必须原样输出
举例:
#include <stdio.h>
int main(void)
{
int i;
scanf("mm%d", &i); //mm为非输入控制符 %d为输入控制符
printf("i = %d\n", i);
return 0;
}
mm123为正确输入,而123为非法的输入
③scanf(”输入控制符1 输入控制符2 …", 输入参数1, 输入参数2, … );
一次给多个变量键盘赋值
```c
#include <stdio.h>
int main(void)
{
int i, j, k;
scanf("%d, %d, %d", &i, &j, &k);
printf("i = %d, j = %d, k = %d\n", i, j, k);
return 0;
}
Tip:","为非输入控制符,要原样输入,才能保证是合法输入
④如何使用scanf编写出高质量代码?
使用scanf前最好先使用printf提示用户以什么样的方式来输入;
scanf中尽量不要使用非控制符,尤其不要使用\n。
⑤编写代码对scanf中用户的非法输入做适当处理
while ( (ch = getchar()) != ‘\n’ )
continue;
——此处用到循环语句,后期深入学习
#include <stdio.h>
int main(void)
{
int i,j;
char ch;
scanf("%d", &i);
printf("i = %d\n", i);
//......
while ( (ch = getchar()) != '\n')
continue;
scanf("%d", &j);
printf("j = %d\n", j);
return 0;
}
2、运算符
(1)算术运算符:+ - * /(除) %(取余)
(2)关系运算符:> >= < <= !=(不等于) ==(等于)
(3)逻辑运算符:!(非) &&(并且) ||(或者)
(4)赋值运算符:= += -= *= /=
(5)优先级别:算术 > 关系 > 逻辑 > 赋值
注意:
①除法运算中,运算结果与运算对象的数据类型有关,两个数都为整数,则商为int,若商中有小数,则截取整数部分;被除数和除数中只要有一个或者两个为浮点型数据,则商也是浮点型数据,不截取小数部分。
②取余的运算对象必须是整数,结果是整除后的余数,其余数的符号与被除数相同,例如:13%-3=1, -13%3=-1, -13%3=-1。
③C语言对真假的处理:非零是真,零是假,真用1表示,假用0表示。
#include<stdio.h>
int main(void)
{
int i = 1;
int j = 2;
int k = 3;
int m;
//m = (3>2) && (k = 8); //=表示赋值 ——m为1, k为8
//m = (3>2) && (k = 0); //m为0, k为0
m = (2>3) && (k = 20); //m为0, k为3
//不含有";"的是表达式,含有";"的是语句
printf("m = %d, k = %d", m, k);
}
若&&左边为假,右边的表达式肯定不会执行;
若||左边为真,右边的表达式肯定不会执行。
3、运算符补充
附录的一些琐碎运算符知识
自增 自减 三目运算符 逗号表达式
(1)自增(或者自减)
①分类:
前自增 :++i --i
后自增:i++ i–
②前自增与后自增的异同:
相同点:最终都使i的值加1
不同点:前自增整体表达式的值是i加1之后的值;后自增整体表达式的值是i加1之前的值。
③为什么出现自增?
代码更精炼;自增的速度更快。
④学习自增要明白的几个问题
编程应尽量屏蔽前自增和后自增的区别;
自增最好不要作为一个更大的表达式来使用(或者说:++i 和 i++ 单独成一个语句,不要把它作为一个完整符合语句的一部分来使用)。
例如:
int m = i++ + ++i + i + i++ //这样写不但是错误的,而且不可移植
(2)三目运算符
格式:
A ? B : C
——问号与冒号合起来叫做三目运算符,用的不多
等价于:
if (A)
B;
else
C;
示例:
#include <stdio.h>
int main(void)
{
int i;
i = (3>2 ? 5 : 1);
printf("%d\n", i);
return 0;
}
输出结果:5
(3)逗号表达式
格式:
(A, B, C, D);
功能:
从左到右执行,最终表达式的值是最后一项的值
示例:
#include <stdio.h>
int main(void)
{
int i;
i = (3, 4, 2, 8);
printf("%d\n", i);
return 0;
}
输出结果:8
4、标识符(有名有姓的C)
(1)定义
C语言规定,标识符可以是字母A-Z、a-z、数字0-9、下划线**_**组成的字符串。第一个字符必须是字母或下划线。
(2)注意点
①标识符长度最好不要超过8位,在某些版本的C中规定标识符前8位有效,若两个标识符前8位相同,会被认为是同一个标识符;
②标识符严格区分大小写。Student与student是两个不同的标识符;
③标识符最好选有意义的英文单词,做到“见名知意”,不要使用中文;
④标识符不能是C语言的关键字。
(3)不可改变的常量
在程序执行过程中,值不发生改变的量称为常量,C语言的常量可以分为直接常量和符号常量。直接常量也称为字面常量,可以直接使用,无需说明;符号常量是可以使用一个标识符来表示一个常量。符号常量在使用前必须先定义,其一般形式为:
#define 标识符 常量值
#include <stdio.h>
#define POCKETMONEY 10 //定义常量及常量值
int main(void)
{
//POCKETMONEY = 12;——符号常量不可以被更改,会报错
printf("小明今天又得到了%d零花钱\n", POCKETMONEY);
return 0;
}
Tip:符号常量不可以被更改,会报错!
5、枚举
(1)什么是枚举
把一个事物所有可能的取值一一列举出来
(2)怎样使用枚举
以代码说明:
#include <stdio.h>
enum WeekDay
{
MonDay, TuesDay, WednesDay, ThursDay, FriDay, SaturDay, SunDay
};
int main(void)
{
enum WeekDay day = WednesDay;
printf("%d", day);
return 0;
}
(3)枚举的优缺点
优点:使代码更安全;
缺点:书写麻烦
6、冒泡排序
#include <stdio.h>
void sort(int * a, int len)
{
int i, j, t;
for (i=0; i<len-1; ++i)
{
for (j=0; j<len-1-i; ++j)
{
if (a[j] > a[j+1]) //">"表示升序,"<"表示降序
{
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
int main(void)
{
int a[6] = {
1, 4, 8, -5, 10, 11};
int i = 0;
sort(a, 6);
for (i=0; i<6; ++i)</