#include "point.h"
// & 运算符,取得变量的地址
//在64位架构下,指针是8个字节,32位下是四个字节
//&运算符只能对变量取地址
//&(a+b) &(a++)之类的操作都是不可以的
void point1(void){
/*
//探究指针的字节大小
int i=0;
int p = (int)&i;
printf("0x%p\n",&i);
printf("0x%x\n",p);
printf("%lu\n",sizeof(int));
printf("%lu\n",sizeof(&i));
*/
/*
//两个相邻变量的大小
int i=0;
int p=0;
printf("0x%p\n",&i);
printf("0x%p\n",&p); //本地变量分配在堆栈里,堆栈中是自顶向下,先定义的变量地址更高,后定义的地址更低
*/
//数组取地址
int a[10];
printf("%p\n",&a);
printf("%p\n",a);
printf("%p\n",&a[0]); //运行结果可以得出,数组的名称就是数组第一个元素的地址,而且数组取地址不需要 &
printf("%p\n",&a[1]);
}
//指针
//指针是保存地址的变量,新建一个指针的方法如下:
//int *p=&i;//注意:这里的p得到了变量i的内存地址,而*p被赋予了通过p里的内存地址操作内存地址上变量的能力。*p即指针
//int *p,q;//这里新建了一个指针 ,和一个int类型的q
//指针作为参数时,函数原型如下: void f(int *p); 而调用函数时 f(&i);函数里可以通过指针访问外面这个i
//探究指针做函数参数
void f(int *p){
printf(" p=%p\n",p);//p获取了外面变量i的地址
printf("*p=%d\n",*p);//通过*p指针,获取了i的值
*p=26;//通过指针改变i的值
}
void point2(void){
int i=6;
printf("i=%d\n",i);
printf("&i=%p\n",&i);
f(&i);
printf("i=%d\n",i);//检验i的值是否改变
}
//指针的运用---值的交换
void swap(int *a,int *b){
int temp=*a;
*a=*b;
*b=temp;
}
void point3(){
int a=1;
int b=2;
printf("a=%d\n",a);
printf("b=%d\n",b);
swap(&a,&b);
printf("a=%d\n",a);
printf("b=%d\n",b);
}
//指针的运用2---传递参数并且改变参数,把改变后的参数作为结果。返回值变运行状态
//数组做函数参数,实际上是传入指针
void minmax(int *a,int len,int *min,int *max){
int i;
*min=*max=a[0];
for(i=0;i<len;i++){
if(*min>a[i]){
*min=a[i];
}
else if(*max<a[i]){
*max=a[i];
}
}
}
void point4(void){
int a[]={2,5,6,4,7,1,9,46,3,4,56};
int min,max;
minmax(a,sizeof(a)/sizeof(a[0]),&min,&max);
printf("min is %d\n",min);
printf("max is %d\n",max);
}
//指针与数组
//数组做函数参数,实际上是传入指针
//int sum(int *ar,int n) 等价于 int sum(int ar[],int n)
//数组变量是特殊的指针,所以对数组取地址不需要 &,即 int a[10]; int *p=a;其实a的地址等于a[0]的地址,即 int *p=a也可等价为 int *p=a[0];
//但是数组的单元取地址,需要 & ,即 int *p = &a[1];
//数组变量是const类型的指针,不能被赋值,即所指的地址不能被改变,在数组被创建时,这个特殊的指针指向的地址就固定下来了
//指针与const
/*
例如: int *const q =&i; //q是const,表示一旦得到某个变量的地址,不能再指向其他变量
所以指针不能变化,即 q++不被允许
*/
/*
const int *p=&i; //表示不能通过这个指针去修改变量(并不能使得这个变量变为const)
即 *p=26不被允许,但是 i=26,是可以的
*/
//以上这两种情况,判断是的依据是const是在 * 的前面还是后面
//转换
/*
可以把一个非const的值转换成const的
例如:
void f(const int *x);
int a=15;
f(&a);
这样的意义在于,不能通过指针,改变变量。进而保证数据安全
*/
//const数组
/*
例如:
const int a[]={1,2,3,4,5,6};
本身数组就是特殊的指针,他指向的地址不能改变 伪代码即 int * const a
又在数组前加上const,即 const int * const a,则数组每个单元也都是 const int
所以const int a[],必须通过初始化进行赋值
*/
//保护数组值
/*
当希望传入函数一个数组,又不希望函数可以修改数组,可以在函数原型进行设置,即
int sum(const int a[],int length);
*/
//指针运算
void point5(void){
char ac[]={0,1,2,3,4,5,6,7,8,9,};
char *p=ac;
char *p1=&ac[5];
printf("p1-p=%d\n",p1-p);//指针相减,C语言会自动帮我们得出两个地址之间隔了多少个 sizeof(指针类型)
printf("p=%p\n",p);
printf("p=%p\n",p+1);
/*
*p--->ac[0]
*(p+1)--->ac[1]
*/
int ai[]={0,1,2,3,4,5,6,7,8,9,};
int *q=ai;
printf("q=%p\n",q);
printf("q=%p\n",q+1);//指针的移动,是以指针类型所占字节的大小移动的
}
/*
*p++,这个特殊的用法在于,先取出地址,完事后顺便移到下一个位置,在电脑上有专门对应这个用法的汇编语言
*/
/*
指针的类型
变量类型与指针类型要匹配,否则可能出现错误
*/
/*
指针的转换
void *表示不知道指向什么东西的指针
计算时与char*相同(但不想通)
指针可以转换类型,比如:
int *p=&i; void *q=(void*)p;这实际上没有改变p所指的变量的类型,而是改变了指向这个变量的指针的类型
*/