C++基础概念:指针与数组,指针运算,指针与机器物理地址
关键字:指针,数组,指针与数组,指针运算,标准库函数begin和end;
指针与数组:
在C++中,指针与数组有着非常紧密的联系。
在使用数组的时候,实际上编译器会把它转化成指针。
数组还有一个特性:编译器会自动将数组名字替换为一个指向数组首元素的指针。
string StringArray[10] = {"A1", "A2", "A3","A4", "A5", "A6", "A7", "A8", "A9", "A10" } ;
string *p = StringArray;// 等价于 p = &StringArray[0]
所以在C++中,数组操作就是指针操作。
所以这几个做法是等价的:
1.
for (int i=0; i < 10 ; ++i ) {
cout << StringArray[i] << " " ;
}
2.
string *ArrayEnd = end(StringArray) ;
for (string *p = StringArray ; p < ArrayEnd; ++p ) {
cout << *p << " " ;
}
3.
string *ArrayBegin = StringArray;
for (int i=0 ; i < 10 ; ++i ) {
cout << *(ArrayBegin + i) << " " ;
}
4.
for (int i=0 ; i < 10 ; ++i ) {
cout << ArrayBegin[i] << " " ;
}
指针运算:
指针是可以进行比大小,加减一个整数,自增,自减,互相减等运算的。
注意:这些都只能在同类型的指针之间进行。
1. 两个同类型的指针变量,可以比较大小
- 地址p1< 地址 p2, p1< p2 值为真。
- 地址p1= 地址 p2, p1== p2 值为真
- 地址p1> 地址 p2 ,p1 > p2 值为真
2. 两个同类型的指针变量,可以相减
- 两个T * 类型的指针 p1 和 p2
- p1 - p2 = ( 地址 p1 - 地址 p2 ) / sizeof(T)
注意两个指针相减的结果并不是两指针所在的物理地址相减。
C++是强数据类型的,编译器会根据指针指向的变量的类型,做相应调整。
所以两个整形指针相减的结果是实际物理地址的差值然后再除以4。
3.指针变量加减一个整数的结果是指针
- p: T * 类型的指针
- n: 整数类型的变量或常量
- p+n: T * 类型的指针,指向地址: p + n × sizeof(T)
4.指针变量可以自增、自减
- T* 类型的指针 p 指向地址 n
- p++,++p : p 指向 n + sizeof (T)
- p--,--, p : p 指向 n - sizeof (T)
5. 指针可以用下标运算符 “[ ]”进行运算
- p是一个 T * 类型的指针,
- n是整数类型的变量或常量
- p[n] 等价于 *(p+n)
指针与机器物理地址:
指针可以理解为一种数据类型,是与它所指向的变量的类型强相关的;
所以指针变量并不完全等于它的机器物理地址的值。
所以指针的+,-, ++, --与其机器地址的+,-, ++, --是不一样的。
string * 类型的指针 ArrayBegin进行加1操作后,实际的物理地址增加了32, 也就是string的字节数。
ArrayBegin: 0x7ffc061df210
ArrayBegin +1 : 0x7ffc061df230
如果要得到指针的实际物理地址,
在C++中可以采用强制类型转化,
把指针转化成long long类型的整数地址;
long long intAttrayBegin_address = (long long) intArrayBegin ;
示例代码中的其他细节:
在cout中可以用hex直接把指针用16进制数输出,对应的就是其编译后的实际物理地址。
把指针强制转化为整数要用long long类型;如果用int,可能会有溢出,导致编译错误。
可以用标准库函数begin和end,取数组的首元素的地址,和最后一个元素的地址的后面一个地址。
其他细节请直接查看源代码。
程序源代码:
#include <iostream>
#include <string>
#include <iterator>
using namespace std;
int main ()
{
string StringArray[10] = {"A1", "A2", "A3","A4", "A5", "A6", "A7", "A8", "A9", "A10" } ;
string *ArrayEnd = end(StringArray) ;
for (int i=0; i < 10 ; ++i ) {
cout << StringArray[i] << " " ;
}
cout << endl;
for (string *p = StringArray ; p != ArrayEnd; ++p ) {
cout << *p << " " ;
}
cout << endl;
for (string *p = StringArray ; p < ArrayEnd; ++p ) {
cout << *p << " " ;
}
cout << endl;
string *ArrayBegin = StringArray;
for (int i=0 ; i < 10 ; ++i ) {
cout << *(ArrayBegin + i) << " " ;
}
cout << endl;
for (int i=0 ; i < 10 ; ++i ) {
cout << ArrayBegin[i] << " " ;
}
cout << endl;
cout << "size of string is:" << sizeof(string) << endl ;
cout << "ArrayBegin:"<< "\t" << hex << ArrayBegin << endl ;
cout << "ArrayBegin +1 :"<< "\t" << hex << (ArrayBegin +1 ) << endl ;
int intArray[] = {11, 12} ;
int *intArrayBegin = intArray;
cout << "size of int is:" << sizeof(int) << endl ;
cout << "intArrayBegin:"<< "\t\t" << hex << intArrayBegin << endl ;
cout << "intArrayBegin +1 :"<< "\t" << hex << (intArrayBegin +1 ) << endl ;
int *intArrayEnd = end(intArray);
cout << "intArrayEnd - intArrayBegin =" << (intArrayEnd - intArrayBegin) << endl ;
long long intAttrayBegin_address = (long long) intArrayBegin ;
cout << "intAttrayBegin_address = " << hex << intAttrayBegin_address << endl ;
long long intAttrayEnd_address = (long long) intArrayEnd ;
cout << "intAttrayEnd_address - intAttrayBegin_address = " << intAttrayEnd_address - intAttrayBegin_address << endl ;
return 0 ;
}
输出结果:
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
A1 A2 A3 A4 A5 A6 A7 A8 A9 A10
size of string is:32
ArrayBegin: 0x7ffc061df210
ArrayBegin +1 : 0x7ffc061df230
size of int is:4
intArrayBegin: 0x7ffc061df208
intArrayBegin +1 : 0x7ffc061df20c
intArrayEnd - intArrayBegin = 2
intAttrayBegin_address = 7ffc061df208
intAttrayEnd_address - intAttrayBegin_address = 8
相关文章
- Linux服务器硬件信息查询与日常运维命令总结
- Linux服务器带宽跑不满?用ethtool调优网卡参数,性能提升30%
- 如何在 Rocky Linux 中查看网卡流量?跟着小编学习iftop安装和使用
- Linux查看网卡速率_linux查看网卡当前速率
- 五一我要看七天小说!免费开源的轻量化书库talebook搭建流程。
- 我是如何用这3个小工具,助力小姐姐提升100%开发效率的
- html5和css3的常用参考网_基于html5和css3的网页制作
- 超详细的网络抓包神器 tcpdump 使用指南
- Vue 技术栈(全家桶)_vue全栈项目教程
- 学习ES6- 入门Vue(大量源代码及笔记,带你起飞)