Skip to content

Latest commit

 

History

History
92 lines (64 loc) · 2.02 KB

byval.md

File metadata and controls

92 lines (64 loc) · 2.02 KB

回目录

值传递

  在函数调用那一篇里已经揭开了值传递的真相: 实参、形参有各自的存储空间(实参也可能只是一个值, 而没有存储空间),实参 -> 形参是个值拷贝的过程, 在函数调用前完成了这个拷贝过程, 此后如果函数中对形参进行修改,实参的值不会跟着变。

  但并不是我们就没办法在函数中修改外部变量了, 用指针就好了,我们不需要修改指针的值, 而只是修改指针指向的内存块:

0重指针(基本类型、结构体)

int add(int a, int b)
{
	return a + b;
}

  只有这种参数的函数,只需要参数的值,进行计算后返回结果, 不需要修改外部变量。

1重指针

void swap(int *a, int *b)
{
	int t = *a;
	*a = *b;
	*b = t;
}

  使用场景:

int a=1, b=2;
swap(&a, &b);

  函数中使用 1 重指针一般出于两种目的:

  1. 函数中要修改外部 基本类型 或 结构体 的值。
  2. 为了节省参数空间。假设函数想要读一个外部的 占用空间很大的结构体变量,比如有 4KB 大小, 虽然根本没想改它,但是如果用指针接收它的地址, 参数只占 4 字节;如果用结构体作为参数, 参数要占 4KB 的内存,而且还要进行值拷贝!
    用 char* 来接收字符串也可以看做是出于节省空间的目的。

2重指针

  C 标准库的头文件 string.h 中提供了一个 strdup 函数:

char *strdup(char *s);

  该函数的作用是复制字符串, 返回的字符串的存储空间是动态申请的,不是原来字符串的空间。 如果你是第 1 次听说有这个函数,不要妄自菲薄, 我也是大三下才知道的O(∩_∩)O~

  现在不用返回值,用 2 重指针来实现这个函数:

void my_strdup(char **p, char *s)
{
	unsigned int len = strlen(s) + 1;

	*p = (char *)malloc(len);
	memcpy(*p, s, len);
}

  使用场景:

char *s = "abc";
char *d = NULL;

my_strdup(&d, s);

  从这个例子中可以看出 2 重指针用于需要修改指针的时候, 一般是要在函数中为指针动态地申请空间。 而这一般可用返回指针来实现,但是如果有多个指针要一并修改, 用 2 重指针就要方便很多,因为返回值只有 1 个, 而参数的个数在语法上是没有限制的。

  strdup 返回的字符串用完后不要忘了 free 哦!

  另外,一般没有使用 3 重以上指针作参数的必要。

回目录