ITPub博客

首页 > 应用开发 > C/C++ > c语言深度解剖(数据类型关键字)

c语言深度解剖(数据类型关键字)

原创 C/C++ 作者:LinuxDevqqqqqq 时间:2018-11-22 16:47:53 0 删除 编辑

1.  前面说点话

上一个章节

写完后,很多看完的人都想把我按在地上摩擦,咬牙切齿不足解恨,但是也有很多人表示支持,在此,鄙人表示感谢。

这个章节说下 C 语言的关键字

我很想好好说下这个章节,主要是很多人不知道数据如何在内存里面存储的,而且什么是内存,很多初学者也不理解,内存可以理解成很多很多个格子,比如 1G 的内存,就有 1024x1024x1024 byte 个格子,每个格子里面都有 8 个小格子,而且每个格子都有自己的编号,这样想就没那么复杂了,数据类型就是把各种各样的数据保存在这些格子里面。

如何存?怎么存?就跟不同的数据类型有关系了

 

什么是关键字?

C 语言有多少个关键字?

1 、关键字要跟编译器联系起来,比如 int 关键字,我写了个 ( int i = 0;) 编译器就知道 int 这个家伙是认识的,编译器就会给 int  修饰的变量分配一个房子,比如说这个房子有四个字节。

2 C 语言有 32 个关键字

  2. C 语言的关键字(数据类型关键字)

数据类型关键字一共有 12 个,分别是下面

字符类型

(1) char  :声明字符型变量或函数

数值类型

(1) double  :声明双精度变量或函数

(2) float :声明浮点型变量或函数

(3) int 声明整型变量或函数

(4) long  :声明长整型变量或函数

(5) short  :声明短整型变量或函数

构造类型

(1) enum  :声明枚举类型

(2) struct :声明结构体变量或函数

(3) union :声明联合数据类型

有符号型和无符号型

(1) unsigned :声明无符号类型变量或函数

(2) signed :声明有符号类型变量或函数

 

什么是数据类型?

我相信很多人有疑问,或者很多人自信满满觉得自己对数据类型非常懂,在我看来就是由不同的格子组成的,最最最基本的数据类型是 char ,char 数据类型就有一个格子(一个字节),像下面这样

char 数据类型的一个格子

先说 char 数据类型

这个格子能装多少东西呢?这是我们最想知道的,编译器告诉你这个格子可以装二进制数 0B11111111, 里面有 8 个小格子,每个格子里面的东西是未知的。

<img src=" data-size="normal" data-rawwidth="84" data-rawheight="88" width="84">

一个格子里面装的东西示意图

如果里面装的是 0B11111111, 那这个格子应该是这个样子的,对应的十进制就是 255

上面说了 char, 下面说 unsigned  signed

上面说了,一个大格子里面有 8 个小格子,但是 8 个小格子是有顺序编号的,就是 0~7

 

比如一个数字 0B 11111111  ,这个我们都知道是  =256

定义

无符号数( unsigned )无符号数只能表示非负数( 及正数)。

有符号数( signed )可以表示任何类型规定范围内的数。

8 个小格子,我们需要有一个格子来告诉编译器,这个大格子装的数据是有符号型的还是无符号类型。编译器指定最高位的格子第 8 个格子表示符号位

所以

unsigned char i;

表示的大小是 0~255 ,一共 256 个数字

signed char i;

表示的大小是 -   2^{7}  ~ 2^{7}    =-128~127 ,其中包括 ,也是 256 个数字

小例子

#include "stdafx.h"

 

int main ( int argc,  char * argv[])

{

 

      unsigned char = ;

      signed char = ;

      int = ;

      for (k = ;k < 300 ;k ++ )

     {

        i ++ ;

        j ++ ;

       printf( "%4d %4d\t" ,i,j);

     }

      return ;

}

 

从图上可以看到, j 最大值是 127 i 最小值是 i 最大值可以达到 255 j 最小值是 -128

变量在内存里怎么保存的,看看下面这个图片

我们上面把 char unsigned signed  搞定之后,我们再来看看其他的数据类型

数值类型

(1) double  :声明双精度变量或函数

(2) float :声明浮点型变量或函数

(3) int 声明整型变量或函数

(4) long  :声明长整型变量或函数

(5) short  :声明短整型变量或函数

 

既然我们知道了 char 是一个格子,那么 double float,int,long,short 是多少个格子呢?

这时候,我们就需要用到一个关键字 sezeof ,这个关键字是用来确定对象的大小的,然后我们把上面的代码改一下

#include "stdio.h"

 

 

int main ( int argc,  char * argv[])

{

     

      char x1  = ;

      int   x2  = ;

      short x3  = ;

      long x4  = ;

      double   x5  = ;

      float x6  = ;

 

     printf( "char %d int %d short %d long %d double %d float %d\n" \

         , sizeof (x1), sizeof (x2), sizeof (x3), sizeof (x4), sizeof (x5), sizeof (x6));

     

      return ;

}

输出如图

所以我们可以知道

int  类型和 long,float 类型的格子大小如下

double 类型的格子大小如下

short 类型的格子大小如下

char 类型的格子大小如下

好了,到这里了,大家想想看

char char i = 0 ;

i 占领的格子大小有多少呢?有没有这样的写法呢?

看上面的图片, char char i =0; 是编译不通过的,但是你想过 int int ,long long ,short short,long double 呢?

为什么会编译出错呢?

说太多会有别人说我装逼厉害,有一种东西叫做编译器,编译器就像我们人类的法律一样,规定什么可以做什么是违法的,人类有很多种国家的法律,有些国家的法律允许一个老公娶几个老婆,当然,编译器也有很多个,这个自行百度。

 

