C语言| 什么是指针?指针的简单介绍与应用(一)

目录

一、什么是指针?

二、指针变量

2.1 什么是指针变量?

2.2 指针变量的类型与大小

2.3 如何使用指针变量?

2.4利用函数实现两数交换

三、指针变量的运算

3.1 指针可以进行什么运算?

3.2 指针如何进行自加与自减运算?

封面:

C语言学习中,如果文章有错误,请海涵,并敬请在评论区指正。感谢您看到这里,希望您能点一个免费的赞,祝您生活愉快!


一、什么是指针?

指针即地址,地址即指针,我们在编译器上编写代码时,每创建一个变量,计算机就要分配一块内存空间来储存这个变量,而指针则是标记,让我们能够通过指针来访问其指向的空间的内容,并对该空间的内容进行修改。

举个例子,我们使用scanf函数给未初始化的int型变量i赋值,需要写这样一行代码:

scanf("%d",&i);

当前情况下,这个函数有两个待传入的参数,逗号分隔符左侧是整型占位符,向函数说明待接收的数据的类型,而右侧是i的地址(&i是指针常量),向函数说明接收的数据的存储位置。以此来访问i变量并给它赋值。

绝大多数人初学C语言时,会把这一行代码错误的写为:

scanf("%d", i );

为什么呢?在未接触指针的概念时,我们会认为只要知晓变量名,就可以访问该变量,但事实上是不可以的,至少在C语言是不可以的,需要知道相应的地址,我们才能访问在该地址上的变量,并对其内容进行修改。

这就是指针的概念,接下来我们介绍指针变量。

二、指针变量

2.1 什么是指针变量?

如果我们想要储存一个整数,就会创建一个整型变量,那如果我们想存储一个指针(地址)呢?就需要创建一个指针变量。

2.2 指针变量的类型与大小

我们知道数据的类型有int,short,float,double,char等,而不同的类型变量的地址就需要相应类型的指针变量来存储,如表所示:(仅列举了部分类型)

char*存储char类型变量的地址。
int*存储int类型变量的地址。
short*存储short类型变量的地址。
double*存储double类型变量的地址。
int(*)[n]存储整个数组的地址,该数组必须有n个元素。

在x86环境下,任何类型的指针变量,大小均为四个字节。

而在x64环境下,任何类型的指针变量,大小均为八个字节。 

2.3 如何使用指针变量?

代码1:

#include <stdio.h>
int main()
{
    int p=0;
    int* str=&p;
    *str=3;
    printf("%d\n",p);
    return 0;
}

我们先来看一下程序运行结果:

结果是很容易猜到的,但是初学者对于上述代码一定有一些疑惑,我们分别进行解析。

首先是这一行:int* str =&p;

它的意思是创建一个名为str的整型指针变量,并初始化str的值为&p(p的地址) 

就像我们可以把 int p=0; 分为int p; p=0;这两步,int* str=&p;也可以分为int* str; str=&p;这两步。

再来看这一行:*str=3;

' * '是操作符,它的作用是解引用。

‘ * ’与数据类型结合形成指针类型,例如int* str=&p;中‘ * ’与int结合形成整型指针类型(int *),由此定义 str 为整型指针变量,再将&p作为str的初始值。

' * '与指针变量名结合则是解引用,即访问该指针变量所储存的地址,*str=3; 就是访问p的地址内容,并将该地址上储存的内容00000000000000000000000000000000改为00000000000000000000000000000011,其效果等价于 p=3; 不如说,*str=3;就是p=3;

这样解析的话,这个代码的内容是不是就豁然开朗了呢?这就是指针变量最基本的使用方式。

2.4利用函数实现两数交换

题目:有两个变量x,y,请利用函数交换x与y的值。

初学的读者看了,肯定会说这有什么难的,马上就键步如飞地敲下了下面这个代码。

代码2:

#include<stdio.h>
void Exchange(int x,int y);
int main()
{
    int x=3;
    int y=5;
    Exchange(x,y);
    printf("x= %d\n",x);
    printf("y= %d\n",y);
    return 0;
}
void Exchange(int x,int y)
{
    int c=x;
    x=y;
    y=c;
}

我们来运行一下这个代码,其结果是:

并没有实现两数的交换,为什么呢?

我们要知道,Exchange函数内部定义的x变量与y变量,并非我们外部的x变量与y变量,我们仅仅将变量x与y的值传入给了Exchange函数,Exchange函数将值赋给了内部定义的变量x与y,并将内部定义的x与y进行了数值的交换,然后Exchange函数结束,内部定义的变量x与y被销毁。从头至尾,外部的x变量与y变量没有受到任何影响,所以结果才会出错。

那聪明的你应该想到了,我们应该使用指针来解决这个问题。

代码3:

#include<stdio.h>
void Exchange(int* str1,int* str2);
int main()
{
    int x=3;
    int y=5;
    Exchange(&x,&y);
    printf("x= %d\n",x);
    printf("y= %d\n",y);
    return 0;
}
void Exchange(int* str1,int* str2)
{
    int c=*str1;
    *str1=*str2;
    *str2=c;
}

其运行结果为:

解析:

我们将Exchange函数的两个形参改为整型指针变量,并将x与y的地址传给Exchange函数,让str1指向x的地址,str2指向y的地址,然后进行地址上的内容的交换,就实现x与y的值的交换。

当然,对于两数交换本身还有更好的方法,例如:x=x+y;y=x-y;x=x-y;或者x=x^y;y=x^y;x=x^y;

这里主要为了展示指针的用途与更好的理解,未曾用上述两种方法。

三、指针变量的运算

3.1 指针可以进行什么运算?

指针可以进行自加,自减的运算,指针与指针之间可以进行相减的运算,指针与指针进行加法、乘法、除法所得到的结果都是没有意义的。

3.2 指针如何进行自加与自减运算?

代码4:

#include <stdio.h>
int main()
{
    char i=0;
    int j=0;
    short k=0;
    char* ptr1=&i;
    int* ptr2=&j;
    short* ptr3=&k;
    printf("ptr1=%p\n",ptr1);
    printf("ptr2=%p\n",ptr2);
    printf("ptr3=%p\n",ptr3);
    ptr1++;
    ptr2++;
    ptr3++;
    printf("ptr1+1=%p\n",ptr1);
    printf("ptr2+1=%p\n",ptr2);
    printf("ptr3+1=%p\n",ptr3);
    return 0;
}

%p是占位符,用于打印地址。地址的表现形式是十六进制。 

运行结果为:

观察结果,我们发现,ptr1与ptr1+1之间差1,ptr2与ptr2+1之间差4,而ptr3与ptr3+1之间差2。这又是为什么呢? 

原来地址加一并非是加一,而是加其指针所指变量类型的大小,ptr1指向char型变量i,故加1,ptr2指向int型变量j,故加4,ptr3指向short型变量k,故加2。

为什么要这样呢?我们要知道,指针变量去解引用访问地址上的内容时,访问内容的大小取决于指向的变量的类型的大小,即从该地址开始读取该指向类型大小个字节,以保证内容完整。那指针自加也是遵循这项规则,如果不论类型,地址都是只加上1,那么指针所读取的内容就会出错。

如图:

这样是不是就理解为什么指针加一不是真的加一了吧?

指针自减运算类似,这里不多赘述。

因为要控制字数就先写到这儿吧。

封面:

C语言学习中,如果文章有错误,请海涵,并敬请您在评论区指正。感谢您看到这里,希望您能点一个免费的赞,祝您生活愉快!

  • 34
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值