传递指针可以让多个函数访问指针所引用的对象,而不用把对象声明为全局可访问,要在某个函数中修改数据,需要用指针传递数据,当数据是需要修改的指针的时候,就要传递指针的指针,传递参数(包括指针)的时候,传递的是它们的值,也就是说,传递给函数的是参数值的一个副本
?
?
?
用指针传递数据
用指针传递数据的一个主要原因是函数可以修改数据
?
下面的代码实现一个常见的交换函数:
?
#include
void swap(int* a, int* b)
{
? ? int tmp;
? ? tmp = *a;
? ? *a = *b;
? ? *b = tmp;
}
int main()
{
? ? int m, n;
? ? m = 5;
? ? n = 10;
? ? printf("m=%d, n=%d\n",m, n);
? ? swap(&m, &n);
? ? printf("m=%d, n=%d\n",m, n);
? ? return 0;
}
如果不通过指针传递参数,交换就不会发生,具体的原理参见任何一本
C语言教材
?
传递指向常量的指针
传递指向常量的指针是C中常用的技术,效率很高,因为避免某种情况下复制大量内存,如果不希望数据被修改,就要传递指向常量的指针
?
我们不能修改通过指向常量的指针传进来的值:
?
#include
void passconstant(const int* num1, int*num2)
{
? ? *num2 = *num1;
}
int main()
{
? ? const int a = 100;
? ? int b = 5;
? ? printf("a=%d, b=%d\n",a, b);
? ? passconstant(&a, &b);
? ? printf("a=%d, b=%d\n",a, b);
? ? return 0;
}
下面的代码会产生错误(第二个形参和实参的类型不匹配,试图修改第一个参数所引用的常量):
?
#include
void passconstant(const int* num1, int* num2)
{
? ? *num1 = 100;
? ? *num2 = 200;
}
int main()
{
? ? const int limit = 100;
? ? passconstant(&limit, &limit);
? ? return 0;
}
C语言中堆和栈的区别?
预备知识—程序的内存分配?
?
一个由C编译的程序占用的内存分为以下几个部分:
?
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。?
?
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。?
?
3、全局区(静态区)(static),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由
系统释放。?
?
4、文字常量区 —常量字符串就是放在这里的, 程序结束后由系统释放?
?
5、程序代码区—存放函数体的二进制代码。?
?
下面就说说C语言程序内存分配中的堆和栈,内存分配一般情况下程序存放在Rom或Flash中,运行时需要拷到内存中执行,内存会分别存储不同的信息,如下图所示:
?
?
?
? ? 内存中的栈区处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的,栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。另外还有静态区是分配静态变量,全局变量空间的;只读区是分配常量和程序代码空间的;以及其他一些分区。
?
堆栈的区别,来看一个经典例子:
?
#include
#include
int a = 0; //全局初始化区
char *p1; //全局未初始化区
int main()
{
? ? int b; //栈
? ? char s[] = "abc"; //栈
? ? char *p2; //栈
? ? char *p3 = "123456"; //123456\0在常量区,p3在栈上。
? ? static int c =0; //全局(静态)初始化区
? ? p1 = (char*)malloc(10); ?//堆
? ? p2 = (char*)malloc(10);
? ? return 0;
}
? ? 不知道你是否有点明白了,堆和栈的第一个区别就是申请方式不同:栈(英文名称是stack)是系统自动分配空间的,例如我们定义一个 char a;系统会自动在栈上为其开辟
?
空间。而堆(英文名称是heap)则是程序员根据需要自己申请的空间,例如malloc(10);由于栈上的空间是自动分配自动回收的,所以栈上的数据的生存周期只是在函数的运行过程中,运行后就释放掉,不可以再访问。而堆上的数据只要程序员不释放空间,就一直可以访问到,不过缺点是一旦忘记释放会造成内存泄露。还有其他的一些区别网上的总结的不错这里转述一下:
?
1.申请后系统的响应
?
栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
?
堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的 delete语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中,也就是说堆会在申请后还要做一些后续的工作这就会引出申请效率的问题。
?
2.申请效率的比较
?
栈:由系统自动分配,速度较快。但程序员是无法控制的。
?
堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
?
3.申请大小的限制
?
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在 WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
?
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
?
4.堆和栈中的存储内容
?
栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指