关于C语言数据类型的十个问题

在学习c的数据类型是,有很多疑惑和问题,在这里提一些问题并注上自己的理解和看法。

1、 什么是结构,怎么定义结构?

通俗的讲就是打包封装,把一些有共同特征的变量封装在内部,并通过一定方法修改内部变量。

定义结构变量的一般格式为:

     struct 结构名

     {

          类型  变量名;

          类型  变量名;

          ...

         } 结构变量;

  例如,struct stuff

{

        char job[20];

        int age;

        float height;

};

struct stuff Huqinwei;

就是完整的一次定义。structstuff是结构体数据类型名,相当于int{}表示在大括号中的内容也称为成员列表域表,成员列表中的数据类型可以是基本变量类型和数组类型,或者是一个结构体类型。

 

2、什么是指针的类型?

什么是指针所指向的类型?

我们只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。然后把指针声明语句中的指针名字和名字左边的指针声明符 *去掉,剩下的就是指针所指向的类型。比如:

(1)int *ptr;       指针的类型是int *        指针所指向的类型是int

(2)char *ptr;      指针的类型是char *      指针所指向的的类型是char

(3)int **ptr;       指针的类型是 int **      指针所指向的的类型是 int *

(4)int (*ptr)[3];    指针的类型是 int(*)[3]    指针所指向的的类型是 int()[3]

(5)int *(*ptr)[4];   指针的类型是 int *(*)[4]   指针所指向的的类型是 int *()[4]

 

3、什么是入栈、出栈,什么是栈区?

    栈的结构是“先进后出“的,就像堆积木一样,第一根放在最底层的地面上,然后一根一根往上堆。前一个放上去的总是被后一个放上去的压在底下。那我当我再想里面放一根的时候,总不能放中间或者放底下吧。所以要往上面加东西的时候,就得放在最上面。

以上就是进栈的原理,怎么出栈呢,很简单,直接从”积木”的最顶端取下来就行了。

接下来讲程序,由上面的分析我们可以知道一个道理,对于栈的操作,栈顶的元素很重要(也就是积木最上面的那根)。为什么呢。无论是出栈还是进栈,都跟那哥们有直接的联系。你想啊,如果要是有元素要进栈的话,那么它就不能当老顶了,那老顶之位就要交给压在它上头那位了;如果出栈呢,它也不能当老顶了,老顶之位就要交到原来压在它底下的那个。

所以一般的栈都将栈顶的那个元素所在的位置(内存地址数组类型的,或者指针节点类型的)视为栈的栈顶~!通过它来对栈进出进行操作。

而栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

 

4、联合体和结构体的区别

   联合体是一种构造数据类型,其用途为:使几个不同类型的变量共占一段内存(相互覆盖)

结构体是一种构造数据类型,其用途为:把不同类型的数据组合成一个整体(自定义数据类型)

结构体变量所占内存长度是各成员占的内存长度的总和。

联合体变量所占内存长度是各最长的成员占的内存长度。

联合体每次只能存放多个变量中的一种。

联合体变量中起作用的成员是最后一次存放的成员,

在存入新的成员后原有的成员失去了作用!

 

5、什么是volatile

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。所以volatile应该解释为直接存取原始内存地址易变的这种解释简直有点误导人。

 

6、局部变量的作用域

1  int main()

2  {

3    int i=2,j=3,k;

4    k=i+j;

5    {

6      int k=8;

7      printf(“%d\n,k;

8    }

9    printf(“%d\n”,k);

10  }

在上面的代码中,第四行的k值为五,它的作用域为3-9行。第六行的k的值为8,它的作用域为6-7行。但是在67时,值为8k,用我的理解是拥有更高的等级,所以第7行打印出来的k值为8

 

7、定义和声明的区别

定义就是编译器创造一个对象,然后给这个对象一个名字和一个地址,并将这个名字和地址绑定。总的来说,定义就是创造性质的,从无到有。比如:int i;定义一个i变量并给一个地址。

而声明就是说明性质的。比如externint i;就是说明要引用外部变量i到该处。即此变量(函数)是在别处定义的,要在此处引用。

 

8typedef#define的区别

#define是宏,没有参加编译,在预处理的时候就被替换掉了。typedef是编译阶段的一部分。它的意义是单一的。typedef参加编译和链接,是重命名,可以为枚举结构体等重新命名,提高代码整洁。

总体来说#define是死的,它只会替换,而typedef是活的,它参与到编译中。

 

9static对不同变量的作用

static修饰局部变量时,在第一次调用时进行赋值、计算。在之后的调用中(第二次、第三次)只会在上次计算的值后进行计算,而不会再次赋值。

static修饰全局变量时,会减小其作用域。比如没有static时,变量可在多个文件中使用,但用static修饰时,就变味了只对本源文件可见。

 

10extern的用法

    在源文件A里定义的函数,在其它源文件里是看不见的(即不能访问)。为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明:

    extern  函数原型;  

    这样,在源文件B里也可以调用那个函数了。  

    注意这里的用词区别:在A里是定义,在B里是声明。一个函数只能(也必须)在一个源文件里被定义,但是可以在其它多个源文件里被声明。定义引起存储分配,是真正产生那个实体。而声明并不引起存储分配。打一个粗俗的比方:在源文件B里声明后,好比在B里开了一扇窗,让它可以看到A里的那个函数。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值