翁恺老师C语言学习笔记(十)指针_指针变量就是记录地址的变量

指针变量就是记录地址的变量

scanf函数
· 如果能够将取得的变量的地址传递给一个函数,能否通过这个地址在那个函数内访问这个变量
· scanf("%d", &i)
· scanf()的原型应该是怎样的?我们需要一个参数能保存别的变量的地址,如何表达能够保存地址的变量?

scanf()是C语言中的一个输入函数。与printf函数一样,都被声明在头文件stdio.h里,因此在使用scanf函数时要加上#include <stdio.h>。(在有一些实现中,printf函数与scanf函数在使用时可以不使用预编译命令#include <stdio.h>。)它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。

什么样的类型,可以接收取地址得到的地址?

指针
· 指针类型的变量就是保存地址的变量

int i;
int* p = &i; //“*”,指针符号,*p,表示p是一个指针
int* p,q;
int *p,q;

我们来看 int* p = &i;的含义,如果i的地址是0x0001,那么p的的地址就是0001,从这里可以得出p指向了i
当我们说p指向i时,其实就是说p的值指向了i那个变量的地址
在这里插入图片描述

    int* p,q;
    int *p,q;

他们的含义都带*,表示* p*p都表示p是一个int型的指针(这里的*靠近int或是靠近p含义都是一样的,),而q是一个普通的int类型

指针变量
· 变量的值是内存的地址
· 普通变量的值是实际的值
· 指针变量的值是具有实际值的变量地址

~
*作为参数的指针
· void f(int p);
· 在被调用的时候得到了某个变量的地址
· int i=0;f(&i);
· 在函数里面可以通过这个指针访问外面的i

void f(int *p); f函数是它是一个int类型的指针,在我们去调用这个f时,就需要给它一个地址,而不能给一个变量本身或者是这个变量的值
int i=0;f(&i); 用&符号取得变量i的地址,将这个地址赋予指针p

下面来看下例子

void f(int *p);

int main(void)
{
	int i = 6;
	printf("&i=%p\n", &i);// 打印出i的地址
	f(&i);// 将i的地址赋予f 
	return 0;
} 

void f(int *p)
{
	printf(" p=%p\n", p); // 打印出p的值,看他们是否相等	
}

运行结果

&i=0061FE9C
p=0061FE9C

这里看出,在main里有一个变量i=6,它的地址是 9C ,我们将9C这个地址取出来赋予了另外一个变量p,p的值是70,同时可以理解为p是一个指针,指向了变量i

有了上面的情况后,在f函数里面,我们有外面的main里面的i的地址,我们不知道它是i,我么只知道它的地址

如果不传地址进去,只得到它的值会是什么情况,看看下面的例子,新增g 函数

void f(int *p);
void g(int k); // 新增g函数 

int main(void)
{
	int i = 6;
	printf("&i=%p\n", &i); // 打印出i的地址
	f(&i); // 将i的地址赋予f 
	g(i); // 将i的值赋予g函数 
	return 0;
} 

void f(int *p) // 将*p的值赋予f 
{
	printf(" p=%p\n", p); // 打印出p的值,看他们是否相等	
}

void g(int k) // 
{
	printf(" k=%d\n", k); //打印出g,g得到的是i的值, 
} 

输出结果

&i=0061FE9C
p=0061FE9C
k=6

在g函数里,k取到的值k=i=6,k和外面的i没有任何关系,这是之前函数课程里的内容,现在我们通过指针变量p得到了i的地址,这使得f函数里面拥有能够访问外面那个函数的地址的能力

*访问那个地址上的变量
· *是一个单目运算符,用来访问指针的值所指向的地址上的变量
· 拿到这个变量后,它可以拿来做左值也可以拿来做右值
· int k= p;
· p = k+1;

void f(int *p);
void g(int k); // 新增g函数 

int main(void)
{
	int i = 6;
	printf("&i=%p\n", &i); // 打印出i的地址
	f(&i); // 将i的地址赋予f 
	g(i); // 将i的值赋予g函数 
	return 0;
} 

void f(int *p) // 将*p的值赋予f 
{
	printf(" p=%p\n", p); // 打印出p的值,看他们是否相等
	printf("*p=%d\n",*p); // 打印*p的值,将*p看成一个整数的整体	
}

void g(int k) // 
{
	printf(" k=%d\n", k); //打印出g,g得到的是i的值
 
} 

输出结果

&i=0061FE9C
 p=0061FE9C
*p=6
 k=6

在这里,我们通过*p这个指针访问到了int i 的值

如果我们给 *p =26时,i 的值会不会被改变?
那么我们可以通过调用g函数访问i的值

void f(int *p);
void g(int k); // 新增g函数 

int main(void)
{
	int i = 6;
	printf("&i=%p\n", &i); // 打印出i的地址
	f(&i); // 将i的地址赋予f 
	g(i); // 将i的值赋予g函数 
	return 0;
} 

void f(int *p) // 将*p的值赋予f 
{
	printf(" p=%p\n", p); // 打印出p的值,看他们是否相等
	printf("*p=%d\n",*p); // 打印*p的值,将*p看成一个整数的整体
	*p = 26;	
}

void g(int k) // 
{
	printf(" k=%d\n", k); //打印出g,g得到的是i的值
 
} 

输出结果

&i=0061FE9C
p=0061FE9C
*p=6
k=26

从这里看出,i的值被f函数调用后被改变了
我们在*p=26;时,也可以理解为是对i进行了改变,这就是指针

**指针*左值之所以叫左值
· 是因为出现在赋值号左边的不是变量,而是值,是表达式计算的结果:
· a[0] = 2;// 数组,取下标运算符,a[0]是运算结果
· *p = 3; // 是运算符,p是取得p的指针的地址所代表的变量,表达是运算的结果
· 指针是特殊的值,所以叫做左值

*指针的运算符&
· 互相反作用
· *&yptr -> *(&yptr) -> *(yptr的地址) ->得到地址上的变量 -> yptr
· &yptr -> &(yptr) -> &(y) ->得到y得地址,也就是yptr -> yptr

传入地址
· 为什么
· int i;scanf("%d",i);
· 当我们用scanf时,忘记&时编译没有报错,运行起来就会犯错

猜你喜欢

转载自blog.csdn.net/sevensolo/article/details/93309746
今日推荐