必须掌握很牢的关键字

关键字static的作用是什么?

1).函数体static变量的作用范围为该函数体,该变量的内存只被内存分配一次,因此其值在下次调用的时仍然维持上次的值

2)模块内static全局变量可以被模块内所用函数访问但不能被模块外其它函数访问

3)模块内static函数只可被这一模块中内的其他函数调用,这个函数的使用范围被限制在申明他的模块内。

4)中的static成员变量属于整个类所有,对类的所有对象只有一份拷贝。

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

关键字volatile有什么含意 并给出三个不同的例子。

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:

1).并行设备的硬件寄存器(如:状态寄存器)

2).一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)

3).多线程应用中被几个任务共享的变量

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。

1).一个参数既可以是const还可以是volatile吗?解释为什么。

是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2).一个指针可以是volatile吗?解释为什么。

是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。



3).下面的函数有什么错误:

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的值可能被意想不到地该变,因此ab可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int
ptr)

{

int a;

a = *ptr;

return a * a;

}



宏和内联函数

先说宏和函数的区别:

1.宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类型的,可以是各种各样的类型.

2.宏的参数替换是不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的.

3.宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的是编译的时间,而函数占用的是执行时的时间.

4.宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参作为函数的局部变量,显然是占用内存的.

5.函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,再返回主调函数,此时再恢复现场,这些操作,显然在宏中是没有的.

现在来看内联函数:

所谓"内联函数"就是将很简单的函数"内嵌"到调用他的程序代码中,就是在调用函数的地方不是跳转,而是把代码直接写到那里去,只样做的目的是为了避免上面说到的第5,目的旨在节约下原本函数调用时的时空开销.对于短小的代码来说,inline可以带来一定的效率提升,而且比宏更安全可靠。

必须注意的是:(只用于如下情况)

(1)作为内联函数,函数体必须十分简单,不能含有循环、条件、选择等复杂的结构,否则就不能做为内联函数了。

(2)一个函数不断被重复调用。

事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。



const有什么用途,请至少说明两种。

c程序中,const的用法主要有定义常量、修饰函数参数、修饰函数返回值等3个用处。在c++程序中,它还可以修饰函数的定义体,定义类中某个职位为恒态函数,即不改变类中的函数成员。

(1)可以定义const常量2const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

SizeofStrlen的区别与联系(转)

1.sizeof操作符的结果类型是size_t,它在头文件中typedefunsigned int类型。

该类型保证能容纳实现所建立的最大对象的字节大小。

2.sizeof是算符,strlen是函数。

3.sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以''\0''结尾的。

sizeof还可以用函数做参数,比如:

short f();

printf("%d\n", sizeof(f()));

输出的结果是sizeof(short),即2

4.数组做sizeof的参数不退化,传递给strlen就退化为指针了。

5.大部分编译程序 在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因

char str[20]="0123456789";

int a=strlen(str); //a=10;

int b=sizeof(str); //b=20;

6.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。

7.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

8.当适用了于一个结构类型时或变量,sizeof返回实际的大小,

当适用一静态地空间数组,sizeof归还全部数组的尺寸。

sizeof操作符不能返回动态地被分派了的数组或外部的数组的尺寸

9.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,

如:

fun(char [8])

fun(char [])

都等价于fun(char *)

C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小

如果想在函数内知道数组的大小, 需要这样做:

进入函数后用memcpy拷贝出来,长度由另一个形参传进去

fun(unsiged char *p1, int len)

{

unsigned char* buf = new unsigned char[len+1]

memcpy(buf, p1, len);

}

我们能常在用到sizeofstrlen的时候,通常是计算字符串数组的长度

看了上面的详细解释,发现两者的使用还是有区别的,从这个例子可以看得很清楚:

char str[20]="0123456789";

int a=strlen(str); //a=10; >>>> strlen计算字符串的长度,以结束符0x00为字符串结束。

int b=sizeof(str); //b=20; >>>> sizeof计算的则是分配的数组str[20]所占的内存空间的大小,不受里面存储的内容改变。

上面是对静态数组处理的结果,如果是对指针,结果就不一样了

char* ss = "0123456789";

sizeof(ss)结果4===》ss是指向字符串常量的字符指针,sizeof获得的是一个指针的之所占的空间,应该是长整型的,所以是4

sizeof(ss)结果1===》ss是第一个字符 其实就是获得了字符串的第一位'0'所占的内存空间,是char类型的,占了1

strlen(ss)= 10 >>>>如果要获得这个字符串的长度,则一定要使用strlen




原文链接: https://www.cnblogs.com/yuanfang/archive/2010/12/23/1914864.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/19182

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午8:10
下一篇 2023年2月7日 下午8:11

相关推荐