您的位置:首页 > 编程语言 > C语言/C++

AaronYang风格 C语言挑讲[二][基本类型、运算符和表达式]

2013-06-16 01:31 218 查看

AaronYang风格就是:不讲老生长谈的东西,挑主题内难懂的地方细讲,其他总结一笔带过,有口诀教口诀,示例实践出来,文章内容充实。

本文原理理解性方面的较多,但是都被我用gif图片(自己photoshop做的)讲解

更底层的东西,我自己都不懂的,不可能拿出来讲的

本文是针对有学过其他编程语言的来学的,有很多地方我跳过略讲,所以这不是一篇入门的文章

我在看C的时候,其实发现了一些挺好玩的东西,比如宏替换,带符号,不带符号的类型。C的常量定义也不一样。

重点讲位运算符的运算,还有逗号运算符

最主要是每个类型占了多少个字节的理解,以后优化程序可以用到。

要避免不必要的类型转换




精彩预览:



比如课外知识,很多人知道怎么去写编程,但原理知道的很少,知道怎么用,比如操作系统32位和64位的关于编程方面的区别

这里讲的很容易理解,自己做了些图片方便理解,如果想直接看,就在本文末最后一节,呵呵



数据类型基本一览




我学C#的,无符号类型和指针没怎么接触过

其他概念:

打开程序时候,数据会存在内存中(个别可能在寄存器中),我们要对每个数据在内存中分配若干个字节,用于存放数据。数据所占用的内存字节数称为该数据的“数据长度”。所以我们要定义不同的数据类型,来安排合适的长度去分配数据存放。于是我们需要数据类型这个概念,不知道有没有听懂了



常量


(一)整型常量

十进制:平常的数字写法,0,22,+11,-3

八进制:0开头的书写形式,例如00,+08,-033,021

十六进制:0x开头的书写形式,例如0x1,-0x121,+0x12,0x21

占用字节:一般微型机中占用2个字节,不分进制,他们的数值范围都是十进制的-32768~+32767

长整型常量:范围-2147483648~+2147483647,占用4个字节。

书写形式:在整数的末尾加上l或者L例如:10L-011L+0x15L

那么其他的都是短整型常量了。如果整型常量后面没有字母“L”或“l”,而且超过了短整型常量能够表示的数值范围,则自动认为该常量是长整型常量了,例如-32769、32768、40000都是长整型常量了

总结:整型常量分短整型和长整型两种,又分十进制,八进制,十六进制三种书写形式,使用时,要注意区分。例如,88和88L,数值一样,但是它们在内存中占用不同数量的字节;比如10,010L,0x10虽然是短整型常量,但是表示的整数值不一样。




(二)实型常量

一般形式
[+或者–]整数部分小数点小数部分

指数形式
[+或者–]整数部分小数点小数部分e或者E[+或者–]指数(就是普通的整数)

例如12.345e3就等于12.345乘以10的3次方就是12345

12345E-3就等于12345乘以10的-3次方就是12.345

总结:实型常量在一般的微机中占用4个字节,数值范围都是-10的38次方到10的38次方,有效数字是7位

例如:1.23456789和1.234567是相同的,因为有效数字是7位,所以后两位是无效的




(三)字符常量

就是char类型了,C语言中,字母区分大小写的,‘a’和‘A’是不一样的

在内存中,每个字符常量都占用一个字节,具体存放的是该字符对应的ASCII代码值。例如‘a’‘A’‘1'‘%’‘\r’‘\x3d’在内存中的字节中存放的分别是十进制整数976549371361

