#include
int main(int argc, const char *argv[])
{
printf("hello world\n");
return 0;
}
注意:
- 所有的标点符号必须在英文状态下输入
- 单词不要写错
- 注意空格
创建 C语言
程序步骤:
1、创建一个文档,以 .c
作为后缀名
2、在该文档中编写以下代码
3、使用gcc编译器编译该程序
4、执行编译生成的可执行文件
编译顺序:
编译时
代码从文件头开始检查
运行时
程序在运行时会寻找main函数
在main函数中从上向下依次执行
作用:解释说明
特点:不会影响代码的运行
语法:
单行注释
//注释的内容
块注释
/*
注释的内容
多行
*/
注意:不能嵌套
作用:给控制台输出内容
语法:
printf("输出的内容", 位置1, 位置2,..);
占位符:
%d, 十进制有符号整数
%u, 十进制无符号整数
%x, 以十六进制表示的整数
%o, 以八进制表示的整数
%f, float 型浮点数
%.2f, 小数点后保留2位
%lf, double 型浮点数
%e, 指数形式的浮点数
%s, 字符串
%c, 单个字符
%p, 指针的值
例:
要求:输出xxx今年xx岁,身高xxm
#include
int main(){
printf("%s今年%d岁,身高%fm","张三",18,1.76);
return 0;
}
概念:标记的符号,名称
变量名,函数名,数组名,枚举名,结构体名,...
命名规则(强制要求) :
不能使用数字开头
不能使用特殊符号,_与$除外
不能使用关键字
不能使用中文
命名风格(建议) :
驼峰命名法
大驼峰
写法:每个单词首字母大写
一般用于:枚举名,结构体名
小驼峰
写法:第一个单词首字母小写,其他单词首字母大写
一般用于:变量名,数字名,函数名等
全大写
写法:全大写
一般用于:常量名
全小写
写法:全小写
一般用于:文件夹名
Liunx风格命名法
多个单词之间使用下划线连接
比如: hello_world
short 短整形
int 整形
long 长整形
float 单精度浮点数
double 双精度浮点数
char 字符
struct 结构体
union 共用体
enum 枚举
signed 有符号
unsigned 无符号
void 空的返回值类型
register 寄存器存储
static 静态的
const 不可修改的
auto 自动
extern 声明
if
else
break
continue
for
while
do
switch
case
goto
default
sizeof 测量数据或数据类型的大小,单位是字节
typedef 给已知数类型起别名
volatile 用 volatile 定义的变量,是易改变的,即告诉 cpu 每次用volatile 变量的时候,
重新去内存中取保证用的是最新的值,而不是寄存器中的备份。
char 字符 1字节 8位
注意:
字符需要单引号包裹,一对单引号只能包裹一个字符
'a'
'中'
'ab' 错
特殊的字符
转意字符
\" 双引号
\' 单引号
\\ \
\n 换行
\t 制表
\r 回到行首符号
\a 发出警报
\0 字符串结束符
short 短正型 2字节 16位 -2^15~2^15-1
int 整形 4字节 32位 -2^31~2^31-1
long 长整形 4字节(32位)或8字节(64位) 32位或64位
float 单精度浮点型 4字节
double 双精度浮点型 8字节 (小数默认是double)
signed 有符号
unsigned 无符号
null 空
注意:
- 当值后加
l
表示为long型的数据,其他情况下整数默认为int- 当值后加
f
表为float型的数据,小数默认为doublesigned char char sigend int int sigend short int short unsigned int typedef int myint; volatile register 建议寄存器存储
临时记录一个值,可以被改变的数据
例:
需求:
使用变量分别记录人的姓名,性别,年龄,并在控制台打印,打印格式如
xxx 性别为xx,年龄为xx岁
记录的人有
t m 29
b w 27
#include
int main()
{
char name = 't';
char sex = 'm';
int age = 29;
printf("%c 性别为 %c,年龄为%d岁!\n", name, sex, age);
name = 'b';
sex = 'w';
age = 27;
printf("%c 性别为 %c,年龄为%d岁!\n", name, sex, age);
return 0;
}
声明(在某些特殊情况下才需进行)
定义(重点)
语法:
数据类型 变量名;
数据类型 变量名 = 值;
名词:
变量的第一次赋值称为变量的初始化
注意:
- 在
函数中定义
的变量为局部变量
,局部变量默认使用auto修改,此时默认值为一个随机数- 在
函数外定义
的变量为成员变量
,默认值为0例:
#include
//函数外 int main() { //函数中 } //函数外
使用
语法:
取值
变量名
改值
变量名 = 值;
练习:
#include
int main()
{
int age = 18;
char sex = 'm';
printf("%s今年%d岁,性别为%c\n","张三",age,sex);
age = 19;
sex = 'w';
printf("%s今年%d岁,性别为%c\n","张三",age,sex);
return 0;
}
注意:
1、局部变量可以与成员变量重名
2、当局部变量与成员变量重名时,优先使用局部变量
3、同一作用域下变量名不能相同
#include
/*
此处就是变量的声明
变量声明只是告知编译器有该变量,此时并不会为其开辟内存空间
*/
extern int num;
int main()
{
printf("num=%d\n",num);
return 0;
}
/*
变量的定义,编译器编译时会为其开辟内存空间
*/
int num = 10;
相关关键字:
#include
int main()
{
//for(int i = 0; i < 1000; i++){
//当变量为局部变量时
//变量默认就是有符号的
//signed int == int
//当变量为局部变量时等价
//sigened auto int == int
//auto int == int
unsigned int num = 10;
//建议将n02存储在寄存器中
register int n02 = 1;
//volatile强制要求从内存中取值
volatile int n03 = 2;
//typedef 给已经知道的数据类型起别名
typedef int myInt;
myInt n04 = 10;
printf("num=%d\n",n04);
//}
return 0;
}
小类型转换为大类型,无需特殊处理
//'a' 的数据类型为 char 占1字节
//int 占4字节
int num = 'a';
printf("num=%d\n",num);
注意:每一个字符都有对应的数字
ASCII码对照表:
- a~z:97-122
- A~Z:64-90
大类型转换为小类型,需强转,有风险
语法:
小类型变量名 = (小类型)大类型数值或变量
例:
int num = 'a';
char c = (char)num;
printf("c=%c\n",c);
二进制
0b二进制数
取值:
0 1
八进程
0八进制数
取值:
0~7
十六进制
0x十六进制数
取值:
0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f
注意:计算机在存储 8进制
或 16进制
数时按无符号数存储
十进制转换为二进制
口诀:十进制数除2,取余,直到商为0,余数倒读
如:
int num = 12;
12
2
-------
6 0
2
-------
3 0
2
-------
1 1
2
-------
0 1
12对应的2进制为:0000 0000 0000 0000 0000 0000 0000 1100
十进制转换为八进制
口诀:十进制数除8,取余,直到商为0,余数倒读
十进制转换为十六进制
口诀:十进制数除16,取余,直到商为0,余数倒读
如:
int num = 0b111010
111010
1 * 2^5 + 1 * 2^4 + 1 * 2^3 + 0 * 2^2 + 1*2^1 + 0*2^0
32 + 16 + 8 + 0 + 2 + 0
58
如:
int num = 0123;
1 * 8^2 + 2*8^1 + 3*8^0
64 + 16 + 3
83
如:
int num = 0x123;
1 * 16^2 + 2*16^1 + 3*16^0
256 + 32 + 3
291
数值对应的二进制数,最高位为符号位,整数为0,负数为1
int num = 1;
0000 0000 0000 0000 0000 0000 0000 0001
int n01 = -1;
1000 0000 0000 0000 0000 0000 0000 0001
正数三码合一,与原码相同
负数的反码等于原码符号位不动
,其他位取反
int num = 1;
原码: 0000 0000 0000 0000 0000 0000 0000 0001
反码: 0000 0000 0000 0000 0000 0000 0000 0001
int n01 = -1;
原码: 1000 0000 0000 0000 0000 0000 0000 0001
反码: 1111 1111 1111 1111 1111 1111 1111 1110
正数三码合一,与原码相同
负数的补码等于反码+1
int num = 1;
原码: 0000 0000 0000 0000 0000 0000 0000 0001
反码: 0000 0000 0000 0000 0000 0000 0000 0001
补码: 0000 0000 0000 0000 0000 0000 0000 0001
int n01 = -1;
原码: 1000 0000 0000 0000 0000 0000 0000 0001
反码: 1111 1111 1111 1111 1111 1111 1111 1110
补码: 1111 1111 1111 1111 1111 1111 1111 1111
注意:计算机底层以补码形式存储数据
补码的意义:
1、统一了正0与负0的编码
0原码:0000 0000 0000 0000 0000 0000 0000 0000
反码:0000 0000 0000 0000 0000 0000 0000 0000
补码:0000 0000 0000 0000 0000 0000 0000 0000-0
原码:1000 0000 0000 0000 0000 0000 0000 0000
反码:1111 1111 1111 1111 1111 1111 1111 1111
补码:0000 0000 0000 0000 0000 0000 0000 00002、此时减法就是+负数
1111 1111 被当做纯二进制看待时,是255,被当做补码看时是 -1
#include
int main(int argc, char const *argv[])
{
char c = 255; //1111 1111
int i = 255; //0000 0000 0000 0000 0000 0000 1111 1111
printf("c=%d, i=%d\n", c, i);
return 0;
}
//输出:c=-1, i=255
整数越界:
整数的存储是一个圈,越过了最大范围的值,会到最小范围那头。
整数是以纯二进制的方式进行计算的,所以:
1111 1111 + 1 ——> (1)0000 0000 ——> 0
0111 1111 + 1 ——> 1000 0000 ——> -128
1000 0000 - 1 ——> 0111 1111 ——> 127
#include
int main(int argc, char const *argv[])
{
char c = 127; //1111 1111
int i = 255; //0000 0000 0000 0000 0000 0000 1111 1111
c = c + 1;
printf("c=%d, i=%d\n", c, i);
return 0;
}
//输出:c=-128, i=255
计算机存储的是补码
,计算机取值是先将补码转换为源码
,在将源码转换为10进制数
例1:
int num = 0xf1 11 11 11;
计算机存储的num是:
1111 0001 0001 0001 0001 0001 0001 0001
计算机取出的num是:
补码:
1111 0001 0001 0001 0001 0001 0001 0001
反码:
1111 0001 0001 0001 0001 0001 0001 0000
原码:
1000 1110 1110 1110 1110 1110 1110 1111
例2:
char c = 0xf0;
补码: 1111 0000
反码: 1110 1111
原码: 1001 0000
- 1 * 2^4
- 16
+, -, *, /, %
++
注意:
++
++在前:
- 先自增,再参与运算
++在后:
- 先参与运算,再自增
例:
int a = 10; int b = ++a + 1; // 12 int b = a++ + 1; // 11
–
--在前:
先递减,再参与运算
--在后:
先参与运算,再递减
将等号右边的值赋值给左边的变量
=
如:
int a = 10;
int b = a;
int c = a + b;
+=
int a = 1;
int b = 2;
//a = a + b;
a += b;
-=
int a = 1;
int b = 2;
//a = a - b;
a -= b;
*=
int a = 1;
int b = 2;
//a = a * b;
a *= b;
/=
%=
<
1 < 10
int a = 1;
int b = 10;
a < b;
>
<=
>=
==
!
|| 短路或
有真为真,同假为假
int a = 1;
int b = 2;
int c = 3;
a < b || c < b;
&& 短路与
有假为假,同真的真
int a = 1;
int b = 2;
int c = 3;
a < b && c > b;
! 非
非真为假,非假为真
! a < b
! a > b
& 按位与
同1为1,有0为0
如:
int a = 8;
int b = 9;
int c = a & b;
1000
1001
------
1000
| 按位或
有1为1,同0为0
如:
int a = 8;
int b = 9;
int c = a | b;
1000
1001
------
1001
~ 取反
1为0,0为1
^ 按位异或
不同得1,相同得0
>> 右移
int num = 4;
int a = num >> 2;
100
001
<< 左移
int num = 4;
int a = num << 2;
100
10000
语法:
条件表达式1 ? 值1 : 值2;逻辑:
如果条件表达式1为真,取值1,反之取值2
例:
//获取a,b之间的最大值
int a = 10;
int b = 1;
int max = a > b ? a : b;
//获取a,b,c之间的最大值
int a = 10;
int b = 1;
int c = 3;
int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;
运算符优先级: