dtcms文档 tws mirror centos laravel winforms encryption cakephp grails shiny ftp grid angular ui router vue实例 vue开发 bootstrap后台管理 less官网 python模块 python链接mysql数据库 python安装环境变量 random函数用法 python编程工具 python数字类型 java中的正则表达式 java编译环境 java中tostring方法 java如何使用 java字符串格式化 java包名 java操作数据库 java时间转时间戳 linux入门基础 服务器系统安装 go2lan ps镜头校正 拼多多商家下载 光标变粗 马颂德 nastran gif动画制作工具 linux解压缩命令
当前位置: 首页 > 学习教程  > 编程语言

9.1【C语言学习:指针/取地址运算/指针的使用】指针

2020/7/24 10:11:42 文章标签:

9.1【C语言学习:指针/取地址运算/指针的使用】指针

一、取地址运算:& 运算符取得变量的地址

1.运算符&

scanf ("%d", &i);// 这里的 & 就是取地址运算符

获得变量的地址,它的操作数必须是变量

int i; printf("%x",&i);

地址的大小是否与int相同取决于编译器,64 or 32位架构

nt i; printf("%p",&i);

示例1:Pointer1.c

#include <stdio.h>

int main(void)
{
	int i=0;
	int p;
	p=(int)&i;
	
	printf("0x%x\n", p);
	//%x——16进制 
	printf("%p\n", &i);
	//%p——输出地址 ;自己在前面加上0x,并且转换成16进制 
	//这两个的结果一样 
	
    printf("%lu\n", sizeof(int));//输出字节 
    printf("%lu\n", sizeof(&i));
    
	return 0;
}

2.&不能取的地址

&不能对没有地址的东⻄取地址

&(a+b)&(a++)&(++a)

3.&+

•变量的地址
• 相邻的变量的地址
• &的结果的sizeof
• 数组的地址
• 数组单元的地址
• 相邻的数组单元的地址
示例2:Pointer2.c

#include <stdio.h>

int main(void)
{
	int a[10];
	
	printf("%p\n", &a);
	printf("%p\n", a);
	printf("%p\n", &a[0]);
	printf("%p\n", &a[1]);
	//前三个地址一样
	//最后一个比前一个多4,相邻数组之间的差距永远是4 
    
	return 0;
}

运行结果:
在这里插入图片描述

二、指针

1.scanf

• 如果能够将取得的变量的地址传递给⼀个函数,能否通过这个地址在那个函数内访问这个变量?

scanf(“%d”, &i);

• scanf()的原型应该是怎样的?我们需要⼀个参数能保存别的变量的地址,如何表达能够保存地址的变量?

2.指针,就是保存地址的变量

int i;
//指针类型的变量 p存储的值是i的地址,就说p指向了i
int* p = &i;

//注意下面两种表达中,*的位置没有影响;
//下面的q仅仅表示int q;
//总之,*不是加给int,而是加给了p;
int* p,q;
int *p,q;

3.指针变量

• 变量的值是内存的地址
• 普通变量的值是实际的值
• 指针变量的值是具有实际值的变量的地址,如int * p中,指针变量p存储具有实际int值的

4.作为参数的指针

void f(int *p);

• 在被调用的时候得到了某个变量的地址:int i=0; f(&i);

• 在函数里面可以通过这个指针访问外面的这个i;
示例3:Pointer3.c

#include <stdio.h>

void f(int *p);
void g(int k);

int main(void)
{
	int i=6;
	printf("&i=%p\n", &i);
	f(&i);
	g(i);
	
	return 0;
}

void f(int *p)
{
	printf(" p=%p\n", p);
	printf("*p=%d\n", *p);
	*p=26;
	//*p表示(int* p = &i;)取得p这个指针它的地址所代表的那个变量
	//通过内部地址的访问,实现了:*p就代表了i,即*p=i
}

void g(int k)
{
	printf("k=%d\n", k);
}

运行结果:
在这里插入图片描述

5.访问那个地址上的变量 *

• * 是⼀个单目运算符,用来访问指针的值所表示的地址上的变量

int k = *p;
*p = k+1;
• 所以,* p 可以做右值也可以做左值,

•*左值之所以叫左值 是因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果:
a[0] = 2;
*p = 3; //*p表示(int* p = &i;)取得p这个指针它的地址所代表的那个变量
【它们是特殊的值,所以叫做左值】

6.指针的运算符: &(取地址)和 *(取地址所代表的变量)

• 它们是互相反作用

• * &yptr -> * (&yptr) -> * (yptr的地址)-> 得到那个地址上的变量 -> yptr

• &*yptr -> &(*yptr) -> &(y) -> 得到y的地址,也就是yptr -> yptr

三、指针的使用

1.指针应用场景1:交换两个变量的值

示例4:Pointer4-app1.c

#include <stdio.h>

void swap(int *pa, int *pb);

int main(void)
{
	int a= 5;
	int b= 6;
	swap(&a, &b);
	printf("a=%d,b=%d\n", a, b);
	return 0;
}

void swap(int *pa, int *pb)
{
	int t= *pa;
	*pa= *pb;
	*pb= t; 
}

运行结果:
在这里插入图片描述

2.指针应用场景2:函数返回多个值

• 函数返回多个值函数结果不止一个,某些值就只能通过指针返回

• 传入的参数实际上是需要保存带回的结果的变量
示例5:Pointer5_app2.c

#include <stdio.h>

void minmax(int a[], int len, int *max, int *min);

int main(void)
{
	int a[]={1,2,3,4,5,6,7,8,9,12,13,14,16,17,21,23,55};
	int min, max;
	minmax(a, sizeof(a)/sizeof(a[0]), &min, &max);
	printf("min=%d, max=%d\n", min, max);
	
	return 0;
}

void minmax(int a[], int len, int *max, int *min)
{
	int i;
	*min = *max =a[0];
	for(i=1; i<len; i++){
		*min = a[i];
	}
	if(a[i]>*max){
		*max = a[i];
	}
}

运行结果:
在这里插入图片描述

3.指针应用场景3:处理异常

示例6:Pointer6_app3.c

#include <stdio.h>
/*
      return  如果除法成功,返回1;否则返回0 
*/
int divide(int a,int b,int *result);

int main(void)
{
	int a=5;
	int b=2;
	int c;
	if(divide(a, b, &c)){
		printf("%d/%d=%d\n", a, b, c);
	}
	return 0;
}

int divide(int a, int b,int *result)
{
	int ret =1;
	if(b==0) ret=0;
	else{
		*result=a/b;
	}
	return ret;
}

运行结果:
在这里插入图片描述
• 函数返回运算的状态,结果通过指针返回
• 一般是让函数返回特殊的不属于有效范围内的值来表示出错: -1或0
• 但是当任何数值都是有效的可能结果时,就得分开返回了,相当于处理异常的try-catch
• 后续的语⾔(C++,Java)采⽤了异常机制来解决这
个问题——try-catch-finally

4.指针常见错误

• 定义了指针变量,还没有指向任何变量,就开始使用指针

#include <stdio.h>

int main(void)
{
	int i=6;
	int *p;
	*p=12;
//错误,定义指针变量,但没有指向任何变量,所以不能使⽤指针
	return 0;
}


本文链接: http://www.dtmao.cc/news_show_50216.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?