zoukankan      html  css  js  c++  java
  • AaronYang风格 C语言挑讲[二][基本类型、运算符和表达式]

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

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

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

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

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

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

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

    要避免不必要的类型转换

    精彩预览:


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

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

     

    数据类型基本一览

    image

    我学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’在内存中的字节中存放的分别是十进制整数 97     65    49    37    13   61

    总结:由于整型常量在内存中存放的是整数值,如果其值在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编译程序将在程序编译前将所有的符号常量自动替换成对应的常量

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

    例如  #define PI 3.1415926 效果同于C#的      const double PI=3.1415926

            #define A ‘A’      效果等同于C#的      const char A=‘A’

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

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

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

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

    #define PI 3.14159

    #define R 10

    #define D (R+R)

    #define L PI*D

    若程序中用到了L

    ①先替换成 PI*D

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

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

    下面是1个特殊的例子:

    例子:      #define PI 3.14159

                    #define R1 2+3

                    #define R2 (2+3)

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

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

     

    变量

    定义模式跟C#基本一样

    类型 变量名=值

    类型 变量名

    算了,直接举例子

    int i;

    float i,j;

    unsigned short me;

    long a1=11L;

    unsigned short a1=0111,a2=0x11;

    int i=1,j=2,k;

    int i,j,k=10;

    char c1=‘A’,c2,c3=‘a’;

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

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

    C中如下:

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

    跟C# const一样

    例如 const char FALE='男',FEMALE='女';

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

     

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

    运算符感觉最基本的

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

    正负号 + -

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

    还有 就是      !       &&    ||

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

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

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

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

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

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

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

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

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

    一、基本常见的跳过了

    二、长度运算符(sizeof)

    打开C-Free5

    image

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

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

    image

    重点讲解一下 位运算符

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

    一、位逻辑运算符

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

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

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

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

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

    image

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

    image

    【例一】

    设变量定义如下: unsigned short a=0111,b=0x53

    先把  a 无符号八进制转换成二进制:     0000 0000 0100  1001

             b 无符号十六进制转换成二进制:  0000 0000 0101 0011

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

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

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

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




    二、位移位运算符

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

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

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

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

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

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

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

    无符号右移

    位移符号演示右移无符号

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

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




    三、位自反赋值运算符

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

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

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

     

     

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

    1. 算数表达式
    2. 关系表达式
    3. 逻辑表达式
    4. 赋值表达式
    5. 逗号表达式
    6. 条件表达式

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

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

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

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

    3+5,6+8

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

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

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

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

    例一

    image

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

    例二

    image

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

     

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

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

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

      例如:image

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

      例如:image

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

      例如:image

    4. 避免转换的小例子

      例如:image

     

    课外知识

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

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

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

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

    下面讲一个小题目了

    image

    回忆本篇第一部分

    image

    short类型的字节长度2

    long类型长度是4

    下面用图片解释一下

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

    image

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

     
     
     

    学习总结

    1. 对常量,宏替换,变量 原理性的理解和使用
    2. 数据长度,进制转换的理解
    3. 位运算符的理解和使用
    4. 逗号运算符的使用
    5. 占用字节数的理解和实践
  • 相关阅读:
    网络端口
    Jmeter安装
    【紫光同创国产FPGA教程】【第一章】Pango Design Suite 2020.3安装 ALINX
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第三十章 自定义IP实验
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十九章PL端AXI GPIO的使用
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十八章 PS端EMIO的使用
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十七章System Monitor
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十六章 PS端网络远程更新QSPI
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十五章 PS端以太网使用之lwip
    【ZYNQ Ultrascale+ MPSOC FPGA教程】第二十四章 PS端SD卡读写
  • 原文地址:https://www.cnblogs.com/AaronYang/p/3137728.html
Copyright © 2011-2022 走看看