参考:【itheima】
[TOC]
C语言概述 第一个C程序 Hello World 1 2 3 4 5 6 7 #include <stdio.h> int main () { printf ("hello world\n" ); return 0 ; }
gcc编译器 1) gcc编译器介绍
编译器是将高级计算机语言翻译为低级机器语言的程序。
gcc(GNU Compiler Collection,GNU 编译器套件),是由 GNU 开发的编程语言编译器。gcc原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,gcc同样适用于微软的Windows。
gcc最初用于编译C语言,随着项目的发展gcc已经成为了能够编译C、C++、Java、Ada、fortran、Object C、Object C++、Go语言的编译器大家族。
2) 编译命令使用
格式
1 2 gcc [-option1] ... <filename> g++ [-option1] ... <filename>
常用选项说明
选项
含义
-o file
指定生成的输出文件名为file
-E
只进行预处理
-S(大写)
只进行预处理和编译
-c(小写)
只进行预处理、编译和汇编
使用(Linux下):
1 2 3 gcc hello.c //没有指定可执行程序文件名,默认生成a.out ./a.out //执行 gccc hello.c -o hello //指定名字
3)win下gcc环境配置
代码分析 1 2 3 4 5 6 7 1. #include< > 与 #include ""的区别: < > 表示系统直接按系统指定的目录检索 "" 表示系统先在 "" 指定的路径(没写路径代表当前路径)查找头文件,如果找不到,再按系统指定的目录检索 2. return语句 main定义的时候前面是void,那么return后面什么也不需要写 在main函数中return 0代表程序执行成功,return -1代表程序执行失败 int main()和void main()在C语言中是一样的,但C++只接受int main这种定义方式
system函数 使用
1 2 3 4 5 6 7 #include <stdlib.h> int system(const char *command); 功能:在已经运行的程序中执行另外一个外部程序 参数:外部可执行程序名字 返回值: 成功:不同系统返回值不一样 失败:通常是 - 1
示例
1 2 3 4 5 6 7 8 #include <stdio.h> #include <stdlib.h> int main () { system("ls" ); return 0 ; }
C语言编译过程 C程序编译步骤 1 2 3 4 5 4步: 1. 预处理:宏定义展开、头文件展开、条件编译等,同时将代码中的注释删除,这里并不会检查语法 2. 编译:检查语法,将预处理后文件编译生成汇编文件 3. 汇编:将汇编文件生成目标文件(二进制文件) 4. 链接:C语言写的程序是需要依赖各种库的,所以编译之后还需要把库链接到最终的可执行程序中去
gcc编译过程 分步编译
1 2 3 4 预处理:gcc -E hello.c -o hello.i 编 译:gcc -S hello.i -o hello.s 汇 编:gcc -c hello.s -o hello.o 链 接:gcc hello.o -o hello_elf
选项
含义
-E
只进行预处理
-S(大写)
只进行预处理和编译
-c(小写)
只进行预处理、编译和汇编
-o file
指定生成的输出文件名为 file
文件后缀
含义
.c
C 语言文件
.i
预处理后的 C 语言文件
.s
编译后的汇编文件
.o
编译后的目标文件
一步编译
1 gcc hello.c -o demo //经过:预处理、编译、汇编、链接的过程
集成开发环境IDE Qt Creator Microsoft Visual Studio 数据类型 常量与变量 32个关键字 1 2 3 4 5 6 7 8 9 10 11 1. 数据类型关键字(12个): char short int long float double unsigned signed struct enum void 2. 控制语句关键字(12个): A循环语句 for do while break continue B条件语句 if else goto C开关语句 switch case default D返回语句 return 3. 存储类型关键字(5个): auto extern register static const 4. 其它关键字(3个): sizeof typedef volatile
数据类型 数据类型的作用:编译器预算对象(变量)分配的内存空间大小。
常量
整型常量
100,200,-100,0
实型常量
3.14 , 0.125,-3.123
字符型常量
‘a’,‘b’,‘1’,‘\n’
字符串常量
“a”,“ab”,“12356”
变量 1 2 3 4 5 6 1. 变量在编译时为其分配相应的内存空间 2. 可以通过其名字和地址访问相应内存 3. 声明和定义区别 声明变量不需要建立存储空间,如:extern int a; 定义变量需要建立存储空间,如:int b; int b 它既是声明,同时又是定义
使用示例 1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> #define MAX 10 int main () { int a; const int b = 10 ; a = MAX; a = 123 ; printf ("%d\n" , a); return 0 ; }
进制 C语言如何表示相应进制数
十进制
以正常数字1-9开头,如123
八进制
以数字0开头,如0123
十六进制
以0x开头,如0x123
二进制
C语言不能直接书写二进制数
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { int a = 123 ; int b = 0123 ; int c = 0xABC ; printf ("十进制:%d\n" ,a ); printf ("八进制:%o\n" , b); printf ("十六进制:%x\n" , c); return 0 ; }
计算机内存数值存储方式 原码 1 2 3 4 一个数的原码(原始的二进制码)有如下特点: - 最高位做为符号位,0表示正,为1表示负 - 其它数值部分就是数值本身绝对值的二进制数 - 负数的原码是在其绝对值的基础上,最高位变为1
十进制数
原码
+15
0000 1111
-15
1000 1111
+0
0000 0000
-0
1000 0000
原码不便于加减运算
反码 1 2 对于正数,反码与原码相同 对于负数,符号位不变,其它部分取反(1变0,0变1)
十进制数
反码
+15
0000 1111
-15
1111 0000
+0
0000 0000
-0
1111 1111
反码运算也不方便,通常用来作为求补码的中间过渡。
补码 1 2 3 4 5 在计算机系统中,数值一律用补码来存储。 补码特点: 1. 对于正数,原码、反码、补码相同 2. 对于负数,其补码为它的反码加1 3. 补码符号位不动,其他位求反,最后整个数加1,得到原码
十进制数
补码
+15
0000 1111
-15
1111 0001
+0
0000 0000
-0
0000 0000
1 2 3 4 5 6 7 8 9 10 11 12 #include <stdio.h> int main () { int a = -15 ; printf ("%x\n" , a); return 0 ; }
补码的意义 示例1:用8位二进制数分别表示+0和-0
十进制数
原码
+0
0000 0000
-0
1000 0000
十进制数
反码
+0
0000 0000
-0
1111 1111
但是如果以补码方式存储,补码统一了零的编码:
十进制数
补码
+0
0000 0000
-0
10000 0000 //由于只用8位描述,最高位1丢弃,变为0000 0000
示例2:计算9-6的结果
以原码方式相加:
十进制数
原码
9
0000 1001
-6
1000 0110
结果为1000 1111 = -15,不正确。
以补码方式相加:
十进制数
补码
9
0000 1001
-6
1111 1010
相加为1 0000 0001 益处,剩余8位二进制表示的是3,正确。
在计算机系统中,数值一律用补码来存储 ,主要原因是:
1 2 3 4 统一了零的编码 将符号位和其它位统一处理 将减法运算转变为加法运算 两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃
sizeof关键字 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include <stdio.h> int main () { int a; int b = sizeof (a); printf ("b = %d\n" , b); size_t c = sizeof (a); printf ("c = %u\n" , c); return 0 ; }
整型:int 整型变量的定义和输出
打印格式
含义
%d
输出一个有符号的10进制int类型
%o(字母o)
输出8进制的int类型
%x
输出16进制的int类型,字母以小写输出
%X
输出16进制的int类型,字母以大写写输出
%u
输出一个10进制的无符号数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <stdio.h> int main () { int a = 123 ; int b = 0567 ; int c = 0xabc ; printf ("a = %d\n" , a); printf ("8进制:b = %o\n" , b); printf ("10进制:b = %d\n" , b); printf ("16进制:c = %x\n" , c); printf ("16进制:c = %X\n" , c); printf ("10进制:c = %d\n" , c); unsigned int d = 0xffffffff ; printf ("有符号方式打印:d = %d\n" , d); printf ("无符号方式打印:d = %u\n" , d); return 0 ; }
整型变量的输入 1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { int a; printf ("请输入a的值:" ); scanf ("%d" , &a); printf ("a = %d\n" , a); return 0 ; }
short、int、long、long long
数据类型
占用空间
short(短整型)
2字节
int(整型)
4字节
long(长整形)
Windows为4字节,Linux为4字节(32位),8字节(64位)
long long(长长整形)
8字节
注意
1 当一个小的数据类型赋值给一个大的数据类型,不会出错,因为编译器会自动转化。但当一个大的类型赋值给一个小的数据类型,那么就可能丢失高位。
整型常量
所需类型
10
代表int类型
10l, 10L
代表long类型
10ll, 10LL
代表long long类型
10u, 10U
代表unsigned int类型
10ul, 10UL
代表unsigned long类型
10ull, 10ULL
代表unsigned long long类型
打印格式
含义
%hd
输出short类型
%d
输出int类型
%l
输出long类型
%ll
输出long long类型
%hu
输出unsigned short类型
%u
输出unsigned int类型
%lu
输出unsigned long类型
%llu
输出unsigned long long类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 #include <stdio.h> int main () { short a = 10 ; int b = 10 ; long c = 10l ; long long d = 10l l; printf ("sizeof(a) = %u\n" , sizeof (a)); printf ("sizeof(b) = %u\n" , sizeof (b)); printf ("sizeof(c) = %u\n" , sizeof (c)); printf ("sizeof(c) = %u\n" , sizeof (d)); printf ("short a = %hd\n" , a); printf ("int b = %d\n" , b); printf ("long c = %ld\n" , c); printf ("long long d = %lld\n" , d); unsigned short a2 = 20u ; unsigned int b2 = 20u ; unsigned long c2= 20u l; unsigned long long d2 = 20u ll; printf ("unsigned short a = %hu\n" , a2); printf ("unsigned int b = %u\n" , b2); printf ("unsigned long c = %lu\n" , c2); printf ("unsigned long long d = %llu\n" , d2); return 0 ; }
有符号数和无符号数区别 1) 有符号数
有符号数是最高位为符号位,0代表正数,1代表负数。
1 2 3 4 5 6 7 8 9 10 #include <stdio.h> int main () { signed int a = -1089474374 ; printf ("%X\n" , a); return 0 ; }
2) 无符号数
无符号数最高位不是符号位,而就是数的一部分,无符号数不可能是负数。
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <stdio.h> int main () { unsigned int a = 3236958022 ; printf ("%X\n" , a); return 0 ; }
3) 有符号和无符号整型取值范围
字符型:char 字符变量的定义和输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <stdio.h> int main () { char ch = 'a' ; printf ("sizeof(ch) = %u\n" , sizeof (ch)); printf ("ch[%%c] = %c\n" , ch); printf ("ch[%%d] = %d\n" , ch); char A = 'A' ; char a = 'a' ; printf ("a = %d\n" , a); printf ("A = %d\n" , A); printf ("A = %c\n" , 'a' - 32 ); printf ("a = %c\n" , 'A' + 32 ); ch = ' ' ; printf ("空字符:%d\n" , ch); printf ("A = %c\n" , 'a' - ' ' ); printf ("a = %c\n" , 'A' + ' ' ); return 0 ; }
字符变量的输入 1 2 3 4 5 6 7 8 9 10 11 #include <stdio.h> int main () { char ch; printf ("请输入ch的值:" ); scanf ("%c" , &ch); printf ("ch = %c\n" , ch); return 0 ; }
ASCII对照表
ASCII 值
控制字符
ASCII值
字符
ASCII值
字符
ASCII值
字符
0
NUT
32
(space)
64
@
96
、
1
SOH
33
!
65
A
97
a
2
STX
34
“
66
B
98
b
3
ETX
35
#
67
C
99
c
4
EOT
36
$
68
D
100
d
5
ENQ
37
%
69
E
101
e
6
ACK
38
&
70
F
102
f
7
BEL
39
,
71
G
103
g
8
BS
40
(
72
H
104
h
9
HT
41
)
73
I
105
i
10
LF
42
*
74
J
106
j
11
VT
43
+
75
K
107
k
12
FF
44
,
76
L
108
l
13
CR
45
-
77
M
109
m
14
SO
46
.
78
N
110
n
15
SI
47
/
79
O
111
o
16
DLE
48
0
80
P
112
p
17
DCI
49
1
81
Q
113
q
18
DC2
50
2
82
R
114
r
19
DC3
51
3
83
S
115
s
20
DC4
52
4
84
T
116
t
21
NAK
53
5
85
U
117
u
22
SYN
54
6
86
V
118
v
23
TB
55
7
87
W
119
w
24
CAN
56
8
88
X
120
x
25
EM
57
9
89
Y
121
y
26
SUB
58
:
90
Z
122
z
27
ESC
59
;
91
[
123
{
28
FS
60
<
92
/
124
|
29
GS
61
=
93
]
125
}
30
RS
62
>
94
^
126
`
31
US
63
?
95
_
127
DEL
1 2 3 ASCII 码大致由以下两部分组成: 1. ASCII 非打印控制字符: ASCII 表上的数字 0-31 分配给了控制字符,用于控制像打印机等一些外围设备。 2. ASCII 打印字符:数字 32-126 分配给了能在键盘上找到的字符,当查看或打印文档时就会出现。数字 127 代表 Del 命令。
转义字符
转义字符
含义
ASCII** 码值(十进制)**
\a
警报
007
\b
退格(BS) ,将当前位置移到前一列
008
\f
换页(FF),将当前位置移到下页开头
012
\n
换行(LF) ,将当前位置移到下一行开头
010
\r
回车(CR) ,将当前位置移到本行开头
013
\t
水平制表(HT) (跳到下一个TAB位置)
009
\v
垂直制表(VT)
011
\
代表一个反斜线字符”"
092
'
代表一个单引号(撇号)字符
039
"
代表一个双引号字符
034
?
代表一个问号
063
\0
数字0
000
\ddd
8进制转义字符,d范围0~7
3位8进制
\xhh
16进制转义字符,h范围09,af,A~F
3位16进制
注意: \a–\v 为不可打印字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> int main () { printf ("abc" ); printf ("\refg\n" ); printf ("abc" ); printf ("\befg\n" ); printf ("%d\n" , '\123' ); printf ("%d\n" , '\x23' ); return 0 ; }
数值溢出 1 2 - 当超过一个数据类型能够存放最大的范围时,数值会溢出。 - 有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。
数据类型
占用空间
取值范围
char
1字节
-128到 127(-27 ~ 27-1)
unsigned char
1字节
0 到 255(0 ~ 28-1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <stdio.h> int main () { char ch; ch = 0x7f + 2 ; printf ("%d\n" , ch); unsigned char ch2; ch2 = 0xff +1 ; printf ("%u\n" , ch2); ch2 = 0xff + 2 ; printf ("%u\n" , ch2); return 0 ; }
实型(浮点型):float、double
数据类型
占用空间
有效数字范围
float
4字节
7位有效数字
double
8字节
15~16位有效数字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <stdio.h> int main () { float a = 3.14f ; double b = 3.14 ; printf ("a = %f\n" , a); printf ("b = %lf\n" , b); a = 3.2e3 f; printf ("a1 = %f\n" , a); a = 100e-3 f; printf ("a2 = %f\n" , a); a = 3.1415926f ; printf ("a3 = %f\n" , a); return 0 ; }
类型限定符
限定符
含义
extern
声明一个变量,extern声明的变量没有建立存储空间。 extern int a;
const
定义一个常量,常量的值不能修改。 const int a = 10;
volatile
防止编译器优化代码
register
定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。
字符串格式化输出和输入 字符串常量 1 2 3 - 字符串是内存中一段连续的char空间,以'\0'(数字0)结尾。 - 字符串常量与字符常量的不同:每个字符串的结尾,编译器会自动的添加一个结束标志位'\0',即 "a" 包含两个字符'a'和’\0’
printf函数和putchar函数 printf是输出一个字符串,putchar输出一个char。
printf格式字符:
打印格式
对应数据类型
含义
%d
int
接受整数值并将它表示为有符号的十进制整数
%hd
short int
短整数
%hu
unsigned short
无符号短整数
%o
unsigned int
无符号8进制整数
%u
unsigned int
无符号10进制整数
%x,%X
unsigned int
无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
%f
float
单精度浮点数
%lf
double
双精度浮点数
%e,%E
double
科学计数法表示的数,此处”e”的大小写代表在输出时用的”e”的大小写
%c
char
字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
%s
char *
字符串。输出字符串中的字符直至字符串中的空字符(字符串以’\0‘结尾,这个’\0’即空字符)
%p
void *
以16进制形式输出指针
%%
%
输出一个百分号
printf附加格式:
字符
含义
l(字母l)
附加在d,u,x,o前面,表示长整数
-
左对齐
m(代表一个整数)
数据最小宽度
0(数字0)
将输出的前面补上0直到占满指定列宽为止不可以搭配使用-
m.n(代表一个整数)
m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <stdio.h> int main () { int a = 100 ; printf ("a = %d\n" , a); printf ("%p\n" , &a); printf ("%%d\n" ); char c = 'a' ; putchar (c); long a2 = 100 ; printf ("%ld, %lx, %lo\n" , a2, a2, a2); long long a3 = 1000 ; printf ("%lld, %llx, %llo\n" , a3, a3, a3); int abc = 10 ; printf ("abc = '%6d'\n" , abc); printf ("abc = '%-6d'\n" , abc); printf ("abc = '%06d'\n" , abc); printf ("abc = '%-06d'\n" , abc); double d = 12.3 ; printf ("d = \' %-10.3lf \'\n" , d); return 0 ; }
scanf函数与getchar函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 #include <stdio.h> int main () { char ch1; char ch2; char ch3; int a; int b; printf ("请输入ch1的字符:" ); ch1 = getchar(); printf ("ch1 = %c\n" , ch1); getchar(); printf ("请输入ch2的字符:" ); ch2 = getchar(); printf ("\'ch2 = %ctest\'\n" , ch2); getchar(); printf ("请输入ch3的字符:" ); scanf ("%c" , &ch3); printf ("ch3 = %c\n" , ch3); printf ("请输入a的值:" ); scanf ("%d" , &a); printf ("a = %d\n" , a); printf ("请输入b的值:" ); scanf ("%d" , &b); printf ("b = %d\n" , b); return 0 ; }
运算符与表达式