Chinaunix首页 | 论坛 | 博客
  • 博客访问: 480899
  • 博文数量: 76
  • 博客积分: 5196
  • 博客等级: 大校
  • 技术积分: 1414
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-10 18:43
个人简介

转了个圈,又回来了

文章分类

全部博文(76)

文章存档

2013年(1)

2011年(8)

2010年(9)

2009年(22)

2008年(36)

我的朋友

分类: 嵌入式

2009-11-24 20:00:21

函数的参数有很多种,有的是传值,有的是指针,有的是引用,有的是指向指针的指针。下面对各种用法做个总结1:函数参数
下面由两个例子来说明:
void f(int i)
{
    i = 0;
}
 
void f1(int *i)
    *i = 0;
}
 
mian()
{
    int x = 1, y = 1;
    f(x);
    f1(&y);
}
 
上面的例子很简单,是指针与值的区别,f不会改变传进来的参数的值,但是f1会改变值。原因是调用f(x)时,函数f会在栈中为变量x创建一个副本i,这样对i的改变并不会影响到x。同理f1(&y),函数f1也会在栈中为&y创建一个副本i,但是由于i是指向y的,所以对i指向的内容的操作同样是对y的操作,所以会改变y.
 
在看看下面一个函数:
void GetMemory(char *p)
{
p = (char*)malloc(100);
}

void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}

Test函数中调用GetMemory,这样GetMemory在栈中为str创建了个副本p,此时str指向空,同时p也指向空,当在GetMemory为p在堆空间中分配空间后,p指向了堆中的某个地址,而str同样指向空。所以会出错。这个原因是改的是对指针本身,而不是改他们共同指向的空间
 
改进很简单:
void GetMemory(char **p)
{
*p = (char*)malloc(100);
}

void Test(void)
{
char *str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);

free(str);
}

这样改的就是指向指针的指针的值了。

总结:在函数参数中,看是要改指针指向的内容,还是改指针本身,而改指针本身的地方就要特别注意了,他是能反映到参数上面的。这个时候可以加一层指针。

至于引用,C++ 中一般都用引用就可以了,C 中没有引用,就使用指针。引用就是给一个变量起了个别名而已。相当于同一个地址空间的两个不同的名字而已。

void function(int &refval)
{
refval=100;
}

int main()
{
int x=200;
function(x);
return 0;
}

总结2:函数返回值
函数的返回值,有的时候是返回一个值,有的时候返还一个地址,有时返回的地址可用,有时又不可用。
 
2.1 返回值
如:
int f()
{
    int i = 0;
    return i;
}
这个返回值是返回了i的值为0;
 
2.2返回指针
int f()
{
    int *i;
    *i = 0;
    return *i;
}
这个也是正确的,他返回的也是个值。
 
int* f()
{
    int *j;
    *j = 0;
    return j;
}
但是这个返还的就么有上面用处了,因为返回的是j,j的值是有函数f在栈空间分配的一个地址,比如是0x6789。0x6789里的值是0.但是当函数返回后,这个空间被回收,不能在对0x6789这个地址空间处理了。
 
2.3返回局部变量指针
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}

void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

这个例子同上面的道理是一样的,返回的p同样是在栈空间里分配的数组。

2.4返回全局变量指针

char *GetMemory(void)
{
char *p = "hello world";
return p;
}

void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

上面的空间有可用,因为p指向的是个常量,是个全局变量。同理对上面的一个改成

static char p[] = "hello world";

也是可以的,因为static变量存放在全局区

2.6返回堆指针

char *GetMemory(void)
{
char *p = (char*)malloc(num);

return p;
}

void Test(void)
{
char *str = NULL;
str = GetMemory();
free(str);
}

上面的函数也可以,因为返回的空间是在堆空间里分配。

总结:函数的返回值,如果是值,是可以的。如果返回的是地址,那就要注意了,要看返回的地址是在栈里分配的,还是在堆,全局区里。

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