说完数值数据类型,下面就开始说

构造类型

(1) enum  :声明枚举类型

(2) struct :声明结构体变量或函数

(3) union :声明联合数据类型

 

先说枚举类型 enum

enum union_type_age{

     UNION_AGE_1 = 10 ,

     UNION_AGE_2,

     UNION_AGE_3

}union_var_age;

enum 是关键字, union_type_age 说明是这个整体,是这个枚举变量的类型,就像一个户口本,有一个户主的名字一样,比如小明家的爸爸叫做小宝,小宝是小明家的户主,别人会这样说,小宝家的小明,小宝家的 XX 之类的。

里面的 UNION_AGE_1=10, UNION_AGE_2, UNION_AGE_3  是这个枚举类型的数值,它们是 const 常数类型的,只能在初始化的时候取设定它的值。

union_var_age 是枚举类型的变量,它的值只能取花括号里面的数据。

 

用下面的一个小程序理解上面的内容,不理解的请留言

#include "stdio.h"

 

enum union_type_age{

     UNION_AGE_1 = 10 ,

     UNION_AGE_2,

     UNION_AGE_3

}union_var_age;

 

 

int main ( int argc,  char * argv[])

{

     

     printf( "enum %d\n" , sizeof ( enum ));

     

     union_var_age  = UNION_AGE_2;

     printf( "union_var_age %d\n" ,union_var_age);

      return ;

}

再说结构体 struct  数据类型

这个关键字的数据类型太厉害了,学过 C++ 都知道 C++ 是面向对象的语言,但是 linux 内核下面有很多通过 c 实现面向对象的,其中 struct 起到了非常重要的作用, struct 可以把很多不一样的数据类型统一成一个整体去使用。

#include "stdafx.h"

#include "stdio.h"

 

struct str_cpu{

      int age;

      char * name;

      double f;

}str_t;

 

 

int main ( int argc,  char * argv[])

{

     str_t.age  = 10 ;

     str_t.name  = "Linux" ;

     str_t.f  = 1.077 ;

 

     printf( "str_t.age %d str_t.name %s str_t.f %f\n" ,str_t.age,str_t.name,str_t.f);

      return ;

}

跟枚举一样 strcpu 这个指的是结构体花括号里面的所有东西,结构体变量名字的大小是花括号里面所有变量大小的总和,你可以用 sizeof(strcpu) 看看它的大小, str_cpu 的大小是里面大小的总和( 16 个字节),但是枚举类型那个名字的大小却不一样,只有他自己的大小( 4 个字节)。

#include "stdio.h"

 

int add ( int a, int b)

{

      return (a + b);

}

 

typedef struct str_cpu{

      int age;

      char * name;

      double f;

      int ( * func)( int , int );

}str_t;

 

str_t m_str_t;

str_t * str_p  = & m_str_t;

 

int main ( int argc,  char * argv[])

{

     

     m_str_t.age  = 10 ;

     m_str_t.name  = "Linux" ;

     m_str_t.f  = 1.077 ;

     m_str_t.func  = add;

 

     

     printf( "%d %d %s %f\n" ,m_str_t.age,m_str_t.func( 5 , 9 ),m_str_t.name,m_str_t.f);

     str_p -> age  = 12 ;

 

     printf( "str_p->age = %d\n" ,str_p -> age);

     

      return ;

}

union  数据类型

union 数据类型关键字的用法与 struct 的用法非常相似, union 维护足够多的空间来放置成员的一种。

union 中,所有的数据成员公用一个空间,同一个时间只能存储其中一个数据成员,所有成员变量的起始地址都是一样的

#include "stdio.h"

 

union CpuMachine

{

     char name;

     int number;

     char * str;

     double time;

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     printf( "UnionCpu %d double %d\n" , sizeof (UnionCpu), sizeof ( double ));

     ret

urn ;

}

看上面的例子, union 最大的数据是 double , 所以 CpuMachine 的长度也是 double 的长度。

但是在内存里如何组织这个大小的呢?

我们用一个视频来体验一下下面的代码

#include "stdio.h"

 

union CpuMachine

{

     char name;

     int number;

     char * str;

     double time;

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     UnionCpu.name  = 0x55 ;

     UnionCpu.number  = 500 ;

     UnionCpu.str  = "Microsoft Visual" ;

     UnionCpu.time  = 1.5678 ;

 

     printf( "UnionCpu %d double %d\n" , sizeof (UnionCpu), sizeof ( double ));

      return ;

}

每次单步执行之后,共用体之后的值把之前的值给覆盖了,一个时间点后,共用体只能保存一个值。

 

问题:

1 、数据类型是有不同大小的格子来组成的,那么不同的数据类型型格子保存在哪里呢?是由谁来决定的呢?

2 、说下下面代码的输出是多少?

#include "stdio.h"

 

union CpuMachine

{

     int i;

     char array[ 2 ];

}UnionCpu;

 

int main ( int argc,  char * argv[])

{

     UnionCpu.array[ = 0x55 ;

     UnionCpu.array[ 1 = 0x33 ;

 

     printf( "i 0x%x\n" ,UnionCpu.i);

      return ;

}

 

看完觉得有收获的,请帮忙点赞支持


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31561984/viewspace-2221200/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
微信公众号-嵌入式Linux 嵌入式开发有10余年,从刚开始的STC89C51单片机,STM32单片机,ARM,Linux ,Nordic ble ,Android系统开发,在学习和开发过程中,积累了很多经验,希望这些学习经验跟在码农路上一起奋斗的同学们一起分享。

注册时间:2018-11-13

  • 博文量
    60
  • 访问量
    68591