C++笔记(6) 指针
2023-02-18 16:27:15 时间
1.指针和数组
指针和数组基本等价的原因在于指针算数和C++内部处理数组的方式。在很多情况下,可以用相同的方式使用数组名和指针名。
- 在多数情况下,C++将数组名视为数组的第一个元素的地址。指针p的值为数组第一个元素的地址,*p数组第一个元素的值。
- 将指针变量+1后,增加的量等于它指向的类型的字节数。比如,将指向double类型的指针加1后,指针值+8;将指向short类型的指针加1后,指针值+2。
两者之间的区别:
- 可以修改指针的值(p=p+1 (OK)),而数组名是常量(arrayname = arrayname+1 (ERROR))。
- 对数组应用sizeof运算符得到数组的长度,而对指针应用sizeof得到指针的长度。无论指针指向的数据类型是什么,sizeof(指针)=4。
#include <iostream> using namespace std; int main() { short stacks[3] = { 3,2,1 }; cout << "stacks:" << stacks << endl; cout << "&stacks[0]:" << &stacks[0] << endl; short* p = stacks; cout << "p:" << p << endl; cout << "*p:" << *p << endl; cout << "(p+1):" << (p + 1) << endl; cout << "*(p+1):" << *(p + 1) << endl; cout << "sizeof(p):" << sizeof(p) << endl; return 0; }
运行结果
2. 指针和字符串
1)如果给cout提供一个字符的地址,它将从该字符开始打印,直到遇到空字符为止。
下面为不同形式的字符串:
- 数组中的字符串
- 用引号括起来的字符串常量
- 指针所描述的字符串
char animal[10] = "bear";
const char* bird = "wren";
请看下面的代码:
char flower[10] = "rose"; cout << flower << endl; char animal[4] = { 'f','i','s','h' }; cout << animal << endl;
运行结果:
在cout和大多数C++表达式中char数组名、char指针以及用引号括起的字符串常量都被解释为字符串第一个字符的地址。数组名flower是字符r的地址,数组名animal是字符f的地址。
2)一般来说,给cout提供一个指针,它将打印地址。但如果指针的类型为char *,则cout将显示指向的字符串。如果想要显示字符串的地址,则必须将这种指针强制转化为另一种指针类型,如int*。如下所示:
const char* bird = "wren"; cout << "bird:" << bird << endl; cout << "(int*)bird:" << (int*)bird << endl;
运行结果:
3)在将字符串读入程序时,应使用已分配的内存地址。该地址可以是数组名,也可以是使用new初始化后的指针。
#include <iostream> using namespace std; int main() { char flower[10]; cin >> flower; cout << "flower:" << flower << ",(int*)flower:" << (int*)flower << endl; cout << "sizeof(flower):" << sizeof(flower) << ",strlen(flower):" << strlen(flower) << endl; char* p=new char[strlen(flower)+1]; strcpy_s(p, strlen(flower) + 1, flower); cout << "p:" << p << ",(int*)p:" << (int*)p << endl; delete [] p; return 0; }
运行结果:
3.指针和对象
使用对象指针时,需要注意以下几点:
-
使用常规表示法来声明指向对象的指针
String * s;
-
可以将指针初始化为指向已有的对象
String * s = &sayings[0];
-
可以使用new来初始化指针,这将创建一个新的对象
String * s = new String();
-
对类使用new将调用相应的类构造函数来初始化新创建的对象
String * s1 = new String();//调用了默认构造函数 String *s2 = new String("my my my");//调用了 String(const char *)构造函数 String *s3 = new String(sayings[0]);//调用了拷贝构造函数 String(const String &)
-
可以使用->运算符通过指针访问类方法
if(sayings[i].length() < s->length())
-
可以对对象指针应用解除引用运算符(*)来获得对象
if(sayings[i] < *s) s = &sayings[i];
相关文章
- Redis被问到哭?看完这篇,她站起来了……
- Redis-技术专区-帮从底层彻底吃透RDB技术原理
- Mybatis-技术专区-如何清晰的解决出现「多对一模型」和「一对多模型」的问题
- 🏆【JVM技术专区】「难点-核心-遗漏」TLAB内存分配+锁的碰撞(技术串烧)!
- 🏆【Alibaba微服务技术系列】「Dubbo3.0技术专题」回顾Dubbo2.x的技术原理和功能实现及源码分析(温故而知新)
- 【微服务技术专题】Netflix动态化配置服务-微服务配置组件变色龙Archaius
- 🏆【JVM技术专区】「虚拟机专题」JDK/JVM的新储君—GraalVM和Quarkus
- Alibaba-技术专区-RocketMQ 延迟消息实现原理和源码分析
- 【SpringBoot技术专题】「JWT技术专区」SpringSecurity整合JWT授权和认证实现
- Alibaba-技术专区-Dubbo3总体技术体系介绍及技术指南(目录)
- Alibaba-技术专区-Dubbo3总体技术体系介绍及技术指南(序章)
- SpringBoot-技术专区-用正确的姿势如何用外置tomcat配置及运行(Tomcat优化分析)
- 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(下)
- 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(中)
- 【SpringCloud技术专题】「原生态Fegin」打开Fegin之RPC技术的开端,你会使用原生态的Fegin吗?(上)
- 🏆(不要错过!)【CI/CD技术专题】「Jenkins实战系列」(4)jenkins+pipeline构建自动化部署
- 🏆(不要错过!)【CI/CD技术专题】「Jenkins实战系列」(3)Jenkinsfile+DockerFile实现自动部署
- 【Maven实战技巧】「插件使用专题」Maven-Assembly插件实现自定义打包
- [书单]
- MySQL-技术专题-innodb存储引擎