《C专家编程》之一

一、解决函数返回指针的几种方法

  1. 返回一个指向字符串常量的指针。

  例子:

char* func()
{
    rturn "Only work for simple strings";
}

 

  优点:简单

  缺点:如果你需要计算字符串的内容,这种方法就无能为力了。如果以后需要修改返回的字符串,你也会遇到麻烦!

  2. 使用全局声明的数组。

  例子:

char my_global_array[255];

char* func()
{
    my_global_array[0] = '0';
    return my_global_array;
}

 

  优点:适用于自己创建的字符串,简单易用。

  缺点:任何人都有可能在任何时候修改这个全局数组,而且该函数的下一次调用也会覆盖该数组的内容。

  3. 使用静态数组。

  例子:

char* func()
{
    static char buff[20];
    buff[0] = '0';
    return buff;
}

 

  优点:可以防止任何人都修改这个数组,只有拥有指向该数组的指针的函数(通过参数传递给它)才能修改这个静态数组。

  缺点:但是,该函数的下一次调用将覆盖这个数组的内容,所以调用者必须在此之前使用或备份数组的内容。和全局数据一样,大型缓冲区如果闲置不用是非常浪费内存空间的。

  4. 显式地分配一些内存,保存返回的值。

  例子:

char* func()
{
    char *s = malloc(120);
    ...
    return s;
}

 

  优点:这个方法具有静态数组的优点,而且在每次调用时都创建一个新的缓冲区,所有该函数以后的调用不会覆盖以前的返回值。它适用于多线程的代码。

  缺点:程序员必须承担起内存管理的责任。

  5. 要求调用者分配内存类保存函数的返回值。程序员 malloc 和 free

  例子:

void func(char* result, int size)
{
    ...
    strncpy(result, "that'd be in the data segment, Bob", size);
}

buffer = malloc(size);
func(buffer, size);
...
free(buffer);

 

  优点:内存管理比较轻松。

  缺点:程序员还是需要自己管理内存,但是相比起第4种方法而言,malloc和free成对出现,管理内存会更方便。

 

 

二、关于声明

2.1 一些不能

  1. 函数的返回值不能是一个函数;foo() ()是非法的。

  2. 函数的返回值不能是一个数组;foo()[0]是非法的。

  3. 数组里面不能有函数;foo[]()是非法的。

 

三、关于函数参数传递

  有些C语言书籍声称“在调用函数时,参数按照从右到左的次序压到堆栈里。”这样的说法过于简单了。其实,参数在传递时首先尽可能地存放到寄存器中(为了追求速度)。

  注意:int型变量i和包含一个int型成员的结构(struct)变量s在参数传递时的方式可能完全不同。一个int型变量参数一般会被传递到寄存器中,而结构参数则可能被传递到堆栈中。

 

四、define和typedef的区别

4.1 其一

  define只是文本替换

  而typedef却不只是文本替换。typedef是一种彻底的“封装”类型——在声明它之后不能再往里面增加别的东西。如:

  #define peach int

  unsigned peach i;//No problem.

       typedef int banana;

  unsigned banana i;//Error.

4.2 其二

  在连续几个变量的声明中,用typedef定义的类型能够保证声明中所有的变量均为同一种类型,而用#define定义的类型则无法保证。

  #define int_ptr int *

  int_ptr chalk, cheese;  //as int * chalk, cheese;     means chalk is a pointer, cheese is int.

 

  typede int* int_ptr;

  int_ptr chalk, cheese;//two pointer.

 

 

 

 

  

  

 

posted @ 2014-09-09 16:38  wiessharling  阅读(130)  评论(0)    收藏  举报