第一天 关于数据声明以及关键字const、static、volatile

本文深入解析C语言中的复杂概念,包括不同类型的指针声明、const关键字的多重用途、static的作用范围及volatile变量的特殊场景。通过实例讲解,帮助读者掌握这些关键概念,提升编程技巧。

一、数据声明
用变量a给出下面的定义
  a) 一个整型数(An integer)
  b) 一个指向整型数的指针(A pointer to an integer)
  c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)
  d) 一个有10个整型数的数组(An array of 10 integers)
  e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)
  f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)
  g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
  h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )
答案是: 
a) int a; // (An integer)
  b) int *a; //( A pointer to an integer)
  c) int **a; //( A pointer to a pointer to an integer)
  d) int a[10]; // (An array of 10 integers)
  e) int *a[10]; // (An array of 10 pointers to integers)
  f) int (*a)[10]; //( A pointer to an array of 10 integers)
  g) int (*a)(int); // (A pointer to a function a that takes an integer argument and returns an integer)
  h) int (*a[10])(int); // (An array of 10 pointers to functions that take an integer argument and return an integer)

二、const关键字:
首先,const意味着“只读”,可理解为常量。
 const int a;
  int const a;
  const int *a;
  int * const a;
  int const * a const;
  前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)

const的作用如下:
  1). 关键字const 的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
  2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
  3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

三、static
1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

四、volatile
一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
  1). 并行设备的硬件寄存器(如:状态寄存器)
  2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
  3). 多线程应用中被几个任务共享的变量
  回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。
  假设被面试者正确地回答了这是问题(嗯,怀疑这否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
  1). 一个参数既可以是const还可以是volatile吗?解释为什么。
  2). 一个指针可以是volatile 吗?解释为什么。
  3). 下面的函数有什么错误:
  int square(volatile int *ptr)
  { return ptr * ptr; }
  
  下面是答案:
  1). 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
  2). 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
  3). 这段代码的有个恶作剧。这段代码的目的是用来返指针
ptr指向值的平方,但是,由于
ptr指向一个volatile型参数,编译器将产生类似下面的代码:

  int square(volatile int *ptr)
  { int a,b;
  a = *ptr;
  b = ptr;
  return a * b;  }
  由于
ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
  long square(volatile int *ptr)
  { int a;
  a = *ptr;
  return a * a;}

#此文仅用于个人笔记#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值