C语言入门
1、简单了解C语言
C语言之父——丹尼斯·里奇,他和肯.汤普森在贝尔实验室开发UNIX操作系统时设计了C语言,C语言是在B语言(肯.汤普森)的基础上进行设计的,C语言的设计是作为程序员使用的一种编程工具开发的,其目标是成为有用的语言。
1.1为什么要学C语言
C语言在过去的40年里一直是最重要、最流行的编程语言之一。C语言之所以经久不衰是因为他本身具有不同于其他语言的特性,像设计特性、高效性、可移植性、强大而灵活、面向程序员等,C语言目前在嵌入式开发中,依然占据不可替代的地位,像C++,java等编程语言也是在C语言的基础上进行优化和改造的,C语言作为编程的入门语言,虽然相较于python上手比较难,但是对以后的编程学习会更有帮助。
1.2使用C语言编程的步骤
新手编写代码过程:确定程序功能->写程序框架->完善功能->运行程序
1.3认识编辑器
编辑器是把高级语言程序翻译成计算机能理解的机器语言指令集的程序。一般而言,不同CPU制造商使用的指令系统和编码格式不同,而编辑器可以与特定CPU匹配,这样便可以把一种高级语言程序转换成供各种不同类型CPU使用的机器语言程序。
补充:按定义说最底层的编程语言是机器语言,其次是汇编语言,之后是高级语言,但是这种定义在不同资料上有不同的划分,但是基本划为低级语言和高级语言。机器语言是一种指令集的体系,这种指令集成为机器码,是电脑CPU可直接解读的数据。
机器码有时也被称为原生码(Native Code),这个名词比较强调某种编程语言或库,它与运行平台相关的部份。机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。它是计算机的设计者通过计算机的硬件结构赋予计算机的操作功能。
2、学会写基本的C语言程序
2.1成功输出“hello world"
C语言代码基本框架:
#include<stdio.h>
int main()
{
return 0;
}
语法结构:printf("内容");
一个语句结束后一定是以 ;结尾的
注意:除了汉字,其他的符号、字母,括号等均要英文格式输出。
流程图:
完整代码:
#include<stdio.h>
int main()
{
printf("hello world");
return 0;
}
2.2学会使用变量
流程图:
1、声明变量
语法:变量类型 变量名;
实例:int xuezhang;
char c;
基本变量类型:
整型(整数) | 浮点型(实型) |
---|---|
基本整型:int | 单精度实型:float |
长整型:long int | 双精度实型:double |
短整型: short int | 长精度实型:long double |
无符号整型: unsigned int |
**字符型: char **
不同类型的变量所占的内存空间不同,由于变量类型所占的字节跟编辑器的类型有关,但是通常来说short int,int、long int分别占2、4、8个字节大小,这就使不同类型的变量所能概括的值域范围有所不同(最大值和最小值之间的范围)。
unsigned int 无符号整型,指的是不小于0的整数,也占4个字节大小。
float、double、long double 类型变量通常占用4,8,16个字节大小, float、double默认输出6位小数,不足六位以0补齐,超过六位按四舍五入截断,在需要输出小数更多的情况下,double的输出位数比float要多,运算产生数据的精度更高,long double 也是同样的道理。
char 是字符型,用来存储字符,其变量占用1个字节大小。
2、变量赋值
声明变量时直接赋值:
语法:变量类型 变量名 =数值;
实例:int xuezhang=20;
先声明变量,再赋值:
语法:变量类型 变量名; 变量名=数值
实例:int xuezhang; xuezhang=20;
补充:在声明变量时,要避免变量名重复,不同的数据类型使用相同的变量名,会导致编辑器无法确定变量的类型,导致编辑出错,为了使保证程序正常运行,我们尽量避免变量名重复。
完整代码:
#include<stdio.h>
int main()
{
int xuezhang=20;
int xuezhang2;
xuezhang2=20;
return 0;
}
3、输出变量
语法:printf("格式符",变量);
实例:printf("%d",xuezhang);
下面是对应的输出格式符
格式符 | 含义 | |
整型 | %d | 输出待符号的十进制整数(整数的符号省略) |
%u | 以无符号的十进制整数形式输出 | |
%o | 以无符号的八进制整数形式输出 | |
%x | 以无符号十六进制整数形式输出 | |
%X | 以无符号十六进制整数形式输出 | |
浮点型 | %f | 以十进制小数形式输出实数。小数部分默认是6位。 输出的数字并非全部为有效数字,float有效数字为7位,double有效数字为16位 |
%e | 以指数形式输出实数,小写e表示指数部分 | |
%E | 以实数形式输出实数,大写E表示指数部分 | |
%g | 选取f或e格式中输出宽度较小的一种格式输出实数 | |
字符型 | %c | 输出一个字符 |
字符串 | %s | 输出字符串 |
百分号% | %% | 输出百分号% |
补充:
注释语法://或/*内容*/
注释的内容不会被编辑器编辑,注释方便他人阅读自己的代码
换行符:\n
常放在格式符之后,表示输出后,进行换行操作
实例:printf("%d\n",变量);
补充:
格式修饰符 | 用法 |
l | 加在格式符d、o/x/u前面,用于输出长整型整数 |
域宽m(正整数) | 指定输出数据的最小宽度 |
显示精度.n(正整数) | 实数:小数的位数;字符串:截取的字符个数 |
— | 输出的数组或字符在域内左对齐 |
举例:
float f1=4.2354;//定义变量并赋值
printf("%4.2f\n",f1);//输出的值为 4.23空格 数据宽度为4,不足四位会用空格填充,保留小数2位
long int f2=4257;
printf("%ld",f2); //输出长整型前要加格式修饰符 l
完整代码:
#include<stdio.h>
int main()
{
int xuezhang=20;
int xuezhang2;
xuezhang2=20;
float f1=4.2354;
printf("%d\n",xuezhang);
printf("%8d\n",xuezhang2);
printf("%4.2f",f1);
return 0;
}
2.3学会输入
流程图:
语法:scanf("输入格式符",&变量);
//&叫做取址符
实例:int a;scanf("%d",&a);
//输入的值赋值给变量,不能随意加换行符
注意:变量一定要先定义,才能通过输入进行赋值。
输入格式符
格式符 | 含义 | |
整型 | %d | 用于输入带符号的十进制整数 |
%u | 用于输入无符号的十进制整数 | |
%o | 用于输入无符号的八进制整数 | |
%x或%X | 用于输入无符号十六进制整数(大小写作用相同) | |
浮点型 | %f | 用于输入实数(以小数形式或指数形式输入) |
%e或%E或%g | 与%f可以互换作用,作用相同 | |
字符型 | %c | 用于输入一个字符 |
字符串 | %s | 用于输入字符串 |
格式修饰符
格式修饰符 | 用法 |
l | 加在格式符d、o、x、u前面,用于输入长整型整数;加在f 或e前面,用于输入double型数据 |
L | 加在格式符f、e前面,用于输入long double型实数 |
h | 加在格式符d、o、x前面,用于输入短整型整数 |
域宽m(正整数) | 从输入的数据流中截取指定宽度的数据 |
* | 表示此输入项在读入后不赋值给任何变量 |
注意事项:
int a,b;
scanf("%d%d",&a,&b); //输入一个数值后,按enter键,再输入另一个数值
printf("a=%d,b=%d",a,b);
int c,d;
scanf("%d,%d".&c,&d);//输入一个数字后,按, 再输入另一个数值
//所以分割符不一样,输入的格式也就有所不同
在学习输入时,要严格按照自己设置的输入格式进行输入,这样才能保证数据的准确性
思考:不按照指定类型输入数据,结果会怎么样?
实例:int a;scanf("%d",&a);
输入a,输出的值是怎样的,为什么
补充:
单个字符的输入/输出
语法:char a;a=getchar();
//getchar();函数输入一个字符,赋值给a
putchar(字符变量或常量);
实例:
char a1;
a1=getchar();
putchar(a1);
printf("%c\n",a1);
3、学会运算
流程图:
3.1认识算术运算符和赋值运算符
语法:=+-*/%
运算符 | 含义 | 实例 | 运算结果 |
= | 赋值符 | 变量=常量或初始化的变量 int d,d1; d=10; d1=d; | d=10 |
- | 取相反数 | -10 | -10 |
* | 乘法 | 10*10 | 100 |
/ | 除法 | 10/10 | 1 |
% | 取余 | 3/2 | 1 |
+ | 加法 | 10+10 | 20 |
- | 减法 | 10-10 | 0 |
实例:输出三位整数的个位、十位、百位之和
#include<stdio.h>
int main()
{
int sum,a1,a2,a3,b;
b=185;
a1=b/100;
a2=b/10%10;
a3=b%10;
sum=a1+a2+a3;
printf("sum=%d",sum);
return 0;
}
3.2认识复合的赋值运算符
语法:+= -= *= /= %=
运算符 | 实例 |
+= | x+=y等价于x=x+y |
-= | x-=y等价于x=x-y |
*= | x*=y等价于x=x*y |
/= | x/=y等价于x=x/y |
%= | x%=y等价于x=x%y |
注意:运算符优先级相同的情况下,运算要考虑运算符的结合性,一般的运算符的结合性是自右向左的。在使用复合的赋值运算符时,一定要注意变量的初始化。
实例:
#include<stdio.h>
int main()
{
int x=10,x1=0;
x1+=x-=x*x;// x=x-x*x;x1=x1+x
printf("%d",x1);
return 0;
}
3.3学会使用自增运算符
语法:++ --
实例:
#include<stdio.h>
int main()
{
int x=0;
printf("x=%d\n",x++);//输出的值是 0
printf("x=%d\n",x);//输出的值是 1 因为x++是在变量使用之后再进行自增1的操作
printf("x=%d\n",++x);//输出的值是 2
printf("x=%d\n",x); //输出的值是 2 因为++x是在变量使用之前进行自增1的操作
return 0;
}
自减也是同样的道理。
补充:学会使用sizeof();
语法:sizeof(数据类型/变量/常量);
作用:计算数据类型所占内存的字节数
实例:
#include<stdio.h>
int main()
{
int x=0;
printf("int类型所占内存数为:%d\n",sizeof(x));
return 0;
}
3.4学会设置常量
宏常量语法:#define 标识符 字符串;
常变量语法:const 数据类型 变量名;
宏常量又称符号常量,是指用一个表示符号来代表一个常量。#define表示一个编译预处理指令,变异鱼处理指令不是C语言语句,行末不要加分号。
实例:
#include<stdio.h>
#define d 3
int main()
{
int x=4;
printf("x=%d\n",x*d);//d代表3这个常量
return 0;
}
C语言中将具有特殊含义或在程序中使用频率较高的常量,定义为宏常量或const常量
const常变量,为了克服使用宏常量带来的问题,同事保留宏常量的优点,C语言中提供了具有数据类型的常变量。其中 数据类型前面的const,表示这里定义的数据类型的变量只能在定义时赋初值,且值在变量存在期间是不能随意改变的。
实例:
#include<stdio.h>
int main()
{
int x=4;
const int f1=45;
printf("%d\n",x*f1);
//f1=x; 语法错误,f1的值不能更改
return 0;
}
4、学会使用选择结构
4.1关系运算符和逻辑运算符
关系运算符:
优先级高 | 优先级低 |
<小于 | ==等于 |
<=小于等于 | !=不等于 |
>大于 | |
>=大于等于 |
任何运算都会有一个结果,对于关系运算来首,它的结果是一个逻辑值,逻辑值的取值只有“真”和“假”,跟别对应“对”和“错”,关系“成立”和“不成立”。
由于C语言不存在转门的逻辑值,所以用“非0”表示真,用“0”表示假。
! 逻辑非 | 优先级从高到低 |
&& 逻辑与 | |
|| 逻辑或 |
单分支结构
语法:if(条件){ 执行语句}
或者if(条件表达式) 执行语句;
实例:if(2>1){printf("学长真帅\n");}
注意:只有条件为真时,才会执行{ }里面的语句。
双分支结构
语法:if(条件){} else{}
实例:if(2>1){printf("学长很帅\n");} else{printf("学长一般");}
注意:双分支结构,条件为真则执行if下的语句,否则执行else下的语句。
多分支语句
语法:
if(条件1)
{
执行语句1
}
else if(条件2)
{
执行语句2
}
~~~~~
else
{
执行语句n
}
嵌套结构
语法:
if(条件1)
{
if(条件2)
{
执行语句1
}
else
{
执行语句2
}
}
else{
执行语句3
}
实例:
#include"stdio.h"
int main()
{
printf("请输入你的四级分数\n");
int score;
scanf("%d",&score);
if(score>=425)
{
printf("恭喜你的英语成绩达标\n");
}
else{
if(score>=380)
{
printf("你的成绩符合毕业要求\n");
}
else
{
printf("你的成绩不符合要求\n");
}
}
return 0;
}
条件表达式
语法:表达式1?表达式2:表达式3
语法过程:首先计算表达式1,如果表达式1为真,那么表达式2的值就为整个条件表达式的值;如果表达式1的值为假,那么表达式3的值整个条件表达式的值。
实例:
#include"stdio.h"
int main()
{
printf("请输入你的英语成绩\n");
int score;
scanf("%d",&score);
printf(score>425?"你的英语成绩合格\n":"你的英语成绩不合格");
return 0;
}
思考:如果出现a=1;a>0||(a=5);
逻辑表达式运算之后a的值是什么?
4.3多重选择结构(switch)
语法:
switch(表达式)
{
case 常量表达式1:执行语句1;
break;
case 常量表达式2:执行语句2;
break;
case 常量表达式2:执行语句2;
break;
---
case 常量表达式n:执行语句n;
break;
default:执行语句n+1;
break;
}
实例:
#include"stdio.h"
int main()
{
int c;
printf("请输入0-5之间数字\n");
scanf("%d",&c);
switch(c)
{
case 1: //当c的值为1时,会执行下面语句
printf("模式1\n");//输出模式1
break; //break 代表跳出switch,不再执行下面语句
case 2:
printf("模式2\n");
break;
case 3: //当c的值为3时,会执行下面语句
printf("模式3\n");//输出模式3
case 4: //没有break会继续执行下面语句,c的值为4时,也是从这条语句开始执行
printf("模式4\n");//输出模式4
break; //跳出switch,不再执行下面语句
default: //代表除了case语句标号值的其他情况,会执行下面的语句
break; //跳出switch
}
return 0;
}
注意:switch();括号中的值一定是整型数据或者字符型数据,case后面的标号值不能相同,标号值要与case有空格,且标号值后一定要跟冒号。
5、学会使用循环结构
5.1for循环
语法:
for (R1; R2; R3)
{
循环体语句;
}
执行过程:首先求解表达式R1(只求解一次),再求解表达式R2的值,非零则执行循环体语句,执行循环体语句完毕后,求解R3的值,再求解表达式R2的值,进行循环,R2为值为0,则不再执行for循环
实例:
#include<stdio.h>
int main()
{
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d", i);
}//输出结果为01234
return 0;
}
5.2while循环
语法:
while(R1)
{
循环体语句;
}
执行过程:首先判断R1是否非零,非零则执行循环体语句,再判断R1是否为真,依次循环,为零则跳出循环,执行下一个语句
实例:
#include<stdio.h>
int main()
{
int i = 5;
while(i--)
{
printf("%d",i);
}//输出结果为43210
return 0;
}
5.3do-while循环
语法:
do
{
循环体语句;
}while(R2);
执行过程:先执行循环体语句,再判断表达式R2的值是否为零,非零则再次执行循环体语句,为零则跳出循环
实例:
#include<stdio.h>
int main()
{
int i = 5;
do
{
printf("%d",i);
}while(i--);
//输出543210
return 0;
}
补充:do-while循环至少执行一次循环体语句,其他两个循环至少执行0次循环体语句,使用break语句都可以跳出循环结构
6、知识点补充
6.1位运算
运算符:
、运算符 | 含义 | 运算符 | 含义 |
& | 按位与 | - | 取反 |
| | 按位或 | << | 左移 |
^ | 按位异或 | >> | 右移 |
位运算是二进制编码间的运算,位运算符中出~意外,均为二元运算符,即要求运算符两侧各有一个运算量。运算量是整型或字符型的数据。
按位与:参加运算的两个数的二进制补码,从左向右每一组对应数位上的二进制数进行“与”运算,如果对应数位上的二进制数都为1,则该位的结果值为1,否则为0。
按位或:参加运算的两个数的二进制不嘛,从左向右每一组对应数位上的二进制数进行“或”运算。要要有一个1,则结果为1.
取反:对一个二进制数的每一位取反,即将0变成1,1变成0。
左移:将一个数的各二进制位全部左移若干位
例如:a=00011100;a<<2;a=01110000;
右移:将一个数的各二进制位全部右移若干位
补充:左移一位相当于相应的十进制数乘以2,右移一位相当于相应的十进制数除以2
6.2continue与break的区别
使用范围:continue只能在循环体中使用,break可以在循环体和switch中使用
作用:continue可以跳过本次循环,进入下一次循环;break可以是整个循环终止
案例:
#include<stdio.h>
int main()
{
int i = 5,j=6;
while (i)
{
i--;
if (i % 2 == 0)
{
continue;
}
printf("%d", i);
}//输出31
printf("\n");
while (j)
{
j--;
if (j% 2 == 0)
{
break;
}
printf("%d\n", j);
}//输出5
return 0;
}
<td>取反</td>
</tr>
<tr>
<td>|</td>
<td>按位或</td>
<td><<</td>
<td>左移</td>
</tr>
^ 按位异或 >> 右移
位运算是二进制编码间的运算,位运算符中出~意外,均为二元运算符,即要求运算符两侧各有一个运算量。运算量是整型或字符型的数据。
按位与:参加运算的两个数的二进制补码,从左向右每一组对应数位上的二进制数进行“与”运算,如果对应数位上的二进制数都为1,则该位的结果值为1,否则为0。
按位或:参加运算的两个数的二进制不嘛,从左向右每一组对应数位上的二进制数进行“或”运算。要要有一个1,则结果为1.
取反:对一个二进制数的每一位取反,即将0变成1,1变成0。
左移:将一个数的各二进制位全部左移若干位
例如:a=00011100;a<<2;a=01110000;
右移:将一个数的各二进制位全部右移若干位
补充:左移一位相当于相应的十进制数乘以2,右移一位相当于相应的十进制数除以2
6.2continue与break的区别
使用范围:continue只能在循环体中使用,break可以在循环体和switch中使用
作用:continue可以跳过本次循环,进入下一次循环;break可以是整个循环终止
案例:
#include<stdio.h>
int main()
{
int i = 5,j=6;
while (i)
{
i--;
if (i % 2 == 0)
{
continue;
}
printf("%d", i);
}//输出31
printf("\n");
while (j)
{
j--;
if (j% 2 == 0)
{
break;
}
printf("%d\n", j);
}//输出5
return 0;
}