原创 C语法精讲1

2014-8-9 17:33 634 6 6 分类: MCU/ 嵌入式

·一般的程序如下:

程序  =  数据结构  + 算法

     数据结构含有基本数据和复杂数据,即我们将要交给计算机运算的量


因为数据量 ----> 大小 ----> 存储空间

所以在高级语言中要合理规划存储空间,变量(容器)大小,也就是要合理选择变量类型。

 

  8bit      16bit     32bit    32bit   64bit      96bit/128bit(大小取决与系统)

  char    short int    int     float   double      long double

 1字节     2字节      4字节    4字节   8字节      12字节/16字节

 

有符号:    char A;                 -----> 最高位为符号位,精度减半

无符号:    unsigned char A;        -----> 没有符号位,精度完整

 

 //定义一个char型变量A

  char A;

 //第一给A赋值,初始化

  A = 49;

  A = '1';   --->  ASCII   1 ------>   man ascii ---->  每个ascii 字母对应这一个整型量

A = 49;等价与A = '1';

 有符号 :   1 ---> 0000 0001 -----> 最高位为符号位 : 0  --> 正数  1 ----> 负数

            -1 ---> 1000 0001 -----> 最高位为符号位 : 0  --> 正数  1 ----> 负数 

·故有符号char数值范围:-128 ~ 127

------------------------------------------程序的空间使用---------------------------------------------

#include

char A;

short int B;

int C;

float D;

double E;

long double F;


int main()

{

       return 0;

}

分析:

1)在程序中定义了全局变量(在文件中,函数体外定义的变量,作用范围为整个文件),是静态变量 

★已初始化变量占用文件的存储空间(影响文件的大小)

★未初始化变量不占用文件的存储空间(不影响文件的大小)但是占用符号

 

2)在函数中定义了局部变量(作用范围为该函数,随着函数的运行而开辟空间,随着函数的退出而回收空间),是动态变量

★变量不占用文件的存储空间(不影响文件的大小)

 

nm 结果:  ------> 当前程序中,变量的存储地址

0804a05c B A

0804a034 B B

0804a058 B C

0804a030 B D

0804a050 B E

0804a040 B F

 

地址: 0804a040

B   BSS 未初始化的数据

A-F :  变量名

 

readelf filename –a读取elf可执行文件的内容信息

 

readelf重要字段介绍

1) 文件头(ELF Header)  ---->  每种类型的文件都有头信息。

2) 段信息(Section Headers)  ---->  当前程序的数据与代码的分类存储区域

                .text   --->程序的代码位置

                .rodata --->只读数据段,为常量

                .data   --->已初始化可读可写的数据

                .bss    --->未初始化的数据

 3)符号表(Symbol table) ----->   变量名,函数名 都属于一种符号。

E.g:

              Value    Size   Type     Bind    Vis         Ndx  Name

            0804a050     8   OBJECT  GLOBAL DEFAULT    25   E

  

Value  : 地址值

size   :  占用的存储空间

Name   : 符号名

 ------------------------------------------运算符-----------------------------------------------------

<1>赋值运算     =   ------->  右值必须与左值类型相等,同时左值不能为常量

 

   A  =  1;      ----> 赋值表达式

   A  =  add();   ---->add()返回的值赋给变量A

