Chinaunix首页 | 论坛 | 博客
  • 博客访问: 328100
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-06-16 13:17:43

1.声明对象的存储时间
一个对象的存储时间决定了他的生存周期。有三种存储时间:static, automatic,allocated。

错误代码:

点击(此处)折叠或打开

  1. char const *p;
  2. void dont_do_this() {
  3.     char const str[] = "This will change";
  4.     p = str; /* dangerous */
  5.     /* ... */
  6. }
  7. void innocuous() {
  8.     char const str[] = "Surprise, surprise";
  9.     printf("%s\n", p);
  10. }

  11. /* ... */
  12. dont_do_this();
  13. innocuous();
  14. /* now, it is likely that p is pointing to "Surprise, surprise" */
p是指向字符常量的指针,全文可见。第4行,str是automatic,它生存周期从dont_do_this()函数执行到其结束。当调用dont_do_this函数结束后,调用innocuous()函数,p指向"Surprise, Surprise",不是我们想要的结果。

正确:

点击(此处)折叠或打开

  1. char const *p;
  2. void is_this_OK() {
  3.     char const str[] = "Everything OK?";
  4.     p = str;
  5.     /* ... */
  6.     p = NULL;
  7. }
使用local stack变量作为返回值:

点击(此处)折叠或打开

  1. char *init_array() {
  2.     char array[10];
  3.     /* Initialize array */
  4.     return array;
  5. }
正确示范:

点击(此处)折叠或打开

  1. int main(int argc, char *argv[]) {
  2.     char array[10];
  3.     init_array(array);
  4.     /* ... */
  5.     return 0;
  6. }
  7. void init_array(char array[]) {
  8.     /* Initialize array */
  9.     return;
  10. }

2.如果使用restrict符号, 确保函数的源指针和目的指针指向的数据没有重叠.若发生重叠,其行为未定义。

restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码.

3.使用volatile来修饰的数据不能缓存
定义为volatile以后,编译器每次取变量的值的时候都会从内存中载入,这样即使这个变量已经被别的程序修改了当前函数用的时候也能得到修改后的值.

点击(此处)折叠或打开

  1. #include <signal.h>
  2. sig_atomic_t i;
  3. void handler() {
  4.     i = 0;
  5. }
  6. int main(void) {
  7.     signal(SIGINT, handler);
  8.     i = 1;
  9.     while (i) {
  10.         /* do something */
  11.     }
  12. }
假设i被缓存,则while将一直循环下去,即使受到SIGINT信号。

使用volatile,则每次while循环都会检测i的值:

点击(此处)折叠或打开

  1. #include <signal.h>
  2. volatile sig_atomic_t i;
  3. void handler() {
  4.     i = 0;
  5. }
  6. int main(void) {
  7.     signal(SIGINT, handler);
  8.     i = 1;
  9.     while (i) {
  10.         /* do something */
  11.     }
  12. }

4.函数指针指向其他函数时,确保指向的新函数的类型与原始函数类型相同,否则其行为未定义。

点击(此处)折叠或打开

  1. /* type 1 function has return type int */
  2. static int function_type_1(int a) {
  3.     /* ... */
  4.     return a;
  5. }
  6. /* type 2 function has return type void */
  7. static void function_type_2(int a) {
  8.     /* ... */
  9.     return;
  10. }
  11. int main(void) {
  12.     int x;
  13.     int (*new_function)(int a) = function_type_1; /* new_function points to a type 1 function */
  14.     x = (*new_function)(10); /* x is 10 */
  15.     new_function = function_type_2; /* new_function now points to a type 2 function */
  16.     x = (*new_function)(10); /* the resulting value is undefined */
  17.     return 0;
  18. }














阅读(544) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~