指针:c语言的特色

作用:对复杂数据进行处理,对计算机内存进行分配,让函数返回多个值。

(一)指针的定义和基本运用

地址:在定义变量或者执行程序的时候,变量或代码会被分配在相应的以字节为单位的存储器中,eg:int型假如需要2字节,那么就随机给他分配2字节的内存单元。计算机对于数据要进行操作,所以要有地址(所以对内存单元进行编号)。

也就是说,对于数据或变量,它们有类型【eg:int】还有专门的地址【让计算机找到它】和里面的内容。

指针:1.形式上:‘*’加上变量名(自取),在定义的时候就是: int *p;也就是说在变量前面加上‘*’就好了,‘*’在此处作用是声明符。表示,我们告诉计算机这是指针。注意:指针是一个个变量的集合,指针变量是具体某一个变量。‘*’只是在定义的时候作为声明符,它不是指针的一部分!!

2.指针的作用和用法:【作用:】通过储存其它变量的地址来访问其他变量。因为‘*’还有一个作用是表示间接访问,也就是说,【用法:】当我使用指针时,我先定义,在赋值【初始化,可以先让指针=0变成空指针,也可以一步到位的让指针直接等于我要访问的变量的地址】,最后在使用过程中*变量就等价于我访问的变量。eg:int *p ,a=4 ; p=&a;*p=6;向上面的代码,‘p=&a’,就是把a的地址放到指针变量p里面,【就算指针和其他变量用法不一样,但是它也是变量,也要放内容,只不过放的是其他变量的地址(&)而已】,然后*p表示间接访问指针p所储存的内容(此处是a的地址),实现了对a的间接访问。但是如果改一下例子:int *p,a=4;p=&a;p=6;这样的话emmm那就是p的内容变成了6而a的地址没有变,所以p不再是a的指针,咱也不知道会访问出个啥,问计算机吧。。。

3.指针与自增自减:复习:a++;表示先把当前a的值赋给a,在执行a+1;++a:表示先执行a+1,在把a的值赋值给a。自增与指针复合起来:eg:*p=*p+1等价于++*p等价于(*p)++,就是 先把*p所访问的变量的值+1,因为此处*p中的*表示间接访问符,所以*p是一个整体,又如:*p++等价于     *(p++)等价于*p=*p;p++;此处,先取*p的值作为表达式的值,再让p 加1,运算后,p不在指向原来被访问的变量。(带有间接访问符的变量再不同情况下有不同含义,初学者要小心。)

4.还有一些小细节:int *p=&a;等价于int *p;p=&a;        *p在运算过程中等价于a,因为*p的作用就是访问a,所以*p=5(间接访问的a=5)就是a=5;

5.指针之间的相互赋值只能发生在相同类型之间,如:int a=4;int *p1=&a,&p2=0;p2=p1;这段代码就把p1d的内容给了p2,让p2储存a的地址,也可以访问a。

(二)指针作为函数的参数:

举例子来运用:这段代码是这样的:有三个备选方案(函数)要用来交换a,b的值。最后只有方案2过了,我们来解释原因。

/*通过函数调用来交换变量的值[指针]##26*/
#include <stdio.h>
void swap1(int x, int y), swap2(int *px, int *py), swap3(int *px, int *py);

int main() {
	int a = 1, b = 2;
	int *pa = &a, *pb = &b;
	swap1(a, b);
	printf("a=%d b=%d\n", a, b);
	a = 1;
	b = 2;
	swap2(pa, pb);//也可以写成swap2(&a,&b);
	printf("a=%d b=%d\n", a, b);
	a = 1;
	b = 2;
	swap3(pa, pb);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

void swap1(int x, int y) {
	int t;
	t = x;
	x = y;
	y = t;
}

void swap2(int *px, int *py) {//*px=a;*py=b
	int t;
	t = *px;//*p代表间接访问了变量,这句话等于t=a;
	*px = *py;//等于a=b;一步到位,直接修改了主函数的变量
	*py = t;
}

void swap3(int *px, int *py) {
	int *pt;
	pt = px;
	px = py;
	py = pt;
}

熟悉了吧,那先补充几点:关于函数调用的规则:1.函数调用时的实参和形参之间的数据是单向的值传递。

实参传递给形参是单向传递,形参变量在未出现函数调用时,并不占用内存,只在调用时才占用。调用结束后,将释放内存。执行一个被调用函数时,形参的值如果发生改变,并不会改变主调函数中的实参的值。单向传递,只能由实参传给形参,反之不能。

形参如同公式中的符号,实参就是符号具体的值,在调用过程前必须得到赋值;调用过程就是实现形参与实参的结合,把实参的值通过调用传递给形参,相当于把值代入公式进行计算。

2.在上面那段话中,我们必须知道,int main中的实参在给自定义函数并运行结束的时候是不会改变的,因为它在主函数中还要继续发挥作用,向我们之前的求素数和,我们传入的两个区间范围不变,在主函数中传回来的值是以prime(m,n)==多少反映的,实参m和n,这两个范围并没有变,【当时多多少少有点脑子轴了,没反应过来】。

所以对上面的代码的解释:1.因为swap1传入的是a,b确定的值,但是函数调用结束过后swap1定义的变量会被销毁(也就是x,y被销毁)就算xy交换成功,但是也不可能反向传回给实参。

2.swap2( void swap2(int *px,int *py) ),定义的是指针,就意味着可以间接访问变量,方案2的核心思想是:先让形参通过指针间接访问变量来修改主函数 变量的值【t = *px;*px = *py;*py = t】,这几步直接改了主函数的值,函数调用结束后就算被销毁了,但是被访问的值依然改变(影响还在)。因为*p=a;

3.swap3中交换了指针变量的值(换了一下地址),但是并没有改变被间接访问的变量的值【实在不行就和swap2对比一下喽】

总之:函数本来不能通过调用改变主函数的变量的值,但是唯有通过指针作为形参这种形式,在函数中通过间接修改,来改变主函数的实参。

(三)使用指针让函数返回多个值:非传统意义上的返回多个值【更像是通过函数更改主函数已有的值】。还是像刚刚那样的原理,改变的是主函数里的几个函数。

用法:在变量中将变量地址作为实参,在被调用函数中通过*变量的间接访问来修改变量。

/*使用指针作为函数参数返回多个函数值##27*/
/*输入天数自动判断月日*/
#include <stdio.h>
void month_day(int year, int yearday, int *pmonth, int *pday);

int main() {
	int day = 0, month = 0, year, yearday;
	printf("enter year and yearday:");
	scanf("%d %d", &year, &yearday);
	month_day(year, yearday, &month, &day);//注意是把要被改变的量用&输入
	printf("%d - %d - %d", year, month, day);
	return 0;
}

void month_day(int year, int yearday, int *pmonth, int *pday) {//此处后两个形参是指针,用间接访问 来 改变主函数里面的值
	int a[2][13] = {//定义二维数组的时候要在每一行之间用,隔开
		{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
	};
	int flag = 0;
	int i = 0;
	if ((year % 4 == 0 && year % 100 == 0) || year % 400 == 0)
		flag = 1;
	for (i = 1; yearday > a[flag][i]; i++) {//注意判断条件
		yearday -= a[flag][i];
	}
	*pday = yearday;
	*pmonth = i;
}

自定义函数有多个形参要用,隔开,别打空格!!

谈谈对二级指针的想法:

指针的本质也是变量,所以它自身肯定也是有地址的现在我们又创造出一个指向它自己地址的变量,那么这个变量自然叫做二级指针喽。= ̄ω ̄=

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值