赋值形式(1

   int x;

   x=1;

赋值形式(2

   int x=1;

   int y=2;

赋值形式(3

   int x=1,y=2,z;


<2>逗号表达式:  A  =  (z=x+y,y=5,y+3);   --->  结果等于最后一个表达式的值

   5 = A; 错误

   A = 5

<3>常变量    ---->  该变量装载的数值是不可以修改,只能在定义时初始化。

   const int A = 10;    ---> 变量A 用于等于10 (常量)

   A = 5  错误

       编译警告: error: assignment of read-only variable A

   ------------------------------------------------算数运算符---------------------------------------------------

   <1>算数运算:  +  -  *  /  %     

需要特别强调:精度与数据类型

   int  B  =  3/2;    ====>  1.5   ----> int  ----> 取整型部分 ---> 1

解决方案:

   float  B  = (float)3/2;     ----->  类型强制转换   ---->   3 使用浮点类型进行运算  --->右值为1.500000

   float  B  = (float)(3/2);   ----->  (3/2) 的结果(整型结果为1)使用浮点类型进行运算  --->右值为1.000000

 

 <2> 强制类型转换: 当默认的初始类型不能满足数据的装载需求时,进行强制变更(更变装载空间)

格式: 在原始数据前,使用()运算符进行类型强制声明。E.g  int a=2,b=3; float  B  = (float)b/a;   ------> 作用范围为临时转换

  

 <3>  取模运算(取余)   ----> %两边需为整型数

      int A  = 3%2;   ---->  余数1   ----> A = 1;

%举例应用: 

   123  取个位数:

 

   int A =  123%10

   123  取十位数:


   int A = (123%100)/10

 <4>  自增自减:

   A++  A--     //后操作   ---->  先将A的值参与运算,后加减

   ++A  --A     //前操作   ---->  先加减再运算  

  ----------------------------------------------关系运算符-----------------------------------------------

  △对量进行判断

       关系运算符有:

                            >    >=   <    <=   !=   ==

·结合判断表达式:

  ifa > B

  ifa != B  ---> a 不等于 B

  ifa == B   ----> 判断aB的值是否相同  ----> 只针对整型量  ----> 结果是布尔值 ---> 真或者假

  ifa = B    ----> 赋值语句  ---> 一般为真(遵循赋值的格式前提下,左值与右值等价)

  ------------------------------------------------逻辑运算符--------------------------------------------------

   △对条件进行判断

逻辑运算符有:

                        &&     ||

·结合判断表达式:

   if  !条件    -----> 当条件1为假时,  “ !条件1  ----> 为真

        一般用于判断某个结果是否为空  --->  空值对应 0  ---> 为假

   if  条件1  &&  条件2      -----> 当条件1为真时, 同时条件2也为真  ----> 整个表达式为真,否则为假

         一般用于必须条件1 跟条件2 都同时成立时

   if  条件1  ||  条件2      -----> 当条件1为假时, 条件2为真即可  ---->  一个表达式为真整个表达式为真;两个条件都不成立时为假

         一般用于只要条件1或条件2 有一个成立时

 

  ---------------------------------------位运算符----------------------------------------------------------

位运算符有:

  &   |   ~  ^  <<  >>

  1& 操作:

  0 & 3  ----> 0

      00

*    11

      00

 2 | 操作:

  0 | 3  ----> 3

        00

   +    11

        11

 3 ~ 操作

  unsigned char A = 1   ----> 000000001   ---->   ~A  ---->  11111110

 4 ^ 操作  ---->  对应位相同为0,不同为1

  0 ^ 3  ----> 3

       00

     11  

      11

 5 <<  >> 操作

 获取二进制A的第四位:

  A =  1001 0100    

  char B =   (A >> 0x04)   & 0x01; 

分解:

  (A >> 0x04)   ----->  0000 1001

 

  & 0x01        ----->  0000 1001 & 0000 0001   -----> 1

 

★常用于将字符型组合成整型:

E.g:

 char A,B,C,D;

 int  E

 E =  A << 24 | B << 16 | C << 8 | D;

 ----------------------------------------条件运算符----------------------------------------------

  A ?  B  : C;

  A成立 ,则执行B ,否则执行C

 ------------------------------------------sizeof-----------------------------------------------

  sizeof( A )    ---->   A 可以为变量名  或者 类型名

  返回当前A占用的空间的大小 n 字节

-------------------------------------------复合运算符----------------------------------------------------

位运算符有: -=   +=  *=  /=  %= 

                    <<=  >>=  |=  &=  ^=

  将赋值运算符结合算数运算符或者位运算符

E.g:

             A = A - 1  ---->  A -= 1;

---------------------------------------------格式化IO-------------------------------------------------------

  1printf家族:

 printf(" ...%d..%c.. ",x,y);     ----> 往标准输出中输出指定内容,配合相应的格式化输出的标识符★需要注意输出的精度(精度截取)

   int printf(const char *format, ...);

   int sprintf(char *str, const char *format, ...);

   int sprintf(char *str, const char *format, ...);   ----> 往指定str字符串空间中输出指定内容,配合相应的格式化输出的标识符

  

   <1.1>char buf[10];

   char a=5;

   sprintf(buf, "hello %d",a);

 ----->  "hello 5"


<1.2>int snprintf(char *str, size_t size, const char *format, ...);

   char buf[10];

   char a=5;

   snprintf(buf, 10 ,"hello %d 123456789",a); ----->  "hello 5"


  (2)scanf家族:

scanf("%d",&a);

int fscanf(FILE *stream, const char *format, ...);

    int sscanf(const char *str, const char *format, ...); 

 

★注意: 输入缓冲

  这里要说明scanf是有返回值的,其返回值即为scanf正确读取的变量的个数。

  int a,b,c

  scanf("%d",&a);   ---->  输入1个整数   ----> scanf读取成功,返回值:1

  scanf("%d  %d  %d ",&a,&b,&c);   ---->  3个整数 :  15 16 17 ----> scanf读取成功,返回值:3

  scanf("%d%d%d ",&a,&b,&c);   ---->  3个整数 :15,16,u ----> scanf读取成功,返回值:2  ----> 缓冲中残留u

 

★清除缓冲区的方法:

  while( getchar() != '\n' );   ---> 一直获取输入缓冲中的字符,直到换行符为止。

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
6
关闭 站长推荐上一条 /3 下一条