IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言中指针的解读 -> 正文阅读

[C++知识库]C语言中指针的解读

1、内存、地址

要讲指针,首先要搞清楚内存。内存只不过是一个存放数据的空间,就好像我的看电影时的电影院中的座位一样。每个座位都要编号,我们的内存要存放各种各样的数据,当然我们要知道我们的这些数据存放在什么位置吧!所以内存也要象座位一样进行编号了,这就是我们所说的内存编址。座位可以是按一个座位一个号码的从一号开始编号,内存则是按一个字节一个字节进行编址,如下图所示。每个字节都有个编号,我们称之为内存地址。

C语言中指针的解读


那么对于下面变量申明:
int i;
char a;
这句代码的含义就是向内存申请了一个整型变量宽度的空间(一般是两个字节)并命名为i,同时申请了一个名为a的字符型变量宽度的空间(一个字节)并命名为a。效果如下图所示:

C语言中指针的解读


变量申明之后就是对其赋值:
i=10;
a='dk';
这句代码的含义就是将10存入名为i的内存空间,将dk存入名为a的内存空间,效果图如下:

C语言中指针的解读


通过上面的讲解可以弄清楚变量、内存、地址的概念,下面就来进行指针的探讨。
首先我们要知道怎么去表达一个变量的地址,这就需要知道&i的含义了,我们可以这样读它:返回变量i的地址编号。对于上述定义&i的值就为6(实际编程中不会是这个数,因为地址不会就是6)。
2、指针
指针就是地址;指针变量是存地址的变量
申明一个整型的指针变量如下:
int *p;
其中p就是一个指针变量,实质上它和前面的整型变量和字符型变量没有区别,就是一个变量。上句代码的意思就是向内存申请一个整型指针变量宽度的空间(假设两个字节)并命名为p,效果如下:

C语言中指针的解读


和前面变量的区别是p所对应的空间存储的是变量的地址编号,赋值如下:
p=&i;
这句代码的含义就是将变量i的地址编号存入名为p的内存空间。如下图,变量i的地址编号为6,

C语言中指针的解读


