(捌)指针基础

梗概

一、指针变量

在了解指针之前先要弄清楚地址的概念。

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统 根据城西中定义的变量类型,分配一定长度的空间。

例如:整型变量分配4个字节,字符型分配1个字节,单精度分配4个字节等。

内存区的每一个字节有一个编号,这就是“地址编号”,它就相当于旅馆中的 房间号,每一个房间都可以看作一块内存区域,都可以用来存放东西,我们给每个房间都编一个房间门 牌号,用于更好的区分每一个房间,内存中也是一样的,整个内存由很多个字节组成,每个字节都有其 对应的“房间号”,这就是“地址”了。

通过这个“房间号”就可以找到其对应的“房间”,然后就可以从房间里 取东西,或者把东西放进房间里了。

理解了地址的概念之后,那所谓的指针,就是内存地址,也就是地址的编号,可以把“指针指向地址” 理解成“用小本本把房间号记下来”,那这个小本本就相当于一个用于记房间号的指针了,一个变量的地址称为此变量的“指针”。

指针

指针有指针常量与指针变量之分,For example:&a是指针常量,用基类型与解引用符定义的p是指针变量。 

因此要区分好相关运算符:

解引用符、取值符
指针变量

二、指针与函数

两种应用:1、函数参数为指针类型的函数

函数的参数不仅可以是整型、浮点型、字符型的数据,还可以是指针类型。它的作用是将一个变量的地 址传递到另一个函数,如:

void fun1(int x,int y)
{//这里定义了一个普通函数fun1
printf(“x=%d\ty=%d\n”,x++,y++);
}
void fun2(int *x,int *y)
{//这里定义了一个形参为整型指针类型函数fun2,其形参为指针类型的变量
printf(“x=%d\ty=%d\n”,(*x)++,(*y)++);
//注意:和printf(“x=%d\ty=%d\n”,*x++,*y++);的区别,也就是有括号和没有括号的区别
}
int main()
{
int a=10,b=20,*p,*q;
fun2(&a,&b); //这里调用函数fun时,所传递的实参必须是地址
p=&a; //使用整型指针变量p指向整型变量a的地址
q=&b; //使用整型指针变量q指向整型变量b的地址
printf(“a=%d\tb=%d\n”,*p,*q);
fun2(p,q); //这里使用指针变量p和q作为实参传递
printf(“p=%d\tq=%d\n”,*p,*q);
return 0;
}

调用函数,传地址:
在函数的形参列表中定义指针变量

一个小插曲~🦉

w(゚Д゚)w  这是 c语言语法基础

名称类型
&name0x00000064171ef8a4 <字符串中的字符无效。>char *

这里错误的点有两个:①使用解引用、定义指针变量给它定义并赋初值时,要么使它的初值为NULL(空指针),要么给它赋一个地址,不要给它一个数值,它哪知道这个数在哪儿呀,之后要使传地址不是传不了吗。②啊啊最基本的;赋字符串怎么就只用char就不管了呢,还要用到数组

在change函数那块,改变地址上的值,这块代码修改好了:用字符串确实要多考虑一些,所以这里改传字符了;这些代码的宗旨是利用函数指针改变全局变量的值

传字符串:在主函数里,使用函数传数组地址时直接用数组名(在定义的change函数里没变过来😣还要加把劲才行)

小插曲先到此结束吧(如果有大佬指点迷津那就再好不过了)

2、指针函数

返回值为指针类型的函数称为“指针函数”。

注意:不要反馈出一个局部变量的地址——

#include<stdio.h>
//反馈出一个整型变量的地址   ——是什么类型吗?int*   
int* fun()
{
int a = 10;//是一个局部变量,作用范围:函数体
int*p = &a;
return p;
}//不要反馈出局部变量的地址

int main()
{
   int*p1 = fun();
   printf("%d\n", *p1);//这样做有问题  
   printf("%d\n", *p1);


   return 0;

very strange,right?

正确示范:

int* fun3(int *x,int y)//这是一个指针函数,返回值类型为整型int指针类型
{
*x+=y;
printf(“%d”,++*x);
return x; //返回指针变量x所指向的内存地址
}

指针函数使用场景:(在学习c++开辟动态内存时会用到)

需要去占用一块连续的存储空间,该函数反馈出这个空间首地址,方便我们管理该空间。

三、指针与数组

1、指针指向数组元素、指针指向的移动

整型的数组会发现它们的地址不是连续的,而是相差4;因此,假使 定义一个数组指针

int  *p=arr;//就是定义在数组的首地址,相当于 int *p=&arr[0];

那么p+1式子的结果是p下一个元素的地址
p+1  表达式的结果,加的是一个基类型(如果是地址值加1,就没有意义了)

一个数组间的地址值是不连续的

因此指针偏移的含义为:指针每次会以其基类型所占字节数为单位进行偏移

注意:自增自减运算、赋值运算符才能改变变量自身的值——

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (int i = 0; i < 10; i++) {
		printf("arr[%d]的地址是%#p\n", i, &arr[i]);
		//%#p  显示十六进制的前缀0x
		

	}
int* p = arr;
		p + 4;
		printf("直接把p+4这个表达式放在运行代码里,p的地址是%#p,对照前面看没变\n", p);
		printf("正确使用表达式,首位数组元素往后三位的元素是%d,它的地址是%#p\n", *(p + 3),(p+3));
		printf("正确使用表达式,首位数组元素往后三位的元素是%d,它的地址是%#p,这里用的是方括号,它们的作用是等价的",arr[3],&arr[3]);
}
因此指针可以将整个数组运行出来

[ ]也有解引用的 作用

在上述代码中,
 arr[3] 等价 *(arr+3) 

另外,p[3]也就是arr[3]的地址,即&arr[3]。

2、指针指向字符串

有意思——除了通过数组输出字符串,还可以用指针变量表示它:

char *p = “abcdefg”;
puts(p);
while (*p)
{
printf("%c\t", *(p++));
}

由于C语言中没有真正的字符串类型,可以通过字符数组表示字符串,因为它的元素地址是连续的,这就足够了。
C语言中规定数组代表数组所在内存位置的首地址,也是 str[0]的地址,即str = &str[0];
而printf(“%s”,str); 为什么用首地址就可以输出字符串?
举例:
char *s ;
s = “China”;
为什么可以把一个字符串赋给一个指针变量?

C语言中编译器会给字符串常量分配地址,如果 “China”, 存储在内存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 .
s = “China” ,其实真正的意义是 s =”China” = 0x3000;
————————————————
版权声明:本文为CSDN博主「xumengfan」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xumengfan/article/details/78148317

当用sizeof 测字节大小是,指针变量都是4字节,32位。

因为指针变量相当于一个路标,它不需要随所标记存贮的大小而改变

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

穿井侯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值