必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

与其他模块共享的函数或者变量要EXPORT到内核中

2019-09-12 19:42 来源:未知

我们都知道有 const 修饰时,就意味着是只读的。

关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有extern c的作用const 意味着"只读",下面的声明都是什么意思? const int a; int const a; const int *a; int const *a; const int const *a ;
前两个的作用是一样,a是一个常整型数。
第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。
第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。
最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。
结论: 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。
如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人 来清理的。) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。
(1)欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;
(3)在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。

NSInteger,int,long

  • 在32位系统中int 占4个字节 ,long 占4个字节 ,long long 占8个字节

  • 在64位系统中int 占4个字节 ,long 占8个字节 ,long long 占8个字节

  • int32_t 是int的别名,占4个字节 。int64_t 是long long的别名,占8个字节

这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:
1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。

这个简单的问题很少有人能回答完全。在C语言中,关键字static有三个明显的作用:

const 作用:
  1. 欲阻止一个变量被改变,可以使用 const 关键字;
  1. 对指针来说,可以指定指针本身为 const ,也可以指定指针所指向的数据为 const ,或二者同时指定为 const;
  2. 在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部是不能改变其值的;
  3. 对于类的成员函数,若指定其为 const 类型,则表明是一个常函数,不能修改类的成员变量。

那么如下的一些声明又是表达什么意思呢?

const int a; int const a; const int * a; int const * a; int * const a; int const * const a; const int * const a; 

const int a;声明了一个 const的 int 类型的变量 a

int const a;声明了一个 const的 int 类型的变量 a

const int * a;声明了一个指向 const int的指针 a,该指针指向的 int 类型的数是不可以修改的,但是指针是可以修改的。

int const * a;声明了一个指向 const int 的指针 a,该指针指向的 int 类型的数是不可以修改的,但是指针是可以修改的。

int * const a;声明了一个指向 int 的 const 指针a,该指针指向的 int 类型的数是可以修改的,但是指针是不可以修改的。

int const * const a;声明了一个指向 const int 的 const 指针a,该指针指向的 int 类型的数不可以修改的,而且指针也是不可以修改的。

const int * const a;声明了一个指向 const int 的 const 指针a,该指针指向的 int 类型的数不可以修改的,而且指针也是不可以修改的。

关键字volatile有什么含意?并给出三个不同的例子。一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
下面是volatile变量的几个例子: 并行设备的硬件寄存器(如:状态寄存器) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 多线程应用中被几个任务共享的变量 一个参数既可以是const还可以是volatile吗?解释为什么。 一个指针可以是volatile 吗?解释为什么。 下面是答案: 是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

NSInteger 的实现:
#if __LP64__
typedef long NSInteger; 
#else
typedef int NSInteger;
#endif

NSInteger可以自动判断,如果是32位的架构,它就用int,如果是64位,它就用long。

  1. 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
  2. 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。
    大多数应试者能正确回答第一部分,一部分能正确回答第二部分,但是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。

1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。

static 作用:
  1. 函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只分配一次,因此其值在下次调用时仍维持上次的值
  1. 在模块内的 static 全局变量可以被模块内的所用的函数访问,但不能被模块外其他函数访问;
  2. 在模块内的 static 函数只可以被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内;
  3. 在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
  4. 在类中的 static 成员函数属于整个类所拥有,这个函数不能接受 this 指针,因而只能访问类的 static 成员变量。

static 关键字的作用:
(1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

int、long、long long

unsigned int 0~4294967295
int 2147483648~2147483647
unsigned long 0~4294967295
long 2147483648~2147483647
long long的最大值:9223372036854775807
long long的最小值:-9223372036854775808
unsigned long long的最大值:1844674407370955161
__int64的最大值:9223372036854775807
__int64的最小值:-9223372036854775808
unsigned __int64的最大值:18446744073709551615

  • Int 类型的变量只能用于保存整型值,也就是不包含小数位数的值
  • float 类型的变量可以存储浮点数
  • double 和 char 类型一样,前者范围大约是后者的两倍。char 类型可以存储单个字符
  • char charVar = ‘a’
  • float 类型的变量可以存储包含小数位的值
  • 限定词 long 、longlong、short、unsigned、signed
  • long变量的具体范围也可以由具体的计算机系统决定 %li 将用十进制显示 long int 的值
  • 如果把限定词long放在int 声明前,那声明的整型变量在某些计算机上具有扩展的值域
  • 如果把限定词short放在int 声明前,表示声明特定的变量来存储相当小的整数 (用short是对内存空间的考虑,可以节约空间)
  • unsigned 放在 int 前,表示存储的是正数的整数变量
  • id 类型可以存储任何类型的对象,是多态和动态绑定的基础

考点:在嵌入式系统中,要时刻懂得移植的重要性,程序可能是很多程序员共同协作同时完成,在定义变量及函数的过程,可能会重名,这给系统的集成带来麻烦,因此保证不冲突的办法是显示的表示此变量或者函数是本地的,static即可。
在Linux的模块编程中,这一条很明显,所有的函数和全局变量都要用static关键字声明,将其作用域限制在本模块内部,与其他模块共享的函数或者变量要EXPORT到内核中。

2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

extern "C" 的作用:
(1)被 extern "C"限定的函数或变量是 extern 类型的; extern 是 C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器, 其声明的函数和变量可以在本模块或其它模块中使用。
(2)被 extern "C"修饰的变量和函数是按照 C 语言方式编译和连接的;
extern "C"的惯用法:
(1)在 C++中引用 C 语言中的函数和变量,在包含 C 语言头文件(假设为 cExample.h)时,需进 行下列处理: extern "C" { #include "cExample.h" } 而在 C 语言的头文件中,对其外部函数只能指定为 extern 类型,C 语言中不支持 extern "C"声明,在.c 文件中包含了 extern "C"时会出现编译语法错误。
(2)在 C 中引用 C++语言中的函数和变量时,C++的头文件需添加 extern "C",但是在 C 语言中不能直接引用声明了 extern "C"的该头文件,应该仅将 C 文件中将 C++中定义的 extern "C"函数声明为extern 类型。
10.为什么标准头文件都有类似以下的结构? #ifndef INCvxWorksh #define INCvxWorksh #ifdef cplusplus extern "C" { #endif /.../ #ifdef cplusplus } #endif #endif / __INCvxWorksh / 显然,头文件中的编译宏“#ifndef INCvxWorksh、#define INCvxWorksh、#endif” 的作用是防止该头文件被重复引用。

关键字static有什么作用?

  • 函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

    • 在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

    • 在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

    • 在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

    • 在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

static关键字至少有下列n个作用:
(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)限制变量的作用域,在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
(3)限制函数的作用域,在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
(4)在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;
(5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
关键字const有什么含意?
我只要一听到被面试者说:"const意味着常数"(不是常数,可以是变量,只是你不能修改它),我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着"只读"就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)
如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?
Const只是一个修饰符,不管怎么样a仍然是一个int型的变量
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
本质:const在谁后面谁就不可修改,const在最前面则将其后移一位即可,二者等效

3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

关键字const有什么含意?修饰类呢?

const 意味着"只读",下面的声明都是什么意思?

const int a;
int const a;
const int *a;
int * const a;
int const * a const;

前两个的作用是一样,a是一个常整型数。

第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。

第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。

最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

结论:

关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的) 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

  • 欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

  • 对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;

  • 在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

  • 对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;

  • 对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,指向的整型数是不可修改的,但指针可以,此最常见于函数的参数,当你只引用传进来指针所指向的值时应该加上const修饰符,程序中修改编译就不通过,可以减少程序的bug)。

大多数应试者能正确回答第一部分,一部分能正确回答第二部分,但是很少的人能懂得第三部分。这是一个应试者的严重的缺点,因为他显然不懂得本地化数据和代码范围的好处和重要性。

@synthesize和@dynamic分别有什么作用?

  • @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;

  • @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。

  • @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar
    ,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var
    时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

 

如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字 ,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:

考点:在嵌入式系统中,要时刻懂得移植的重要性,程序可能是很多程序员共同协作同时完成,在定义变量及函数的过程,可能会重名,这给系统的集成带来麻烦,因此保证不冲突的办法是显示的表示此变量或者函数是本地的,static即可。

TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:与其他模块共享的函数或者变量要EXPORT到内核中