数据类型和运算符、表达式

1、什么是变量?

其值在其作用域内可以改变的量称为变量。一个变量应该有一个名字,在内存中占据一定的存储空间。变量在使用前必学要定义,每个变量都有自己的地址。变量依据其定义的类型,分为不同类型,如整形变量、字符型变量、浮点型变量、指针型变量等。

2、局部变量和全局变量

局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于函数内, 离开该函数后再使用这种变量是非法的。
全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。 但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。

3、基本内置类型

1)整形

2)实形

3)构造类型

4)指针类型

5)枚举类型

6)void 类型

4、声明与定义

举一个例子:

A),int a;B),extern int a;

那个是定义,那个是声明呢?或者都是定义,又或者都是声明。

这个问题,在我工作中和学习中,从来没有被教过和问过。

在计算机中,到底什么是定义,什么是声明,定义和声明的区别归根到底在哪?


先来说一下什么是定义:

所谓定义就是创建一个对象,为这个对象分配一块内存,同时给这块内存取一个名字,这个名字就是我们常说的对象名或变量名。但是注意,这个名字一旦和这块内存关联起来,他们就是一个整体,生死相依,不离不弃。并且这块内存的位置也不能被改变。一个对象或者变量,在一个区域内(全局,文件,函数,循环等)只能被定义一次,如果定义多次,编译器会提示你重复定义同一个变量或对象。

再来说一下声明:

第一层含义:告诉这个编译器,这个名字已经匹配到一块内存上路了,后面的代码用变量火女对象实在别的地方定义的。定义是原件,原件唯一有效,那么声明就像复印件,可以重复打印,可以多次声明。

第二层含义:告诉编译器,这个变量或者对象的名字已经被占用了,别的地方,不能在使用这个名字作为其他的变量或者对象名;比如在电影票,你买了一张票后提示他人该位置已经被其他上占用了。

这种声明最典型的例子就是函数参数的声明,例如:

int func(int a, char b);

这一样一疏理后,应该能够区分出:A是定义,B是声明。

那么到底什么是定义和声明的根本区别:是内存。

定义创建对象,并为这个对象分配了内存;而声明只是将与内存关联的对象名进行外域可见性的扩充,看不到,可以继续声明。


5、typedef与define

typedef

    一,定义

           typedef:声明自定义数据类型,配合各种原有数据类型,用来简化编程。

    二,用途

            1,便于移植

                  typedef  int  INT32;

                  INT32     a;//定义整型变量

                  (INT32)   a;//强制转换类型

 

                  为什么有int 还要取同名 INT32 ?

                  答:A微处理器 int 16位,long  32位

                          B微处理器 short 16位,int 32位,long  64位

                         原本A处理器下程序:

                                     typedef  int      INT16;

                                     typedef  long   INT32;

                          要移植到B处理器下,则仅仅需要更改这些新名称就行,而不用更改整个程序。

                                     typedef  short       INT16;

                                     typedef  int            INT32;

             2,在旧的C代码中,帮助struct。

                    由于在旧的C代码中,声明struct对象时,必须带上struct 。

                    如:struct  node

                           {

                                int  data;

                                struct  node  next;  //C语言中必须带上 struct ;而在C++中则可以省略struct

                           } ;

                    而写成

                            typedef   struct  node

                          {

                                 int   data; 

                           }node_re;

                           node_re     root;

            3,定义已有类型的一种别名

                      typedef      char     *pchar;

                      pchar   pa,pb;

                      为指针声明typedef 时,容易出现问题。所以建议:只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身所指对象不会通过指针被修改。

                       typedef   const  char   *pchar;

          

define

    一,定义:定义宏,即允许用一个标示符来表示一个字串。

    二,用处:

                   1,方便程序修改

                         定义程序中经常使用的常量,这样在常量改变时,不用对整个程序进行修改。

                         例如:#define  pi   3.141592653  //不用每次都输入3.141592653 直接输入 pi

 

                   2,提高程序运行效率

                          C语言中,函数的使用可以使程序更加模块化,便于组织,而且可以重复利用。

                          但是,函数调用时,需要保留调用函数的现场,便于子函数执行结束后能返回继续执行。在子函数执行完后要恢复调用函数的现场,这需要一定时间。

                          如果子函数执行操作较多,这种转换时间可以忽略。但是如果执行功能较少,则开销相对较大。

                          例如:#define S(a,b)   a*b   //仅仅是一条乘法 操作

define与typedef的区别

        typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量,到了C++,const、enum、inline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好,如#define INT int这样的语句,用typedef一样可以完成,用哪个好呢?我主张用typedef,因为在早期的许多C编译器中这条语句是非法的,只是现今的编译器又做了扩充。为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

       宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行:

    typedef   (int*)    pINT;
    

    #define    pINT2   int*

