C 语言特点
我的第一个 c 语言程序
#include<stdio.h>
int main()//这个我的第一个 c 语言程序
{
printf("hello world\n");//printf 是输出打印的函数
return 0;
}
1.#include<stdio.h>头文件包含, 一定要有
2.每一个 c 语言的程序有且只有一个 main 函数, 这是整个程序的开始位置
3.C 语言中()、 []、 {}、 “” 、 ’’、 都必须成对出现,必须是英文符号
4.C 语言中语句要以分号结束。
//为注释
关键字
2.1数据类型相关的关键字
用于定义变量或者类型
类型 变量名;
char 、 short、 int 、 long 、 float、 double、struct、
union、 enum 、 signed、 unsigned、 void
char 字符型
用 char 定义的变量是字符型变量, 占 1 个字节
char ch='a'; //=为赋值号
char ch1='1';//正确
char ch2='1234';//错误的
short 短整型
使用 short 定义的变量是短整型变量, 占 2 个字节
short int a=11; //范围: -32768 ----32767
int 整型
用 int 定义的变量是整型变量, 在 32 位系统下占 4 个字节, 在 16 平台下占 2 个字节
int a=44; //-20 亿---20 亿
long 长整型
用 long 定义的变量是长整型的, 在 32 位系统下占 4 个字节
long int a=66;
float 单浮点型 (实数)
用 float 定义的变量是单浮点型的实数, 占 4 个字节
float b=3.8f;
double 双浮点型 (实数)
用 double 定义的变量是双浮点型的实数, 占 8 个字节
double b=3.8;
struct
这个关键字是与结构体类型相关的关键字, 可以用它来定义结构体类型, 以后讲结构体的时候再讲
union
这个关键字是与共用体(联合体) 相关的关键字, 以后再讲
enum
与枚举类型相关的关键字 以后再讲
signed
有符号(正负)的意思
在定义 char 、 整型(short 、 int、 long) 数据的时候用 signed 修饰, 代表咱们定义的数据是有符号的, 可以保存正数, 也可以保存负数
//例 :
signed int a=10;
signed int b=-6;
注意: 默认情况下 signed 可以省略 即 int a=-10;//默认 a 就是有符号类型的数据
unsigned
无符号的意思
在定义 char 、 整型(short 、 int、 long) 数据的时候用 unsigned 修饰, 代表咱们定义的数据是无符号类型的数据,只能保存正数和 0。
unsigned int a=101;
unsigned int a=-101; //错误
12. void
空类型的关键字
char、 int 、 float 都可以定义变量
void 不能定义变量, 没有 void 类型的变量
void 是用来修饰函数的参数或者返回值, 代表函数没有参数或没有返回值
例:
void fun(void){ }
代表 fun 函数没有返回值, fun 函数没有参数
例 2:
#include <stdio.h>
int main()
{
char a = 'a';
short int b = 10;
int c;
long int d;
float e;
double f;
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(b));
printf("%d\n",sizeof(c));
printf("%d\n",sizeof(d));
printf("%d\n",sizeof(e));
printf("%d\n",sizeof(f));
return 0;
}
扩展:
内存存储
char ch='a'; // 占 1 个字节, 存储的是 97 0110 0001
字节: 内存的基本单位, 8 位为 1 个字节
计算机存储时, 只能存储 1 和 0 的二进制组合, 1 和 0 都分别占 1 位
字符型数据在内存中存储的不是字符本身, 而是存储其 AsciI 码
整型变量存储的是其值的二进制
unsigned int a = 97;
正数和负数在内存中到底是怎么存的
原码、 反码、 补码
规定:正数的原码反码和补码相同
5
0000 0101
-5
原码: 最高位为符号位 最高位为 1 代表是个负数
1000 0101
反码: 除了符号位 其他位取反
1111 1010
补码: 反码 +1
1111 1011
注意: 负数在内存中是以补码形式存放的
例 1:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a=-5;
printf("%d\n",a);
printf("%x\n",a);
return 0;
}
2.2存储相关关键字
register、 static、 const、 auto、 extern
register
寄存器的意思, 用 register 修饰的变量是寄存器变量,
即: 在编译的时候告诉编译器这个变量是寄存器变量, 尽量将其存储空间分配在寄存器中。
注意:
(1): 定义的变量不一定真的存放在寄存器中。
(2): cpu 取数据的时候去寄存器中拿数据比去内存中拿数据要快
(3): 因为寄存器比较宝贵, 所以不能定义寄存器数组
(4): register 只能修饰 字符型及整型的, 不能修饰浮点型
register char ch;
register short int b;
register int c;
register float d;//错误的
(5): 因为 register 修饰的变量可能存放在寄存器中不存放在内存中, 所以不能对寄存器变量取地址。 因为只有存放在内存中的数据才有地址
register int a;
int *p;
p=&a;//错误的, a 可能没有地址
static
是静态的意思
static 可以修饰全局变量、 局部变量、 函数
这个以后的课程中重点讲解
3. const
const 是常量的意思
用 const 修饰的变量是只读的, 不能修改它的值
const int a=101;//在定义 a 的时候用 const 修饰, 并赋初值为 101
从此以后, 就不能再给 a 赋值了
a=111;//错误的
const 可以修饰指针, 这个在以后课程中重点讲解
4. auto
int a;和auto int a 是等价的, auto 关键字现在基本不用
5. extern
是外部的意思, 一般用于函数和全局变量的声明, 这个在后面的课程中, 会用到
2.3控制语句相关的关键字
if 、 else 、 break、 continue、 for 、 while、 do、 switch case
goto、 default
2.4其他关键字
sizeof、 typedef、 volatile
1、 sizeof
使用来测变量、 数组的占用存储空间的大小(字节数)
例 3:
int a=10;
int num;
num=sizeof(a);
2、 typedef
重命名相关的关键字
关键字 , 作用是给一个已有的类型, 重新起个类型名, 并没有创造一个新的类型
以前大家看程序的时候见过类似的变量定义方法
INT16 a;
U8 ch;
INT32 b;
大家知道, 在 c 语言中没有 INT16 U8 这些关键字
INT16 U8 是用 typedef 定义出来的新的类型名, 其实就是 short int 及 unsigned char 的别名
typedef 起别名的方法:
1、 用想起名的类型定义一个变量
short int a;
2、 用新的类型名替代变量名
short int INT16;
3、 在最前面加 typedef
typedef short int INT16;
4: 就可以用新的类型名定义变量了
INT16 b;和 short int b;//是一个效果
例 4:
#include <stdio.h>
//short int b;
//short int INT16;
typedef short int INT16;
int main(int argc, char *argv[])
{
short int a=101;
INT16 c=111;
printf("a=%d\n",a);
printf("c=%d\n",c);
return 0;
}
3、 volatile
易改变的意思
用 volatile 定义的变量, 是易改变的, 即告诉 cpu 每次用 volatile 变量的时候, 重新去内存中取
保证用的是最新的值,而不是寄存器中的备份。
volatile 关键字现在较少适用
volatile int a=10;
扩展知识:
命名规则:
在 c 语言中给变量和函数起名的时候, 由字母、 数字、 下划线构成
必须以字母或者下滑线开头
例 5:
int a2;//正确的
int a_2;//正确的
int _b;//正确的
int 2b;// 错误的
int $a2;//错误的
注意: 起名的时候要求见名知意
Linux 风格
stu_num
驼峰风格
StuNum
大小写敏感
int Num;
int num;
3.数据类型
3.1基本类型
char 、 short int 、 int、 long int、 float、 double
3.2构造类型
概念:
由若干个相同或不同类型数据构成的集合, 这种数据类型被称为构造类型
例: int a[10];
数组、 结构体、 共用体、 枚举
3.3常量和变量
常量: 在程序运行过程中, 其值不可以改变的量
例: 100 ‘a’ “hello”
整型 100, 125, -100, 0
实型 3.14 , 0.125f, -3.789
字符型 ‘a’ ,‘b’ ,‘2’
字符串 “a” ,“ab” , “1232”
ASCII 码表
例 6:
#include <stdio.h>
int main(int argc, char *argv[])
{
unsigned int i;
for(i=0;i<=255;i++)
{
printf("%d %c ",i,i);
if(i%10==0)
printf("\n");
}
return 0;
}
变量: 其值可以改变的量被称为变量
int a=100;
a=101;
3.4整型数据
3.4.1整型常量
(按进制分) :
十进制: 以正常数字 1-9 开头, 如 457 789
八进制: 以数字 0 开头, 如 0123
十六进制: 以 0x 开头, 如 0x1e
a=10, b=11,c=12, d=13,e=14,f=15
3.4.2整型变量
有/无符号短整型(un/signed) short(int) 2 个字节
有/无符号基本整型(un/signed) int 4 个字节
有/无符号长整型(un/signed) long (int) 4 个字节 (32 位处理器)
3.5实型数据(浮点型)
3.5.1实型常量
实型常量也称为实数或者浮点数
十进制形式: 由数字和小数点组成:0.0、 0.12、 5.0
指数形式: 123e3 代表 123*10 的三次方
123e-3
不以 f 结尾的常量是 double 类型
以 f 结尾的常量(如 3.14f)是 float 类型
3.5.2实型变量
单精度(float)和双精度(double)3.1415926753456
float 型: 占 4 字节, 7 位有效数字,指数-37 到 38
3333.333 33
double 型: 占 8 字节, 16 位有效数字,指数-307 到 308
3.6字符数据
3.6.1字符常量
直接常量: 用单引号括起来, 如: 'a'、 'b'、 ’0’等.
转义字符: 以反斜杠“\” 开头, 后跟一个或几个字符、 如'\n','\t'等, 分别代表换行、 横向跳格.
‘\\’表示的是\ ‘%%’ ‘\’’
3.6.2字符变量
用 char 定义, 每个字符变量被分配一个字节的内存空间
字符值以 ASCII 码的形式存放在变量的内存单元中;
注: char a;
a = 'x';
a 变量中存放的是字符'x'的 ASCII :120
即 a=120 跟 a='x'在本质上是一致的.
例 7:
#include<stdio.h>
int main(int argc,char *argv[])
{
char a='x';
char b=120;
printf("a=%c\n",a);
printf("b=%c\n",b);
return 0;
}
3.7字符串常量
是由双引号括起来的字符序列, 如“CHINA” 、 ”哈哈哈”
“C program” , “$12.5” 等都是合法的字符串常量.
字符串常量与字符常量的不同
‘a’为字符常量, ”a”为字符串常量
每个字符串的结尾, 编译器会自动的添加一个结束标志位'\0',即“a” 包含两个字符‘a’ 和’ \0’
3.8格式化输出字符:
%d 十进制有符号整数
%u 十进制无符号整数
%x 以十六进制表示的整数 %o 以八进制表示的整数
%f float 型浮点数
%lf double 型浮点数
%e 指数形式的浮点数
%s 字符串
%c 单个字符
%p 指针的值
特殊应用:
%3d:要求宽度为 3 位, 如果不足 3 位, 前面空格补齐;如果足够 3 位, 此语句无效
%03d: 要求宽度为 3 位, 如果不足 3 位, 前面 0 补齐;如果足够 3 位, 此语句无效
%-3d: 要求宽度为 3 位, 如果不足 3 位, 后面空格补齐;如果足够 3 位, 此语句无效
%.2f: 小数点后只保留 2 位
3.8类型转换
数据有不同的类型, 不同类型数据之间进行混合运算时必然涉及到类型的转换问题.
3.8.1转换的方法有两种
自动转换
遵循一定的规则,由编译系统自动完成.
自动转换的原则
1、 占用内存字节数少(值域小)的类型, 向占用内存字节数多(值域大)的类型转换,以保证精度不降低.
2、 转换方向:
1) 当表达式中出现了 char 、 short int 、 int 类型中的一种或者多种, 没有其他类型了,参加运算的成员全部变成 int 类型的参加运算, 结果也是 int 类型的‘
例 8:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%d\n",5/2);
return 0;
}
2) 当表达式中出现了带小数点的实数, 参加运算的成员全部变成 double 类型的参加运算, 结果也是
double 型。
例 9:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("%lf\n",5.0/2);
return 0;
}
3) 当表达式中有有符号数 也有无符号数, 参加运算的成员变成无符号数参加运算结果也是无符号数.(表达式中无实数)
例 10:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a=-8;
unsigned int b=7;
if(a+b>0)
{
printf("a+b>0\n");
}
else
{
printf("a+b<=0\n");
}
printf("%x\n",(a+b));
printf("%d\n",(a+b));
return 0;
}
4) 在赋值语句中等号右边的类型自动转换为等号左边的类型
例 11:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a;
float b=5.8f;//5.8 后面加 f 代表 5.8 是 float 类型, 不加的话, 认为是 double 类型
a=b;
printf("a=%d\n",a);
return 0;
}
5) 注意自动类型转换都是在运算的过程中进行临时性的转换, 并不会影响自动类型转换的变量的值和其
类型
例 12:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a;
float b=5.8f;//5.8 后面加 f 代表 5.8 是 float 类型, 不加的话, 认为是 double 类型
a=b;
printf("a=%d\n",a);
printf("b=%f\n",b);//b 的类型依然是 float 类型的, 它的值依然是 5.8
return 0;
}
强制类型转换:
把表达式的运算结果强制转换成所需的数据类型
强制转换:
通过类型转换运算来实现 (类型说明符) (表达式)
功能:
把表达式的运算结果强制转换成类型说明符所表示的类型
例如:
(float)a; // 把 a 的值转换为实型
(int)(x+y); // 把 x+y 的结果值转换为整型
注意:类型说明符必须 加括号
例 13:
#include <stdio.h>
int main(int argc, char *argv[])
{
float x=0;
int i=0;
x=3.6f;
i = x;
i = (int)x;
printf("x=%f,i=%d\n",x,i);
return 0;
}
说明:无论是强制转换或是自动转换, 都只是为了本次运算的需要, 而对变量的数据长度进行的临时性转换,而不改变数据定义的类型以及它的值
3.9指针
4.控制语句相关关键字讲解
4.1 if 语句
形式1)
if(条件表达式)
{//复合语句, 若干条语句的集合
语句 1;
语句 2;
}
如果条件成立执行大括号里的所有语句, 不成立的话大括号里的语句不执行
例 20:
#include<stdio.h>
int main()
{
int a=10;
if(a>5)
{
printf("a>5\n");
}
return 0;
}
形式2)
if(条件表达式)
{ }
else
{ }
if else 语句的作用是, 如果 if 的条件成立, 执行 if 后面{}内的语句, 否则执行 else 后的语句
例 21:
#include<stdio.h>
int main()
{
int a=10;
if(a>5)
{
printf("a>5\n");
千锋教育——用良心做教育 http://www.mobiletrain.org/
千锋教育——智能物联网+嵌入式培训 免费咨询: 400-811-9990
}
else
{
printf("a<=5\n");
}
eturn 0;
}
注意 if 和 else 之间只能有一条语句, 或者有一个复合语句, 否则编译会出错
例 22:
if()
语句 1;
语句 2;
else
语句 3;
语句 4;
错误: if 和 else 之间只能有一条语句,如果有多条语句的话加大括号
例 23:
if()
{
语句 1;
语句 2;
}
else
{
语句 3;
语句 4;
}
正确
形式3)
if(条件表达式)
{ }
else if(条件表达式)
{ }
else if(条件表达式)
{ }
else
{ }
在判断的时候, 从上往下判断, 一旦有成立的表达式, 执行对应的复合语句,
下边的就不再判断了, 各个条件判断是互斥的
例 24:
#include <stdio.h>
int main(void)
{
char ch;
float score = 0;
printf("请输入学生分数:\n");
scanf("%f",&score);
if(score<0 || score >100)
{
printf("你所输入的信息有错\n");
return 0;
}
else if( score<60)
{
ch = 'E';
}
else if ( score < 70 )
{
ch = 'D';
}
else if ( score < 80 )
{
ch = 'C';
}
else if ( score < 90 )
{
ch = 'B';
}
4lse
{
ch = 'A';
}
printf("成绩评定为: %c\n",ch);
return 0;
}
4.2 switch 语句
switch(表达式) //表达式只能是字符型或整型的(short int int long int)
{
case 常量表达式1:
语句1;
break;
case 常量表达式2:
语句2;
break;
default: 语句3; break;
}
注意: break 的使用
例 25:
#include <stdio.h>
int main(int argc, char *argv[])
{
int n;
printf("请输入一个 1~7 的数\n");
scanf("%d",&n);
switch(n)
{
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
printf("星期六\n");
break;
case 7:
printf("星期天\n");
break;
default:
printf("您的输入有误, 请输入 1~7 的数\n");
break;
}
return 0;
}
4.3 循环控制语句相关的关键字
4.3.1 for 循环
for(表达式 1;表达式 2;表达式 3)
{
//复合语句, 循环体
}
第一次进入循环的时候执行表达式 1, 表达式 1 只干一次,
表达式 2, 是循环的条件, 只有表达式 2 为真了, 才执行循环体, 也就是说每次进入循环体之前要判断表达式 2 是否为真。
每次执行完循环体后, 首先执行表达式 3
例 25: for 循环求 0~100 的和
#include <stdio.h>
int main(void)
{
int i;
int sum=0;
for(i=1;i<=100;i++)
{
sum = sum+i;
}
printf("sum=%d\n",sum);
return 0;
}
例26:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i,j;
for(i=1;i<=9;i++)
{
for(j=1;j<=i;j++)
{
printf("%d*%d=%d ",i,j,i*j);
}
printf("\n");
}
return 0;
}
4.3.2 while 循环
形式 1:
while(条件表达式)
{
//循环体, 复合语句
}
//进入 while 循环的时候, 首先会判断条件表达式是否为真, 为真进入循环体, 否则退出循环
例 27:
#include <stdio.h>
int main(void)
{
int i=1;
int sum=0;
while(i<=100)
{
sum = sum+i;
i++;
}
printf("sum=%d\n",sum);
return 0;
}
形式 2 : do
do{
//循环体
}while(条件表达式);
先执行循环体里的代码, 然后去判断条件表达式是否为真, 为真再次执行循环体, 否则退出循环
例 28:
#include <stdio.h>
int main(void)
{
int i=1;
int sum=0;
do
{
sum = sum+i;
i++;
}while(i<=100);
printf("sum=%d\n",sum);
return 0;
}
形式 1 和形式 2 的区别是, 形式 1 先判断在执行循环体, 形式 2 先执行循环体, 再判断
break 跳出循环
continue 结束本次循环, 进入下一次循环
例 29:
#include <stdio.h>
int main(void)
{
int i;
int sum=0;
for(i=1;i<=100;i++)
{
if(i==10)
break;//将 break 修改成 continue 看效果
sum = sum+i;
}
printf("sum=%d\n",sum);
return 0;
}
return 返回函数的意思。 结束 return 所在的函数,在普通函数中, 返回到被调用处, 在 main 函数中的话, 结束程序
4.3.3 goto
例 30:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("test000000000000000000\n");
printf("test1111111111111111\n");
goto xiutao
printf("test222222222222222222\n");
printf("test3333333333333333\n");
printf("test444444444444444444444\n");
printf("test55555555555555555555\n");
xiutao:
printf("test66666666666666666\n");
return 0;
}