指针变量定义好以后就是使用的问题了,我们就需要搞清楚*p的含义了,我们可以这样读它:p内容所指的地址的内容。此处的*p的值就是地址6所存的内容也就是10。
到此为止就可以搞清楚指针的基本含义和操作,那接下来我们就要探讨指针的用处。
3、指针的使用
(1)访问数组元素
????????用指针来访问数组元素的时候首先要弄清楚数组名的含义:数组名代表数组的首地址,可以采用如下方法来访问数组元素:
int i,a[]={3,4,5,6,7,3,7,4,4,6};
for (i=0;i<=9;i++)
{
printf ( “%d”,  *(a+i) );
}
或者:
int i,*pa,a[]={3,4,5,6,7,3,7,4,4,6};
pa =a  ;//请注意数组名a直接赋值给指针 pa
for (i=0;i<=9;i++)
{
printf ( “%d”, pa[i] );
}?
但是数组名a和pa还是不同的,数组名是一个指针常量,其值不能被更改,pa是一个指针变量其值是可以更改的,下面用一个例子来说明这个问题:
int i,a[]={3,4,5,6,7,3,7,4,4,6};
pa =a;
for (i=0;i<=9;i++)
{
printf ( “%d”, *a );
a++ ;  //注意这里,指针值被修改
}?
上面这段代码运行会出错,因为a是一个指针常量其值不能改变,所以用上面这种方式来访问数组元素是错误的。但是可以采用下面的方式访问:
int i,*pa,a[]={3,4,5,6,7,3,7,4,4,6};
pa =a;
for (i=0;i<=9;i++)
{
printf ( “%d”, *pa );
pa++ ;  //注意这里,指针值被修改
}?
从这两段代码就可以弄清楚指针变量和指针常量的区别。
(2)int const *p和int * const p的区别
const修饰的i不再是一个符号变量,而是一个符号常量,其不能被重新赋值。弄清楚const的含义后就可以来探讨两者的区别了,从语义可以看出int const *p中修饰的是*p,int * const p中修饰的是p即前者*p的值不能修改,后者p的值不能修改。
(3)函数参数的指针传递
在这里首先要搞清楚形参和实参的区别:形参是出现在函数定义中的参数(下文程序中的x,y);实参是出现在函数调用中的参数(下文程序中的a,b)。
下面通过对两个个程序的解读来分析函数参数指针的作用:
题一:程序代码如下:
void Exchg1(int x, int y)
{
int tmp;
tmp=x;
x=y;
y=tmp;
printf (“x=%d,y=%d\n”,x,y)
}
void main()
{
int a=4,b=6;
Exchg1 (a,b) ;
printf(“a=%d,b=%d\n”,a,b)
}
现在来逐条分析程序,从主程序依次执行,首先是对a、b两个变量赋值,然后调用子函数Exchg1,将a、b作为变量代入子函数里面进行执行,这个过程隐含了两条语句:x=a;y=b;(调用函数时是隐含着执行了这两条语句的),然后在子函数里面执行,将x的值和y的值进行交换,而a、b的值是没有发生变化的,所以最后运行的结果是a=4,b=6;x=6,y=4。
题二 代码如下:
Exchg2(int *px, int *py)
{
int tmp=*px;
*px=*py;
*py=tmp;
print(“*px=%d,*py=%d\n”,*px,*py);
}
main()
{
int a=4;
int b=6;
Exchg2( &a,&b);
Print (“a=%d,b=%d\n”, a, b);
}
同样地从主函数中逐条分析,首先是对a,b进行赋值,然后调用子函数Exchg2,这个函数定义的形参是指针变量,因此调用时的实参是a,b的地址。同样地,隐含着两条代码:px=&a;py=&b;然后在子程序中交换的是指针px所对应的内容和指针py所对应的内容,即a和b的值,最后的运行结果为:a=6,b=4;*px=6,*py=4.
(4)**p的含义
**p这是一个指向指针的指针
下面通过一个例子来说明其作用:
设计一个函数:void find1(char array[], char search, char * pi)
要求:这个函数参数中的数组array是以0值为结束的字符串,要求在字符串array中查找字符是参数search里的字符。如果找到,函数通过第三个参数(pa)返回值为array字符串中第一个找到的字符的地址。如果没找到,则为pa为0.
void find1(char array[], char search, char * pa)
{
int i;
for (i=0;*(array+i)!=0;i++)
{
if (*(array+i)==search)
{
pa=array+i
break;
}
else if (*(array+i)==0)
{
pa=0;
break;
}
}
}
测试主程序:
void main()
{
char str[]={“afsdfsdfdf\0”};  //待 查找的字符串
char a=’d’;   //设置要查找的字符
char * p=0;  //如果 查找到后指针p将指向字符串中查找到的第一个字符的地址。
find1(str,a,p);  //调用函数以实 现所要操作。
if (0==p )
{
printf (“没找到!\n”);//1.如果没找到则 输出此句
}
else
{
printf(“找到了,p=%d”,p);  //如果找到则 输出此句
}
测试的结果是没找到,说明子函数有问题,下面进行逐条分析:
函数调用会隐含三条代码:
array[]=str;search=a;pa=p;
从子函数的执行过程可以看出,找到字符后改变的是形参pa的值,实参p的值没有发生改变。
为了得到上述功能,将程序修改如下:
void find2(char array[], char search, char ** ppa)
{
int i;
for (i=0;*(array+i)!=0;i++)
{
if (*(array+i)==search)
{
*ppa=array+i
break;
}
else if (*(array+i)==0)
{
*ppa=0;
break;
}
}
}
主程序调用部分修改如下:
find2(str,a, &p);
同样的隐含地执行了三条代码:
array[]=str;search=a;*ppa=&p;
从中可以看出指针ppa指向的是变量p的地址,在子程序执行过程中改变的ppa所指向的内容即p的地址,那p的值也随之发生改变了。
上面这个例子弄明白后就可以弄清楚指针的含义了。
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-02 14:26:18  更:2021-10-02 14:26:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 22:19:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码