初识指针
初识指针
一、什么是指针?
在了解指针之前先要先弄清楚地址的概念。
如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。
例如:整型变量分配4个字节,字符型分配1个字节,单精度分配4个字节等。内存区的每一个字节有一个编号,这就是“地址编号”,它就相当于旅馆中的房间号,每一个房间都可以看作一块内存区域,都可以用来存放东西,我们给每个房间都编一个房间门牌号,用于更好的区分每一个房间,内存中也是一样的,整个内存由很多个字节组成,每个字节都有其对应的“房间号”,这就是“地址”了。通过这个“房间号”就可以找到其对应的“房间”,然后就可以从房间里取东西,或者把东西放进房间里了。
理解了地址的概念之后,那所谓的指针,就是内存地址,也就是地址的编号,可以把“指针指向地址”理解成“用小本本把房间号记下来”,那这个小本本就相当于一个用于记房间号的指针了,一个变量的地址称为此变量的“指针”。
二、指针常量与指针变量
1、指针常量
? 之前有了解过不同数据类型的变量所占内存字节数的这个概念,那么系统在编译时给一个变量分配的内存地址就称为此变量的“指针”,这个指针的指向是无法改变的,所以又称为指针常量,数组的地址也是指针常量(也称为地址常量)。
int a = 10;
//&a = 10000;
//&a取变量a的地址,是一个地址常量,不能够改变它的位置scanf("%d",&a);
//输入222
printf("a=%d\t &a=%p/n",a,&a);
//输出地址
文章图片
2、指针变量 (1)指针变量的概念
如果有一个变量专门用来存放另一个变量的地址,则称这个变量为“指针变量”,也就是说C语言中有一类变量是专门用来存储(指向)地址的,我们将它称为“指针变量”,指针变量的中存储的地址可以被改变,也就是可以改变指针变量的指向,就好比一张纸或一个小本本,写着一个房间的房间号,那把这个房间的房间号擦掉,写上另一个房间的房间号也是可以的,这就是指针变量和指针常量最大的区别所在了,可以改变指针变量的指向。
//定义指针变量格式:数据类型 *变量名;
int* p;
(2)指针变量的定义
定义指针变量的一般格式:
类型名* 指针变量名;
int a= 10;
int* p;
//定义了一个整型指针变量p,可以用于指向整型数据的地址(里面保存的是整型变量的地址)
p = &a;
//将整型变量a的地址赋值给整型指针变量p,整型指针p指向了整型变量a的地址。int*p,*q;
char* p1,*q1;
double *p2,*q2;
/* 注意:左端的int、char等是在定义指针变量时必须指定的“基类型”。指针变量的基类型用来规定此指针变量可以指向的变量的类型。如:上面定义的*p和*q只能用于指向int整型变量的地址,p2和q2只能用于指向double双精度类型变量的地址。 */
char *q;
int *p;
printf("%d %d\n",sizeof(p),sizeof(q));
//都输出为4,指针变量所占内存大小一般是占4个字节
(3) 指针变量的引用:
int* p;
//定义了一个整型指针变量p,这里的'*'是指针变量定义符
*p;
//*p解引用,这里'*'是解引用符号
int a=10;
int *p;
p = &a;
printf("*&a=%d");
//对a的地址进行解引用,输出为10,。
printf("&p=%p ");
//输出为指针变量p的地址(p自己的地址,不是存储其他变量地址的地址)
与指针和地址相关运算符:’*’(指针运算符)和’&’(取地址运算符)//区别对待位运算符&
//例如:int a,*p;
p=&a;
*p=10;
//在引用指针变量时,有以下几种情况:
//1、给指针变量赋值
如:int a = 10,b=20;
int *p=&a;
//定义一个整型指针变量p,初始化p的值为a的地址,也就是p指向a地址/*解引用:*/
*p=30;
//通过指针变量p引用a变量,改变a的值为30
//这里的’*’为解引用符号,*p引用指针变量p所指向地址中对应的值
scanf(“%d”,p);
//scanf通过指针变量p给变量a赋值
printf(“%d\n”,*p);
//通过指针变量p输出变量a的值
*p=b;
//将b的值放入指针变量p所指向的内存地址中(a的地址单元中)
p=&b;
//改变指针p的指向,指针p不再指向a的地址了,而是指向b的地址
printf(“%d\n”,*p);
//输出变量b的值//输出内存地址编号
printf(“%p\n”,p);
//以十六进制的格式输出指针变量p所指向地址的内存地址编号
printf(“%d\n”,&a);
//以十进制的格式输出变量a所在的内存地址编号
printf(“%o\n”,&b);
//以八进制的格式输出变量b所在的内存地址编号
printf(“%p\n”,&p);
//以十六进制的格式输出指针变量p所在的内存地址编号
三、指针变量作为函数参数 函数的参数不仅可以是整型、浮点型、字符型的数据,还可以是指针类型。它的作用是将一个变量的地址传递到另一个函数中。
1、函数参数为指针类型的函数:
//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时,所传递的实参必须是地址
printf(“a=%d\tb=%d\n”,a,b);
//输出的a和b的值为11,21
p=&a;
//使用整型指针变量p指向整型变量a的地址
q=&b;
//使用整型指针变量q指向整型变量b的地址
fun2(p,q);
//这里使用指针变量p和q作为实参传递
printf(“*p=%d\t*q=%d\n”,*p,*q);
return 0;
}
2、指针函数
//返回值为指针类型的函数称为“指针函数”:
int *fun3(int *x) //这是一个指针函数,返回值类型为整型int指针类型
{//int* x = &a;
++*x;
return x;
//返回指针变量x所指向的内存地址}//调用
int a=10;
int* p;
p=fun3(&a);
printf("a=%d\t");
//输出11;
int *fun4()
{
int a=10;
//局部变量:出了作用域,内存挥被释放
//如果加static,出了作用域,其内存不会被释放,但是只能在作用域范围内使用
return &a;
//返回a内存地址
//注意:不允许返回局部变量的地址}int* p;
p=fun4();
//p=&a;
使用了非法空间
四、通过指针引用数组 1、数组元素的指针
数组元素的地址表示:
如:int a[10] = {0,1,2,3,4,5,6,7,8,9},*p;
&a[0]; //引用数组元素a[0]地址的表示方法
2、指针指向数组元素
p=&a[1];
//指针变量p指向数组元素a[1]的地址
3、指针指向的移动(指针的偏移)
int a[10] = {0,1,2,3,4,5,6,7,8,9},*p;
p=&a[0];
++*p;
//指针指向地址中的数值加1
printf(“%#p\n”,p);
//打印指针变量p所指向的地址编号
p++;
//指针移动到数组元素a[1]的位置
printf(“%#X\n”,p);
//打印移动后指针变量p所指向的地址编号
//指针变量++(或--)移动一次是移动其基类型大小的内存区域for(int i=0;
i<10;
i++)
{
printf(“%d”,*(p+i));
//通过指针移动引用数组元素,输出数组
//指针本身位置不改变
}
for(int i=0;
i<10;
i++)
{
printf(“%d”,p[i]));
//通过指针带下标的形式引用数组元素
//[]相当于*解引用
}
for(int i=0;
i<10;
i++)
{
printf(“%d”,*(a+i));
//通过数组首地址带下标的形式引用数组元素
//这里不能使用*a++,数组的首地址是一个地址常量,其指向不能被改变
}
for(int i=0;
i<10;
i++)
{
printf(“%d”,*p++);
//指针本身的偏移(指针指向的改变)
//如果使用指针本身偏移后,再使用*(p++)就指向数组外面未知区域去了
}
【初识指针】
文章图片
4、指针指向字符串
char *p = “abcdefg”;
//通过字符指针直接引用字符串
//字符串是一个字符数组,其首地址是地址常量
while (*p)
{
printf("%c\t", *(p++));
} int* p;
char* str = "abcdefg1234567890";
p = (int*)str;
//将str强转成int*类型
for(int i=0;
i
推荐阅读
- (六)Component初识组件
- ROOM1
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- 初识html标签
- 《临水照花·尘绾颂》
- 051:指针练习(MyMax)
- 我家的石斛兰
- 吻醒清晨,点亮世界的彩虹花
- C++关于指针|C++关于指针,继承和多态介绍
- 联盟链初识以及Fabric环境搭建流程