C语言学习笔记—指针

#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所指的变量的类型,而是改变了指向这个变量的指针的类型 
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jerry_no_name

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值