您的位置:首页 > 编程语言 > C语言/C++

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

2018-01-23 21:38 204 查看
在学习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、局部变量的作用域

int main()

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

  k=i+j;

  {

    int k=8;

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

  }

  printf(“%d\n”,k);
10
 }
在上面的代码中,第四行的k值为五,它的作用域为3-9行。第六行的k的值为8,它的作用域为6-7行。但是在6、7时,值为8的k,用我的理解是拥有更高的等级,所以第7行打印出来的k值为8。
 
7、定义和声明的区别
定义就是编译器创造一个对象,然后给这个对象一个名字和一个地址,并将这个名字和地址绑定。总的来说,定义就是创造性质的,从无到有。比如:int i;定义一个i变量并给一个地址。
而声明就是说明性质的。比如externint i;就是说明要引用外部变量i到该处。即此变量(函数)是在别处定义的,要在此处引用。
 
8、typedef和#define的区别
#define是宏,没有参加编译,在预处理的时候就被替换掉了。typedef是编译阶段的一部分。它的意义是单一的。typedef参加编译和链接,是重命名,可以为枚举结构体等重新命名,提高代码整洁。
总体来说#define是死的,它只会替换,而typedef是活的,它参与到编译中。
 
9、static对不同变量的作用
用static修饰局部变量时,在第一次调用时进行赋值、计算。在之后的调用中(第二次、第三次)只会在上次计算的值后进行计算,而不会再次赋值。
用static修饰全局变量时,会减小其作用域。比如没有static时,变量可在多个文件中使用,但用static修饰时,就变味了只对本源文件可见。
 
10、extern的用法
   
在源文件A里定义的函数,在其它源文件里是看不见的(即不能访问)。为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明:
  
 extern  函数原型;  

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

 
  注意这里的用词区别:在A里是定义,在B里是声明。一个函数只能(也必须)在一个源文件里被定义,但是可以在其它多个源文件里被声明。定义引起存储分配,是真正产生那个实体。而声明并不引起存储分配。打一个粗俗的比方:在源文件B里声明后,好比在B里开了一扇窗,让它可以看到A里的那个函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C