C++基础 杂记(一)
时间:2022-07-22
本文章向大家介绍C++基础 杂记(一),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
记录以下几点:
- const修饰符
- static修饰符
- C++指针和引用的区别
- 堆和栈的区别
const修饰符
-
const int m=7;
:整型变量m的值为固定值7,不可改变 -
const int* p1 = &a;
:- p1指向的**值**不可改变(简称 左定值,因为 const 位于 * 号左边)
-
不合法,*p1=b
p2=&b
合法
-
int* const p2 = &a;
:- p2的**指向**不可改变(简称**右定向**,const 位于 * 号右边)
-
*p2=b
合法,~~p2=&b
~~不合法
int a = 7;
int b = 8;//===左定值,值(*p1)不可变 (常量const指针*)
const int* p1 = &a;
p1 = &b;//ok
//*p1 = b; // error!//===右定向,指向(p2)不可变 (指针*常量const)
int* const p2 = &a;
//p2 = &b; // error!
*p2 = b;//okconst int* const p3 = &a;//指向常量的指针常量
static修饰符
修饰变量、函数
函数内部定义的变量,当程序执行到它的定义处时,编译器为它在栈上分配空间,在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义为全局的变量,但会破坏此变量的访问范围(使得在此函数中定义的变量,不仅仅只受此函数控制)。static 关键字则可以很好的解决这个问题。
- static 修饰的局部变量只初始化一次,且延长了局部变量的生命周期(作用域不变),程序结束后才释放
- static 修饰的全局变量只能在本文件中访问,不能在其它文件中访问,即便 extern 外部声明也不可以,因而其它文件中可以定义相同名字的变量,不会发生冲突
- static 修饰的函数只能在本文件中调用,不能被其他文件调用
- static 修饰的变量存放在**全局数据区的静态变量区**,包括全局静态变量和局部静态变量,初始化自动为 0
修饰类内成员
静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。
- 静态成员**可以**通过双冒号来使用
<类名>::<静态成员名>
,非静态成员引用**必须**与特定对象相对对象.成员名
- 类的静态成员函数中**不能**使用类的非静态成员(因为**静态成员函数属于整个类,在类实例化对象之前就已经分配空间了**,而非静态成员在类实例化对象后才有内存空间,因而静态成员不认识后来的非静态成员)
- 类的非静态成员函数可以调用用静态成员函数,但反之不能
- 静态成员函数没有 this 指针(因其属于整个类)
- 类的静态成员变量必须先初始化再使用
#include <iostream>using namespace std;class Point{public:
Point() { m_x++; }
~Point() { m_x--; }
void init()
{
output();//非静态函数可以调用用静态函数,但反之不能
}
static void output()
{
cout << m_x << endl;//static类型的m_x
}private:
static int m_x;};static int x;//类外静态变量可以不初始化直接用int Point::m_x = 0;//类的静态成员变量必须先初始化再使用void main(){
x++;
Point pt;
pt.init();//非静态成员只能使用pt.output()
Point::output();//静态成员也可以使用pt.output()}
参考:https://blog.csdn.net/morewindows/article/details/6721430
C++指针和引用的区别
- 指针是一个变量,该变量存储的是一个地址,指向内存的一个存储单元 引用与原来的变量实质上是同一个东西,只不过是原变量的一个别名而已
- 指针可以为空 引用不能为空
- 指针在初始化后,可以改变进而指向其它的变量对象 引用只能在定义时被初始化一次,之后不可变,始终是初始化时对应的变量
- 可以有const指针(可以有
int* const p
,指向int型的常量指针 ,它不能在指向别的变量) 没有const引用(没有int& const a
这种形式,引用本身即别名不可以改变,这是当然的) - 指针可以有多级(
int **p
合法) 是引用只能是一级(int &&a
是不合法的) - “
sizeof (指针
)”得到的是指针本身的大小 “sizeof (引用)
”得到的是所指向的变量(对象)的大小
堆和栈的区别
- 堆空间的释放由程序员控制,容易产生memory leak 栈空间由编译器自动管理
- 堆的空间较大,由系统内存决定 栈的空间有限,最大容量是系统预先规定的(1M或2M)
- 堆频繁的new/delete造成内存空间的不连续,产成大量碎片,使程序效率降低 栈是先进后出的结构,栈始终连续存储
- 堆是向高地址扩展,也就是向着内存地址增加的方向 栈是向低地址扩展,是向着内存地址减小的方向增长
- 堆都是动态分配的,没有静态分配的堆 栈有静态分配(由编译器完成,比如局部变量)和动态分配(由alloca函数进行分配)
- 堆由C/C++函数库提供,机制较复杂 栈由计算机底层提供支持
进程和线程的区别
- 进程是资源分配的最小单位 线程是CPU调度的最小单位
- 进程有自己独立的地址空间,每启动一个进程,系统都会为其分配地址空间,建立数据表来维护代码段、堆栈段和数据段 线程没有独立的地址空间,它使用相同的地址空间共享数据
- 进程之间的通信需要以通信的方式(IPC,Inter-Process Communication)进行 线程之间通信更方便,同一个进程下,线程共享全局变量,静态变量等数据
- 多进程程序更安全,生命力更强,一个进程死掉不会对另一个进程造成影响(源于有独立的地址空间) 多线程程序更不易维护,一个线程死掉,整个进程就死掉了(因为共享地址空间)
- 进程对资源保护要求高,开销大,效率相对较低 线程资源保护要求不高,但开销小,效率高,可频繁切换
- CPU切换一个线程比切换进程花费小
- 创建一个线程比进程开销小
- 线程占用的资源要⽐进程少很多
参考:https://blog.csdn.net/wsq119/article/details/82154305
字节序:大端法和小端法
最高有效字节在最前面的方式称为大端法(先存储高位),例如假设变量x类型为int型,位于地址0x100的地方,其16进制值为0x12345678
,地址范围为0x100到0x103字节。
对于大端法的机器来说(先存储高位0x12
):
0x100 |
0x101 |
0x102 |
0x103 |
---|---|---|---|
12 |
34 |
56 |
78 |
对于小端法的机器来说(先存储高位0x78
):
0x100 |
0x101 |
0x102 |
0x103 |
---|---|---|---|
78 |
56 |
34 |
12 |
参考:https://www.cnblogs.com/broglie/p/5645200.html
- tomcat请求处理分析(三) 绑定本地端口监听请求
- 利用FFmpeg对火眼一体摄像机的回调数据进行处理:YUV转H264,H264封装flv,所有输入都是在内存中。
- MySQL 传统复制中常见故障处理和结构优化案例分析
- sql带条件查找最小缺失编号
- activiti学习笔记(六) 监听器
- activiti学习笔记(五) 流程部署
- 打开文件open()函数的使用方法详解
- activiti学习笔记(四) 配置器
- WaitForMultipleObjects用法详解,一看就懂
- activiti学习笔记(三) 监听生命周期
- Assignment 2 | 斯坦福CS231n-深度学习与计算机视觉课程
- 五个值得深思的PHP面试题
- 5个值得深思的 PHP 面试问题
- activiti学习笔记(二) 获取流程实例
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python-技术篇-打印详细报错日志,获取报错信息位置行数
- React从入门到放弃,一个关于网页速度的故事
- python 技术篇-日志定期清理设置,自动清理上个月的日志实例演示
- python 技术篇-日志模块自定义时间格式
- 恕我直言你可能真的不会java第12篇-如何使用Stream API对Map元素排序
- JavaScript错误处理完全指南
- 从头创建您自己的vue.js——第4部分(构建反应性)
- Oracle 数据库-服务器端字符集查看方法
- Pywinauto 应用后端类型选择错误:AttributeError: 'NoneType' object has no attribute 'backend'. 原因及解决办法
- 恕我直言你可能真的不会java第11篇-Stream API终端操作
- Python+selenium 自动化-滚动的使用方法,如何滚动到元素的位置
- 恕我直言你可能真的不会java第10篇-集合元素归约
- Python+selenium 自动化-模拟键盘输入、点击操作,如何查看所支持的全部键位名称
- Uber为什么放弃Postgres选择迁移到MySQL?
- BAT 批处理命令 - 文件批量复制、克隆功能实例演示