效果相同?实则不同!实践中见差别:

            pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。

            而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针,一个整型变量


6、static

1在函数体内,静态变量具有"记忆"功能。即在函数被调用过程中,一个被声明为静态变量的值维持不变。

  static局部变量和普通局部变量的区别:static局部变量只被初始化一次,下一次的运算依据上一次的结果值。

2在模块内,但在函数体外,它的作用域范围是有限制的static类型的变量,是本地的全局变量。所以,可以被模块内的所有函数访问,不可以被模块外的函数访问。

3static类型的函数,与普通类型函数的作用域不一样。静态函数的作用域仅在本文件中,只可被模块内的其它函数调用,不能被模块外的其它函数调用。


7、什么是原码?什么是补码?什么是反码?正数的原码补码反码怎么表示,负数的原码补码反码怎么表示?

计算机中的存储系统都是用2进制储存的,对我们输入的每一个信息它都会自动转变成二进制的形式,而二进制在存储的时候就会用到原码,反码和补码
例如:十进制 -10
原码就是:10001010
反码: 11110101
补码: 11110110
原码是信息的二进制表示
反码就是把它的原码除符号位都取反(0变1,1变0)
补码是在反码的末位上加1
不过正数的原反补码是相同的


8.运算符分类

9、运算符的优先级


10、位运算
位运算(包括与,或,取反,异或,左移,右移等)是程序设计中的一个重要的领域。尤其是安全和底层开发中,除了指针的频繁使用之外,位运算是另一个非常频繁使用的领域。 因此,在求职面试中,位运算也是每年重点考查的知识点。首先,我们有必要复习一下C语言中位运算的一些基础计算方法。
 
1,与运算:&

与运算的操作符为&。2个数进行与运算时,就是将这2个数的二进制进行与操作, 只有当2个数对应的位都为1,该位运算结果为1,否则运算结果为0。即:1&1=1;1&0=0;0&0=0.
比如计算15&10,首先15的二进制为:1111,10的二进制为1010(二进制,十进制和十六进制转化方法: 点击这里 ),所以15&10为:
所以15&10=10。 

2,或运算:|


或运算的操作符为|。2个数进行或运算时,就是将这2个数的二进制进行或操作, 只要2个数对应的位有一个为1,该位运算结果为1,否则运算结果为0。即:1|1=1;1|0=1;0|0=0.
比如计算15&10,首先15的二进制为:1111,10的二进制为1010,所以15|10为:
所以15|10=15。 

3,取反运算:~


取反运算的操作符为~,为单目运算符。取反运算符顾名思义,就是将一个整数中位为1的变成0,位为0的变成1。即:~1=0;~0=1.
比如计算~10,首先10的二进制为:1010,~10为:
~10=5。

 
4,异或运算:^

异或运算的操作符为^。2个数进行异或运算时,就是将这2个数的二进制进行异或操作, 只要2个数对应的位相同,该位运算结果为0,否则运算结果为1。即:1^1=0;1^0=1;0^0=0.
比如计算15^10,首先15的二进制为:1111,10的二进制为1010,所以15^10为:
所以15^10=5。

5,右移运算符:>>

右移运算符为>>。将一个数a向右移动n位记为:a>>n。比如将12向右移动2位如何计算呢?12的二进制为00001100,那么右移动2位为:00000011,即3。 即12>>2为3。 

右移动运算分为两种右移,一种为逻辑右移,在移动过程中,左边位用0填充。一种为算术右移,在移动过程中,左边用符号位来填充。 比如对于有符号数:10000011,对于逻辑右移,向右移动3位,那么左边用0填充,变成了:00010000。而对于算术右移,向右移动3位,那么左边用1(1为符号位)填充,变成了11110000。而对于01000011,算术右移3位,那么左边用0(0为符号位)填充,变成了00001000。 在C语言中,右移运算符为算术右移运算符,即左边用符号位来填充。

6,左移运算符:《

左移运算符为《。将一个数a向左移动n位记为:a《n。 比如将12向左移动2位如何计算呢?12的二进制为00001100,那么左移动2位为:00110000。 无论左移还是右移,都需要用0或者1去填充移动之后空位。在左移的过程中,右边一律用0去填充。左移就没有右移那样分为逻辑右移和算术右移。 比如,将10左移2位,由于10的二进制为:00001010,那么左移2位,右边用零填充的结果为:00101000。 将一个数左移N位相当于将一个数乘以2^N,而将一个数右移N位相当于将这个数除以2^N。 

位运算运算符的优先级如下:(优先级由高到低排列)
而所有的C运算符的优先级与结合律如下图:(从图中可以看出,算术运算符的优先级高于《和》运算符)
一些常见的二进制位的变换操作如下图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值