总结:由于整型常量在内存中存放的是整数值,如果其值在0~127之间,C语言规定也可以将其看成一个字符型常量,就是数字当符号使用。例如:整型常量111、70、40可以当做字符常量‘o’‘F’‘(’来使用

有个好玩的例子:‘a’+5这里a就会被当做97使用,所以等于结果值102,在C#中我也试过了,也是如此




(四)字符串常量

就是字符串,在C#中是string定义的

但是C中定义字符串不是用string的,以后说吧.

例如“aAbBcCdD”转义字符\

字符串长度

普通的不说了,说点特殊的,例如“”是0,“\\ABCD\\”是6,“\101\102\x43\x44”是4

虽然每个字符在内存中只占用1个字节,但C语言规定,每个字符串在内存中占用的字节数等于字符串的长度+1,其中最后一个字节存放的字符为“空字符串”,其值为0,书写的时常用转义字符“\0”来表示,在C语言中称为字符串结束标记。例如:字符串“AB”和“A”的长度分别是2和1,但他们在内存中分别占用3和2个字节,所以“A”和‘A’是不同的,一个占用2个字节,一个占用1个字节

关于这个在C#是否是这样的,我不清楚…




(五)符号常量#define符号常量常量

C编译程序将在程序编译前将所有的符号常量自动替换成对应的常量

变量规范名字全部用大写字母

例如#definePI3.1415926效果同于C#的constdoublePI=3.1415926

#defineA‘A’效果等同于C#的constcharA=‘A’

宏定义命令的一般格式如下:#define宏名一串符号

宏名就等同于变量名,那个一串符号,你可以理解为对应的值

宏替换就是把名字替换值,然后进行处理。由于宏替换是在编译前进行的,所以宏定义命令属于C语言的”预编译命令”

基本例子,理解替换的过程

#definePI3.14159

#defineR10

#defineD(R+R)

#defineLPI*D

若程序中用到了L

①先替换成PI*D

②再将PI替换成3.14156、D替换成(R+R),结果就是3.14159*(R+R)

③这里面还有宏名,再替换R,最后结果就是3.14159*(10+10)

下面是1个特殊的例子:

例子:#definePI3.14159

#defineR12+3

#defineR2(2+3)

若求2*PI*R1的值宏替换结果是”2*3.14159*2+3”

若求2*PI*R2的值宏替换结果是”2*3.14159*(2+3)”



变量


定义模式跟C#基本一样

类型变量名=值

类型变量名

算了,直接举例子

inti;

floati,j;

unsignedshortme;

longa1=11L;

unsignedshorta1=0111,a2=0x11;

inti=1,j=2,k;

inti,j,k=10;

charc1=‘A’,c2,c3=‘a’;




有名常量的定义(就是C#中的const)

在C#中用const类型名称定义的,变量规范都是一样的,名字用全部的大写字母

C中如下:

const数据类型符变量名1=初值,变量名2=初值2等;

跟C#const一样

例如constcharFALE='男',FEMALE='女';

一旦定义,程序运行的时候就不许修改了,否则报错



运算符(跟C#基本一样,多了几个,这里假设你已经学了其他编程语言)


运算符感觉最基本的

加减乘除求余数+–*/%

正负号+-

关系运算符<><=>===!=

还有就是!&&||

三元运算符(书中写的三元,二元都是三目,二目,我不太习惯)?:

其他符号像赋值=逗号,数组中的[]其他基本的括号()递增的++--

运算完赋值相关的+=-=*=/=%=

数据长度运算符(sizeof),这个C#中没有

关于成员运算符,我们在C#中,都是对象点(.)出来对象中的属性或者方法的,C中用->和.关于->在PHP中也是用这个的

指针运算符,C#中应该没有吧(&*+–)

比较难理解的有位运算符(例如<<>>^~&|&=等),其实C#中也有,我们很少用,过一会讲解一下这个

运算相关的还有就是结合性,运算的优先级这个概念

我以前在Javascript讲过,语言逻辑都是通用的,那里讲的比较详细点击查看




一、基本常见的跳过了



二、长度运算符(sizeof)

打开C-Free5





sizeof是C里面的关键字并非函数,意思是c所占的内存多少单位是字节
getch();用此命令可以在运行的的时候,按任意键退出,如果没有此命令,屏幕闪一下就没了(程序结束就退出)所以看不见结果

等同于C#中的Console.ReadLine();








重点讲解一下位运算符



编程中:0代表false,假,1代表true,真,有句口诀,非0即真

一、位逻辑运算符

使用数目和位置对象类型结果类型结合性

位非~单目前缀整型整型自右向左

位与&双目中缀整型整型自左向右

位或|双目中缀整型整型自左向右

按位加^双目中缀整型整型自左向右





关于16进制转2进制的对照表格





【例一】

设变量定义如下:unsignedshorta=0111,b=0x53

先把a无符号八进制转换成二进制:0000000001001001

b无符号十六进制转换成二进制:0000000001010011

①~a把二进制是0的位置变成1,是1的变成0(对应的二进制就是1111111110110110),然后转换成八进制为0177666,运算后a不变

②a&b,两两位对应,有0则0,对应的二进制是(0000000001000001),然后转换成八进制为0101,运算后a不变

③a|b,两两位对应,有1则1,对应的二进制是(0000000001011011),然后转换成八进制为0133,运算后a不变

④a^b,两两位对应,相异则1,对应的二进制是(0000000000011010),然后转换成八进制为032,运算后a不变

二、位移位运算符

使用数目和位置运算规则对象类型结果类型结合性

左移<<双目中缀a<<b.a向左移b位整型整型自左向右

右移>>双目中缀a>>b.a向右移b位整型整型自左向右

移位时,移出的位数全部丢弃,移出的空位补入的数与左移还是右移有关

如果是左移,则规定补入的数全部是0,;如果是右移,如果不带符号,则补入的数全部是0;如果带符号,则补入的数全部等于原数的最左边位上的数(即原数的符号位)

下面假设a已经是转换成二进制的,原本本来a=47,现在转换成了二进制101111

无符号左移,带符号左移,他们两个一样的,我做张图片演示



无符号右移



带符号右移


带符号右移(最左边是0,就补0,最左边是1,就补1)

移动完后,在将二进制转换成十进制,这就是位移位运算符

三、位自反赋值运算符

功能类似常用的+=-=,运算完了,改变原有的值

主要是这5个:&=|=^=<<=>>=

这里不讲了,就是经过位移运算后,改变原有的值,第一部分,第二部分讲的都是运算后不改变原有的值



表达式(跟C#90%一样)


算数表达式

关系表达式

逻辑表达式

赋值表达式

逗号表达式

条件表达式

重点讲一下,C#中没有的逗号的特殊用法,可以组成逗号表达式

逗号除了声明变量时inta,b=10,还有函数参数也是用逗号来间隔的

但是那里的逗号都不是运算符,在C中,逗号可以是一种运算符。下面我们通过几个例子学习一下

逗号运算符,用它可以将两个表达式连接起来。如:

3+5,6+8

称为逗号表达式,又称为“顺序求值运算符”。逗号表达式的一般形式为

表达式1,表达式,表达式3……表达式n

最终的结果都是以最后一个表达式的值为准,也就是表达式n的值

例如上面一个逗号表达式的值就是6+8,也就是14

例一





这里先算3乘以5等于15,然后把值赋给了a,a等于15了,然后15乘以4,最终整个表达式的值就是60了

例二





C语言表达能力强,其中一个重要方面就在于它的表达式类型丰富,运算符功能强,因而c使用灵活,适应性强



类型转换的小例子,提醒优化(变量=表达式)


C#中有强制转换和隐式转换,C也有,自动转换规则和强制转换规则,99%和C#一样

表达式计算中数据类型的自动转换规则:参加运算的各个数据都转换成数据长度最长的数据类型,然后计算-----”就长不就短“。

例如:



运算结果存入变量时数据类型的自动转换规则:先将运算结果的数据类型自动转换成左边变量的数据类型,然后再赋予该变量-----”就左不就右“。

例如:



运算结果的强制性数据类型转换规则:跟C#一样,例如(int)14.5即14

例如:



避免转换的小例子

例如:





课外知识


一个字节等于8个二进制位;即1byte=8bit

计算机采用二进制的,8=2^3,通常最高位为符号位

  二进制数系统中,每个0或1就是一个位(bit),位是数据存储的最小单位。其中8bit就称为一个字节(Byte)。计算机中的CPU位数指的是CPU一次能处理的最大位数。例如32位计算机的CPU一次最多能处理32位数据。
  Bit,乃BInarydigit(二进制数)位的缩写,是数学家JohnWilderTukey提议的术语(可能是1946年提出,但有资料称1943年就提出了)。这个术语第一次被正式使用,是在香农著名的《信息论》,即《通信的数学理论》(AMathematicalTheoryofCommunication)论文之第1页中

所以说64位操作系统,每次读取的位数更多,所以处理数据更快了,但可能存在兼容性的问题

下面讲一个小题目了





回忆本篇第一部分





short类型的字节长度2

long类型长度是4

下面用图片解释一下

变量b3是4字节的,存放65536后,对应的二进制位数如下:





将b3的值赋予变量a的时候,b3的4字节中低16位数据(右边2字节)组成的新值就赋予变量a了,最后转换成十进制显示,就是0





学习总结


对常量,宏替换,变量原理性的理解和使用

数据长度,进制转换的理解

位运算符的理解和使用

逗号运算符的使用

占用字节数的理解和实践

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: