| |
|
开发:
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、内存、地址
要讲指针,首先要搞清楚内存。内存只不过是一个存放数据的空间,就好像我的看电影时的电影院中的座位一样。每个座位都要编号,我们的内存要存放各种各样的数据,当然我们要知道我们的这些数据存放在什么位置吧!所以内存也要象座位一样进行编号了,这就是我们所说的内存编址。座位可以是按一个座位一个号码的从一号开始编号,内存则是按一个字节一个字节进行编址,如下图所示。每个字节都有个编号,我们称之为内存地址。
int i;
char a;
这句代码的含义就是向内存申请了一个整型变量宽度的空间(一般是两个字节)并命名为i,同时申请了一个名为a的字符型变量宽度的空间(一个字节)并命名为a。效果如下图所示:
i=10;
a='dk';
这句代码的含义就是将10存入名为i的内存空间,将dk存入名为a的内存空间,效果图如下:
首先我们要知道怎么去表达一个变量的地址,这就需要知道&i的含义了,我们可以这样读它:返回变量i的地址编号。对于上述定义&i的值就为6(实际编程中不会是这个数,因为地址不会就是6)。
2、指针
指针就是地址;指针变量是存地址的变量
申明一个整型的指针变量如下:
int *p;
其中p就是一个指针变量,实质上它和前面的整型变量和字符型变量没有区别,就是一个变量。上句代码的意思就是向内存申请一个整型指针变量宽度的空间(假设两个字节)并命名为p,效果如下:
p=&i;
这句代码的含义就是将变量i的地址编号存入名为p的内存空间。如下图,变量i的地址编号为6,
到此为止就可以搞清楚指针的基本含义和操作,那接下来我们就要探讨指针的用处。
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语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年11日历 | -2024/11/24 0:53:11- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |