【1】关键字类型题
常见的关键字有 sizeof、static、const、volatile
1、sizeof:通常与strlen做比较不同
例1:char str[] = “Hello” ;
char *p = str ;
int n = 10;
请计算
(1)sizeof (str ) = 6
(2)sizeof ( p ) = 4
(3)sizeof ( n ) = 4
(4)void Func ( char str[100])
{
…… ;
}
请计算sizeof( str ) = 4
(5)void * p = malloc( 100 );
请计算sizeof ( p ) = 4
例2:sizeof和strlen的区别
Sizeof是求数据类型所占空间的大小,是一个操作符,在编译时计算出结果
Strlen是求以\0结束的字符串的实际长度,是一个函数,在运行时才运算出结果,使用strlen求长度时需要进行初始化,所以没有初始化结果未知。
2、static:通常被问作用,以及在程序中有两处陷阱需要注意:函数中static修饰局部变量和static修饰全局变量。
例1:static有什么用途?(请至少说明两种)
1、Static定义的全局变量只能在本文件中使用,
2、加了static的局部变量会延长其生命周期,存在于整个程序的执行过程,但是其他函数无法使用(变量不可,地址可以)
3、Static函数只会在该模块中可见.
例2:在程序执行过程中,该程序的某一个函数func()中申请的static型变量V有以下哪些特性( BD)。× AB
A V仅能被func()使用
B V存在于整个程序执行过程
C V存在于func()被调用期间
D V能被整个程序使用
例2:下面的代码输出的结果是什么?为什么? 15
int counter(int i)
{
static int count = 0;
count = count + i;
return count;
}
int main(void)
{
int I,j;
for(i=0; i<=5; i++) j =coutner(i);
printf(“%d\n”,j);
return 0;
}
3、const:通常考察作用
例1:const 有什么用途?(请至少说明两种)
1、定义常量
2、修饰函数参数 返回值,被修饰的东西会被保护起来,不会被改变。
3、const 还可以用来修饰数组/数组 const char s[]="David";如果没有const,我们可能会在后面有意无意的写name[4]='x'这样的语句,
这样会导致对只读内存区域的赋值,然后程序会立刻异常终止。。
4、修饰全局变量,比如多任务机制中的共享资源
也许你可能会问,即使不用关键字 const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:
1). 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。
如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)
2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
3). 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。
例2:请问以下代码有什么问题:
char* s="AAA";
printf("%s",s)
s[0]='B';
printf("%s",s);
有什么错?
因为AAA 是字符串常量 编码时通常需要加const, const char* s="AAA";
因为AAA是常量 所以不能赋值
例3:const修饰指针
const(*号)左边放,我是指针变量指向常量;
const(*号)右边放,我是指针常量指向变量;
const(*号)两边放,我是指针常量指向常量;
4、volatile:通常考察作用和使用环境
例1:关键字volatile有什么含意? 并给出三个不同的例子。
volatile 修饰的变量是说明该变量的值会随时发生变化的,每次用的时候需要从存储该变量的地址中直接获取
1.中断服务程序中修改的供其他程序检测的变量需要加volatile
2.多任务环境下个任务间共享的标志位需要加volatile
3.存储器映射的硬件寄存器通常也要加volatile
例2:一个指针可以是volatile吗?
可以,因为指针和普通变量一样,有时也有变化程序的不可控性。
常见例:子中断服务子程序修改一个指向一个buffer的指针时,必须用volatile来修饰这个指针。
例3. 一个参数既可以是const还可以是volatile吗?解释为什么。
是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
例4. 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
这段代码的有个恶作剧。这段代码的目的是用来返指针*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