设为首页 加入收藏

TOP

C语言指针传递详解(二)
2015-01-22 21:26:31 来源: 作者: 【 】 浏览:97
Tags:语言 指针 传递 详解
令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。 当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
?
堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。
?
堆和栈的区别可以引用一位前辈的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
?
局部变量指针
如果不了解程序栈如何工作,就很容易犯返回指向局部数据指针的错误,看下面的例子:
?
#include
#include
int* allocateArray(int size, int value)
{
? ? int arr[size];
? ? for(int i = 0; i < size; i++) {
? ? ? ? arr[i] = value;
? ? }
? ? return arr;
}
int main()
{
? ? int* vector = allocateArray(5, 45);
? ? for(int i = 0; i < 5; i++) {
? ? ? ? printf("%d\n", vector[i]);
? ? }
? ? return 0;
}
一旦函数返回,返回的数组地址也就无效,因为函数的栈帧从栈中弹出了
?
有一种方法是把arr变量声明为static,这样会把变量的作用域现在在函数内部,但是分配在栈帧的外面,避免其他函数覆写变量值
?
#include
#include
int* allocateArray(int size, int value)
{
? ? static int arr[10];
? ? for(int i = 0; i < size; i++) {
? ? ? ? arr[i] = value;
? ? }
? ? return arr;
}
int main()
{
? ? int* vector = allocateArray(5, 45);
? ? for(int i = 0; i < 5; i++) {
? ? ? ? printf("%d\n", vector[i]);
? ? }
? ? return 0;
}
返回指针
从函数返回对象经常使用以下两种技术:
?
使用malloc在函数内部分配内存并返回其地址,调用者负责释放返回的内存
传递一个对象给函数,让函数修改它,这样分配和释放对象的内存都是调用者的责任
#include
#include
int* allocateArray(int size, int value)
{
? ? int* arr ?= (int*)malloc(size * sizeof(int));
? ? for(int i = 0; i < size; i++) {
? ? ? ? arr[i] = value;
? ? }
? ? return arr;
}
int main()
{
? ? int* vector = allocateArray(5, 45);
? ? for(int i = 0; i < 5; i++) {
? ? ? ? printf("%d\n", vector[i]);
? ? }
? ? free(vector);
? ? return 0;
}
下面这个版本的allocateArray函数传递了一个数组指针、数组的长度和用来初始化数组元素的值,返回指针只是为了方便
?
#include
#include
int* allocateArray(int *arr, int size, int value)
{
? ? if(arr != NULL) {
? ? ? ? for(int i = 0; i < size; i++) {
? ? ? ? ? ? arr[i] = value;
? ? ? ? }
? ? }
? ? return arr;
}
int main()
{
? ? int* vector = (int*)malloc(5 * sizeof(int));
? ? allocateArray(vector, 5, 45);
? ? for(int i = 0; i < 5; i++) {
? ? ? ? printf("%d\n", vector[i]);
? ? }
? ? free(vector);
? ? return 0;
}
传递指针的指针
将指针传递给函数的时候,传递的是值,如果希望修改原指针而不是指针的副本,就需要传递指针的指针
?
#include
#include
void allocateArray(int **arr, int size, int value)
{
? ? *arr = (int*)malloc(size * sizeof(int));
? ? if(arr != NULL) {
? ? ? ? for(int i = 0; i < size; i++) {
? ? ? ? ? ? *(*arr + i) = value;
? ? ? ? }
? ? }
}
int main()
{
? ? int* vector = NULL;
? ? allocateArray(&vector, 5, 45);
? ? for(int i = 0; i < 5; i++) {
? ? ? ? printf("%d\n", vector[i]);
? ? }
? ? free(vector);
? ? return 0;
}
二叉树递归实现与二重指针
  二叉树的诸多操作往往是通过递归调用来实现的,这就决定,不能只通过main函数实现全部过程,其中还需要调用main外定义的函数。也因此,对main调用外定义的函数的参数传递,就有了严格的要求。在网上查找很多关于二叉树建立的程序,但直接拷贝在自己计算机上运行却发现不少错误,无法编译通过。以下有关代码编译通过,不涉及二叉树的全部操作,着重通过C语言实现二叉树的创建过程说明递归实现与二重指针的相关问题。
?
1、二叉树的定义
?
二叉树的定义结构通常为如下形式:
?
typedef struct Node
{
? ? char ch;
? ? struct Node *lchild,*rchild;
}Node,*BTree;
Node一般可用来定义二叉树节点,而*BTree可用来定义指向二叉树(根节点)的指针
?
2、内存动态分配
?
采用内存动态分配需要用到malloc函数。值得注意的是,该函数在成功开辟新的内存时,默认返回void*指针,因此需要强制转换成Node*形式,其调用形式如(Node*)malloc(sizeof(Node))
?
3、递归调用
?
因为递归调用的需要,二叉树的一些操作需要独立作为一个函数。但是,这些函数是在main中调用,因此传递的参数和返回的值的处理是非常重要的。另外注意,对二叉树的操作,首先就需要知道二叉树的入口,即指向二叉树的指针,也即指向二叉树根节点的指针。因此,所传递的参数,则为指向根节点的指针。又因为涉及分配内存的操作,必须传递二级指针,如下程序,Creat
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇利用栈实现队列(C语言实现) 下一篇C语言里为何会有“2+2=5”的结果

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: