目录
1、开发环境的选择
2、c的概述
2.1、c语言的发展历史
2.2众多语言的特点
2.3、C语言的编程机制
2.4、编程规范
3、数据类型
3.1、基本数据类型
3.2、整型与浮点型
3.3、其他数据类型
4、位运算
4.1、位与字节的区别
4.2、二进制,八进制,十六进制
4.3、变量、常量
5、运算符与表达式
5.1、算术运算符
5.2、赋值运算符
5.3、关系运算符
5.4、逻辑运算符
5.5、三目运算符(条件运算符)
5.6、逗号运算符
5.7、 sizeof 运算符
5.8、 运算符的优先级
工预善其事,必先利其器,开发环境的选择就是学习工作的第一步。
1.1、在线编译工具
https://tool.lu/coderunner
支持几乎所有主流编程语言
http://www.dooccn.com/cpp/
支持多种语言编译
http://www.tutorialspoint.com/compile_cpp11_online.php
GNU中gcc编译
https://mp.csdn.net/postedit/89355619
编译器优化选项,适合多要求的在线编程任务。
1.2、本地编译工具
Visual Studio
各种功能都很全,包括常见的VB,C/C++,C#,Python开发等,软件都集成度很高,并且调试代码,项目管理都很方便
Dev-c++
安装包小,界面十分简洁。
默认语言好像是中文?对新手极度友好,默认字体和界面看着也比较舒服。
Linux中的vim
linux本身就安装vi和vim的编译器,linux如果需要更好的IDE,可以使用跨平台的IDE
Qt
Qt来写C/C++程序,他不仅有完善的IDE,方便的智能完成,还内嵌了gdb,调试起来很方便,感觉就和VS2005无异,更方便的是还集成了Git等版本控制插件,可以说是相当方便了。
1967年,剑桥大学的 Martin Richards 对CPL语言进行了简化,于是产生了BCPL(Basic Combined Pogramming Language)语言。
1970年,美国贝尔实验室的 Ken Thompson,以BCPL语言为基础,设计出很简单且很接近硬件的B语言(取BCPL的首字母),并且他用B语言写了第一个UNIX操作系统。
1972年,美国贝尔实验室 在B语言的基础上最终设计出了一种新的语言,他取了BCPL的第二个字母作为这种语言的名字,这就是C语言。
1977年Dennis M.Ritchie发表了不依赖于具体机器系统的C语言编译文本为使UNIX操作系统推广。
1978年由美国电话电报公司(AT&T)贝尔实验室正式发表了C语言,1990年,国际标准化组织ISO接受了89 ANSI C 为I SO C 的标准(ISO98993-1990)c89。
1994年,ISO修订了C语言的标准。
1995年,ISO对C90做了一些修订,即“1995基准增补1(ISO/IEC/9899/AMD1:1995)”。
1999年,ISO有对C语言标准进行修订,在基本保留原来C语言特征的基础上,针对应该的需要,增加了一些功能,尤其是对C++中的一些功能,命名为ISO/IEC9899:1999,c99。
2001年和2004年先后进行了两次技术修正。目前流行的C语言编译系统大多是以ANSI C为基础进行开发的,但不同版本的C编译系统所实现的语言功能和语法规则有略有差别。
C语言以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广,C语言贴近底层硬件因此执行效率高而且可移植性好,它是一种面向过程的编程思想,可以用来开发应用软件、驱动、操作系统等,C语言也是其它众多高级语言的鼻祖语言。
C++是C语言的超集,既保留了C语言的灵活性、便于移植等全部精华和特点,又添加了面向对象编程的支持,具有强大的编程功能,可方便地构造出模拟现实问题的实体和操作(class);编写出的程序具有结构清晰可读性好、易于扩充、运行效率高等优良特性,适合于各种应用软件、系统软件的程序设计。(如浏览器,游戏引擎等贴近底层的编程)
Java语言是一门面向对象编程语言,不仅吸收了C/C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java一般编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等 。(如各种大型网站,金融,通讯等服务端应用)
Python是一种解释型、交互性、弱类型的脚本语言且支持面向对象的跨平台编程语言,相比其他编程语言(比如 Java),Python 代码非常简单,上手非常容易,支持多种库。
编辑-->预处理--->编译--->汇编--->链接
编辑:通过编译器,实现C代码的编写(Linux中的vi),即编辑器提供了编写C代码的平台。
预处理:处理和#号相关的代码
(1)处理头文件
#include
将头文件展开3
(2)将宏定义 #define N 10
(3)将条件编译中满足的代码加入编译,不满足的代码不加入编译
#if
#else
#endif编译:将C语言代码编译成汇编代码。
汇编:将汇编代码编译生成二进制文件。
链接:将二进制文件与C语言库函数链接在一起生成一个可以被执行的二进制程序。
练习:gcc分步编译命令生成各个阶段的编译文件,并使用vim对这些文件完成查看
预处理:gcc -E hello.c -o hello.i
编译:gcc -S hello.c -o hello.s
汇编:gcc -c hello.c -o hello.o
链接: gcc hello.c -o hello
总结一下:计算机首先通过编译器将源代码转化成目标代码,然后再通过链接器将系统的标准启动代码、库代码和目标代码连接起来储存在同一个文件中形成可执行文件:
一个说明或一个语句占一行,例如:包含头文件、一个可执行语句结束都需要换行。
函数体内的语句要有明显缩进,通常以按一下Tab键为一个缩进。
括号要成对写,如果需要删除的话也要成对删除。
当一句可执行语句结束的时候末尾需要有分号。
代码中所有符号均为英文半角符号。
注释:多行注释/* 注释内容 */
单行注释 // 注释内容
数据类型 | 名称 | 字节 | 应用 | 示例 |
char | 字符型 | 1 | 存储字符 | char ch='a' |
int | 整型 | 4 | 存储整数 | int pb=22 |
float | 单精度型 | 4 | 存储小数点后6位(默认) | float sum=1.16 |
double | 双精度型 | 8 | 存储小输点后15位 | double num=3.1415926 |
注:数据类型的字节数与编译器有关(上面默认32位)
整型:不带小数的数字(int 、short int 、long int)
数据类型 | 名称 | 字节数 | 取值范围 |
int | 整型 | 4 | -2^31~2^31 - 1 |
short int | 短整型(int可以省略) | 4 | -2^31~2^31-1 |
long int | 长整型(int可以省略) | 8 | -2^63~2^63-1 |
unsigned int | 无符号整型 | 4 | 0~2^32-1 |
unsigned short int | 无符号短整型 | 4 | 0~2^32-1 |
unsigned long int | 无符号长整型 | 8 | 0~2^64-1 |
根据编译环境不同,所取范围有所差异,ANSI标准定义int 是占2字节,VC中占四字节。
浮点型:带小数的数字(float 、double、 long double)
数据类型 | 名称 | 字节数 | 取值范围 |
float | 单精度型 | 4 | -2^31~2^31 - 1 |
double | 双精度型 | 8 | -2^63~2^63-1 |
long double | 长双精度型 | 16 | -2^127~2^127-1 |
#include
#include
int main(void)
{
printf("sizeof char is %d\n", sizeof(char));
printf("sizeof short is %d\n", sizeof(short));
printf("sizeof int is %d\n", sizeof(int));
printf("sizeof long is %d\n", sizeof(long));
printf("sizeof float is %d\n", sizeof(float));
printf("sizeof double is %d\n", sizeof(double));
printf("sizeof bool is %d\n", sizeof(bool));
return 0;
}
泊尔类型bool
#include
bool 逻辑类型 1个字节 1 0 true false
在C语言中一个表达式最终的值为非0值即为真值
基本数据类型好文https://i.csdn.net/#/user-center/collection-list?type=1&spm=1000.2115.3001.7480
1字节(byte) = 8比特(bit)
(1)、比特 :
计算机专业术语,是信息量单位,是由英文BIT音译而来。二进制数的一位所包含的信息就是一比特,如二进制数0101就是4比特。
二进制数字中的位,信息量的度量单位,为信息量的最小单位,,只有两种状态:0和1。数字化音响中用电脉冲表达音频信号,“1”代表有脉冲,“0”代表脉冲间隔。如果波形上每个点的信息比特数越高,表达模拟信号就越精确,对音频信号信号还原能力越强。
(2)、字节:
字节是二进制数据的单位。一个字节通常8位长。但是,一些老型号计算机结构使用不同的长度。为了避免混乱,在大多数国际文献中,使用词代替byte。在多数的计算机系统中,一个字节是一个8位长的数据单位,大多数的计算机用一个字节表示一个字符、数字或其他字符。一个字节也可以表示一系列二进制位。
(3)、字长:
计算机的每个字所包含的位数称为字长,计算的字长是指它一次可处理的二进制数字的数目。一般地,大型计算机的字长为32-64位,小型计算机为12-32位,而微型计算机为4-16位。字长是衡量计算机性能的一个重要因素
进制:进制也就是进位计数制,是人为定义的带进位的计数方法,对于任何一种进制---X进制,就表示每一位上的数运算时都是逢X进一位。二进制就是逢二进一 ,十进制是逢十进一,以此类推,x进制就是逢x进位。
十进制D | 二进制B | 八进制O | 十六进制H |
0 | 0000 | 0 | 00 |
1 | 0001 | 1 | 01 |
2 | 0010 | 2 | 02 |
3 |
0011 | 3 | 03 |
4 | 0100 | 4 | 04 |
5 | 0101 | 5 | 05 |
6 | 0110 | 6 | 06 |
7 | 0111 | 7 | 07 |
8 | 1000 | 10 | 08 |
9 | 1001 | 11 | 09 |
10 | 1010 | 12 | 0A |
11 | 1011 | 13 | 0B |
12 | 1100 | 14 | 0C |
13 | 1101 | 15 | 0D |
14 | 1110 | 16 | 0E |
15 | 1111 | 17 | 0F |
基础位运算功能:
(1)清位:
unsigned char code = 0xfe(十六进制) ; //1111 1110(二进制)
将该数的第2和第3位清0:
code &= ~(1 << 2 | 1 << 3);
首先剖析一下为什么实现了位清0功能:
1 << 2 ---> 4(十进制) ---> 0100(二进制) ---> 0x4(十六进制)
1 << 3 ---> 8 ---> 1000 ---> 0x8
(1 << 2 | 1 << 3) ---> 相当于
0100
| 1000
--------
1100
~(1 << 2 | 1 << 3) ----> 相当于
~(0100 | 1000) ---> ~(1100) ---> 0000
也就是0xfe的第二位和第三位被清除了,但是第一位没有被清除,所以它还是1哦,也就是0xfe--->1111 1110--->此时应当是1111 0010--->后面的低四位是0010
接下来:
code &= ~(1 << 2 | 1 << 3); 也很简单:
----> code = code & (~(1 << 2 | 1 << 3))
1111 1110
& 1111 0010
-------------
1111 0010
在这里,就实现了一个清位的操作。
(2)置位:
unsigned char code = 0x34(十六进制); //0011 0100(二进制)
将该数的第1位和第7位置1
code |= (1 << 1 | 1 << 7);
首先剖析以下为什么实现了置位的功能:
1 << 1 ---> 2 ----> 0000 0010(二进制) ----> 0x2(十六进制)
1 << 7 ---> 128 ---> 1000 0000(二进制) ----> 0x80(十六进制)
所以 (1 << 1 | 1 << 7):
0000 0010
| 1000 0000
----------------
1000 0010
code |= (1 << 1 | 1 << 7);也很简单;
-----> code = code | (1 << 1 | 1 << 7);
0011 0100
| 1000 0010
------------------
1011 0110
(3)取反:
unsigned char code = 0xff ;
code = ~code ;
~(0xff) ---> ~(1111 1111) ----> 0
局部变量与全局变量
C语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。
局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。在复合语句中也可定义变量,其作用域只在复合语句范围内。
全局变量也称为外部变量,它是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件,其作用域是整个源程序。
变量:在程序运行过程中,值能够发生改变的量
注意:
(1)变量要先定义再使用
(2)变量的定义是为变量开辟存储空间
1.变量的定义:
数据类型 变量名;
数据类型:基本数据类型、构造数据类型
char int short long float double bool
变量名:
1.只能由字母、数字、下划线构成
2.不能以数字开头
3.作用域范围内变量名不能重名
4.变量名不能与关键字重名
5.变量名不要与库函数重名
变量作用域:
变量能够使用的范围
变量的作用域位于定义该变量最近的大括号内
变量生存周期:
变量从分配空间到空间被回收的整个过程
执行到变量定义被分配存储空间
变量作用域结束回收变量存储空间
2.变量的初始化:
未经初始化的变量为随机值(为内存中的随机值),因此变量最好都初始化。
初始化:定义变量时给变量初值,成为对变量的初始化。变量赋值的两种方式:
(1)、先声明再赋值
int a;//先声明
a=100;//再赋值
(2)、声明的同时赋值
int a = 100, b = 200, c = 300; 初始化 != 赋值3.整形变量:
用来存放整形数据的变量
int Num;
注意:
1.变量Num占4字节空间
2.Num变量只能存放int值域范围之内的数据,
超过值域范围值会发生错误
3.Num中数据的存储按照signed int存储(补码)
4.字符型变量:
char ch;
5.浮点型变量:
float f;
double d;在生活中很多信息适合用浮点类型数据表示,如:人的体重,商品的价格,圆周率等
#include
int a=20;//全局变量
int main(void)
{
float f=1.34;
double d=3.1415
int b=10;//局部变量
char ch;//定义一个名为ch的字符变量
ch='a';//给ch变量赋值
printf("%c\n",m);//打印变量
printf("%d %d\n",a,b);
return 0;
}
重点:类型转换:
1.显示类型转换(强制类型转换)
(数据类型)变量名
将变量强制转化为数据类型一次
2.隐式类型转换
混合数据类型计算时的隐式转换原则
两种不同类型数据进行数据运算和数据处理时需转换为同一
类型再进行数据处理
转换原则:
1.低精度向高精度转换
2.同种类型所占字节空间越大精度越高
3.浮点型精度 > 整形精度
4.无符号精度 > 有符号精度
5.char类型和short类型数据进行处理时转换为int类型
6.float类型数据处理时转换为double类型
常量:程序运行过程中,值不会发生改变的量
1.整形常量(默认为signed int类型)
123
123u unsigned int
123U unsigned int
123l long
123L long
123UL unsigned long
123ul unsigned long
2.浮点型常量(默认为double类型)
3.1415
3.1415f float
3.1415e-19
3.1415E-19
3.字符常量
'a'
'b'
'A'
'B'
'\n' 换行符
'\r' 回车符
'\b' 退格符
'\t' 横向制表符
'\v' 纵向制表符
'\a' 响铃
'\0' \0字符(字符串结束的标志)
'\\'
' '
'\'' '字符
'0' 字符0
'1' 字符1
'9' 字符9
'\050' 八进制50对应的字符
'\121' 八进制121对应的字符
'\x15' 十六进制15对应的字符
ASCII在32号以前的字符,用于通信控制、终端控制,不能在终端显示
如果强行打印将会出现乱码
ASCII码在32号以后的均为能够在终端界面显示的ASCII字符
注意:
0 '0' '\0'
0:数字0,内存空间存储0
'0':字符0,内存空间存储48对应的二进制
'\0':字符\0,内存空间存储0,为数字0对应的ASCII形式
结论:
0 == '\0'
0和'\0'值相同,类型有所区别
0、'\0' != '0'
'0'表示一个字符,ASCII码值为48与0、'\0'不等价
4.字符串常量
"abc" = 'a' + 'b' + 'c' + '\0'
字符串末尾一定存在一个用来标识字符串结尾的\0字符
注意:
'a'和"a"区别:
'a':字符常量,由'a'构成
"a":字符串类型,由'a'和'\0'构成
"ab\0":'a''b''\0''\0'
"ab123":'a''b''1''2''3''\0'
"ab\123":'a''b''\123''\0'
"zhangsan say:\"hello world\"\n"5.标识常量
, 用一个标识符来表示一个常量,称之为符号常量。符号常量在使用之前必须先定义,其 一般形式为:
#define 标识符 常量值(宏定义);
#include
#define PI 3.1415//宏定义常量3.1415被PI代替
int main(void)
{
int r=3;
float sum=0;
sum =1.0*PI*r*r;
printf("半径为3的圆面积为%lf\n",sum);
return 0;
}
//半径为3的圆面积为28.273500
名称 | 运算符号 | 例子 |
加法 | + | 1+2=3 |
减法 | - | 6-3=3 |
乘法 | * | 3*9=27 |
除法 | / | 18/2=9 |
取余 | % | 8%2=0 |
自增 | ++ | int a =1; a++ |
自减 | -- | int b =9; b--; |
int main(void)
{
int a=6,b=2;
printf("%d\n",a+b);//加法 8
printf("%d\n",a-b);//减法 4
printf("%d\n",a*b);//乘法 12
printf("%d\n",a/b);//除法 3
printf("%d\n",a%b);//取余 0
printf("%d\n",++a);//自增 7
printf("%d\n",--b);//自减 1
return 0;
}
运算符 | 功能 | 例子 |
= | 赋值功能,将=右边的操作数赋值给左边操作数 | a=3 |
+= | 将左操作数加上右操作再赋值给左操作数 | b += 6; b=b+6; |
-= | 将左操作数减去右操作再赋值给左操作数 | c -=5; c=c-5; |
*= | 将左操作数乘上右操作再赋值给左操作数 | d *=3; d=d*3; |
/= | 将左操作数除去右操作再赋值给左操作数 | e /=2; e= e/2; |
%= | 将左操作数取余右操作再赋值给左操作数 | f %=4; f=f%4; |
&= | 将左操作数与上右操作再赋值给左操作数 | g &= 2; g= g&2; |
|= | 将左操作数或上右操作再赋值给左操作数 | h |= 1; h = h|1; |
注意:
1.大数据放入小空间,直接截取数据低位
2.小数据放入大空间,有符号数补符号位,无符号数补0
3.如果赋值运算符左右两边空间一致,直接拷贝
#include
int main(void)
{
int a=3,b=2,c=10,d=6,e=8,f=9,g=3,h=6;
printf("a=%d\n",a);
printf("b=%d\n",b +=6);
printf("c=%d\n",c -=5);
printf("d=%d\n",d *=3);
printf("e=%d\n",e /=2);
printf("f=%d\n",f %=4);
printf("g=%d\n",g &=2);
printf("h=%d\n",h |=1);
return 0;
}
a=3
b=8
c=5
d=18
e=4
f=1
g=2
h=7
运算符 | 功能 | 例子 |
== | 相等 | 1==2; false 0 |
!= | 不相等 | 1 != 2; true 1 |
> | 大于 | 4 > 5; false 0 |
< | 小于 | 3 < 6; true 1 |
>= | 大于等于 | 4 >= 3; true 1 |
<= | 小于等于 | 8 <= 5; false 0 |
#include
int main(void)
{
int num1=5,num2=9;
int result=0;
result = num1 == num2;
printf("result == %d\n",result);
result = num1 != num2;
printf("result != %d\n",result);
result = num1 > num2;
printf("result > %d\n" ,result);
result = num1 < num2;
printf("result < %d\n" ,result);
result = num1 >= num2;
printf("result >= %d\n" ,result);
result = num1 <= num2;
printf("result <= %d\n" ,result);
return 0;
}
result == 0
result != 1
result > 0
result < 1
result >= 0
result <= 1
运算符 | 功能 | 例子 |
&& | 逻辑与,同真为真 | 1 && 1,真 |
|| | 逻辑或,有真为真 | 0 || 1, 真 |
! | 逻辑非,否定 | !真, 假 |
#include
int main(void)
{
int x=1,y=1,z=0;
int result=0;
result = x&&y;
printf("&& %d\n",result);
result = x||z;
printf("|| %d\n",result);
result = !x;
printf("! %d",result);
return 0;
}
&& 1
|| 1
! 0
语法:
表达式1 ?表达式2 : 表达式3
语义:
先执行表达式1,如果表达式1结果为真,那么执行表达式2,如果表达式1结果为假,那么执行表达式3.
#include
int main(void)
{
int a=2,b=6,c=0;
c=(a>b)?a:b;
printf("c %d\n",c);
c=(a
c 6
c 2
逗号运算符(分隔符) 表达式取最后一个值返回。
特点:优先级最低;自左往右执行表达式;返回值为表达式最后一个;
#include
int main(void)
{
int a=(1,2,3);
printf("a=%d",a);
return 0;
}
//a=3
sizeof是c中的关键字,它用来计算变量(或数据类型) 获得数据类型/变量在内存中所占的字节数。
ex: sizeof (数据类型/变量名)
#include
int main(void)
{
printf("sizeof char is %d\n", sizeof(char));
printf("sizeof int is %d\n", sizeof(int));
printf("sizeof float is %d\n", sizeof(float));
return 0;
}
1.单目运算符、双目运算符、三目运算符
单目运算符 > 双目运算符 > 三目运算符 > 赋值运算符 > 逗号运算符简单记忆:!> 算术运算符 > 关系运算符 > && >> || > 逻辑运算符 > 逗号运算符
双目运算符:
1.算数运算符
2.移位运算符
3.关系运算符
4.位运算符
5.逻辑运算符
C语言中优先级口诀:单算移关与,异或逻条赋
■“单”表示单目运算符:逻辑非(!),按位取反(~),自增(++),自减(--),取地址(&),取值(*);
■“算”表示算术运算符:乘、除和求余(*,/,%)级别高于加减(+,-);
■“移”表示按位左移(<<)和位右移(>>);
■“关”表示关系运算符:大小关系(>,>=,<,<=)级别高于相等不相等关系(==,!=);
■“与”表示按位与(&);
■“异”表示按位异或(^);
■“或”表示按位或(|);
■“逻”表示逻辑运算符:逻辑与(&&)级别高于逻辑或(||);
■“条”表示条件运算符(? :);
■“赋”表示赋值运算符(=,+=,-=,*=,/=,%=,>>=,<<=,&=,^=, |=,!=);
◆另,逗号运算符(,) 级别最低,口诀中没有表述,需另加记忆..
#include
int main(void)
{
int a=10,b=20,c=0;
c= a + a*b;
printf("c=%d\n",c);
c= ++a*2 + b*a;
printf("c=%d\n",c);
return 0;
}
c=210
c=242
算术运算符中乘法优先级大于加法优先级;++运算符优先级大于算术运算符优先级
#include
int main(void)
{
int a=1,b=2,c=3;
printf("%d\n",a < b ? b > c ? 9: 7 :a-b);
return 0;
}
//条件运算符嵌套使用
7
等价于ac?9:7):a-b。
#include
int main(void)
{
int a=30,b=90;
int res=0;
res=a > b ? a++ : b--;
printf("a=%d b=%d res=%d",a,b,res);
return 0;
}
a=30 b=89 res=90
参考文章:
(154条消息) C语言中的运算符大全(内附优先级表)_「已注销」的博客-CSDN博客_c语言运算符优先级表
(154条消息) c语言入门这一篇就够了-学习笔记(一万字)_天涯明月笙的博客-CSDN博客_c语言