2016.7.25
任何类型的一维、二维、三维指针占用空间大小相同 4个字节(32位操作系统) 8个字节(64位)
指针与数组
//数组:表示一段连续的内存空间,用来存储多个相同类型的值。
// *******1.数组名的值是数组首元素的地址(即数组名是指向数组首元素的指针)
int array[5]={1,2,3,4,5};
printf("array adress is %p\n",array); // array adress is 0x7fff5fbff800
printf("array[0] adress is %p\n",&array[0]);// array[0] adress is 0x7fff5fbff800
printf("array[1] adress is %p\n",&array[1]);// array[1] adress is 0x7fff5fbff804
// *******2.数组名的值不能发生改变(默认为const类型),它只能为数组中第一个元素的地址
// 通过指针遍历数组中的元素
// p+1:指针向后移动1位(p+n:指针向后移动n位),p-1向前移动一位
int *p=array;
for (int i=0; i<5; i++) {
printf("array[%d] adress is %p\n",i,p++);// adress is 0x7fff5fbff800
//0x7fff5fbff804
//0x7fff5fbff808
//0x7fff5fbff80c
//0x7fff5fbff810
p--;
printf("array[%d] value is %d\n",i,*p++);// array value is 1,2,3,4,5
}
// printf("%d\n",*(++p)); // 改变指针指向
// printf("%d\n",p+1); // 仅仅获取下一个元素的值(get)
printf("%d \n",p[2]);// 结果: 3 把指针当数组用
void func(int array[5]){ // 参数是数组:其本质就是指针传递,退化成指针
printf("array 所占空间 :%lu\n",sizeof(array));// 8 个字节 (一个指针64位下所占空间)
printf("%d \n",array[2]); // 输出结果:3
printf("%d \n",*array); // 输出结果:1 使用时正常使用,无区别
array++; // 退化成指针
*(array+2)=1000;// 把主函数中array第4个元素的值40改为1000
}
func(array);//实参是数组,传递给形参之后,退化成指针(使用时无区别)
// 数组中存储int类型的指针
// 指针数组:数组中每个元素都是指针
int n1=10,n2=20,n3=30;
int *arr[3]={&n1,&n2,&n3};
printf("%d \n",*arr[0]); // 10
// 数组指针:一个指针指向一个数组
int (*p1) [3] ={1,2,3};
printf("%d \n",p1[0]); //p1+1 移动整个数组
内存分配:
静态内存分配:
编译时有系统完成,不占用CPU资源,需要在编译前确定内存块的大小。int num; int array[5];
同态内存分配:
程序执行时由程序员决定开辟空间(管理开辟,大小,释放空间),需要占用CPU资源, malloc
(1)静态内存分配: 栈区:由编译器开辟、释放空间(局部变量、函数形参) 局部变量:仅在当前作用域内有效。
常量区:常量,由编译器管理
全局/静态存储区:全局变量,静态变量也是由编译器管理 全局变量(所有函数体外定义的变量)
静态变量:static 内存不回收
代码区:存放函数体的二进制代码
(2)动态内存分配:堆区,程序执行时由程序员手动开辟空间(管理开辟,大小,释放空间),需要占用CPU资源,C:malloc C++:new
malloc :由#include <stdlib.h>提供函数
1.堆上空间没有名称,所以使用时必须使用指针来指向堆空间。
2.参数:在堆上开辟空间的大小(字节)
3.使用时需要将void * 转换成适用类型的指针
4.如果空间申请失败,函数将返回NULL
示例:
int * num=(int *)malloc(4);
float * num1=(float *)malloc(4);
* num=100;
* num1=100.000;
printf("%d \n",*num);
printf("%0.3f \n",*num1);
free( num);// 确认空间不被使用、释放空间
num=NULL;
free(num1);
num1=NULL;// 注意:malloc一定要与free对应出现
常量指针,指针常量
const 修饰谁,谁不可变
// 常量指针,不可以通过指针改变地址里的内容,但可以改变指向
int a=5;
const int * p=&a; // 常量指针
// *p=20; 地址里的内容不可改变
int b=10;
p=&b;
int * const p1=&b; // 指针常量
*p1=20;
// p1=&a; 指针指向不可改变
引用类型
公用一块内存空间,别名(引用在声明时,必须进行初始化)
int a=5,p=200;
int &b=a;// a=b=5
b=3; // a=b=3
函数传参传引用,形参是实参的别名,操作内存是同一块内存 偷天换日