代码编织梦想


1. 数组

数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素。数组元素用数组名与带方括号的下标表示,同一数组的各元素具有相同的数据类型。

1.1 数组的声明与使用

  • 数组声明

      // 数组类型声明一般形式
      数据类型 标识符[常量表达式1][常量表达式2]...;
    

    声明一个数组类型,应包含:

    • 确定数组的名称
    • 确定数组元素的类型
    • 确定数组的结构(包括数组维数,每一维的大小等)
  • 数组的使用

      // 数组使用一般形式
      数组名[下标表达式1][下标表达式2]...;
    
    • 数组元素的下标表达式可以是任意合法的算术表达式,其结果必为整数
    • 数组元素的下标值不得超过声明时所确定的上下界,否则运行时将出现数组越界错误
    // 数组声明与使用
    #include<iostream>
    using namespace std;
    
    int main() {
    	int a[10], b[10];               //定义两个有10个元素的一维数组a,b
    	for (int i = 0; i < 10; i++) {  //使用for循环对两个数组进行赋值
    		a[i] = i * 2 - 1;
    		b[10 - i - 1] = a[i];
    	}
    	for (int i = 0; i < 10; i++) {  //使用for循环输出结果
    		cout << "a[" << i << "]=" << a[i] << "   ";
    		cout << "b[" << i << "]=" << b[i] << endl;
    	}
    	return 0;
    }
    

1.2 数组的存储与初始化

  • 数组的存储
    数组元素在内存中是顺序、连续存储的。数组元素在内存中占据一组连续的存储单元,逻辑上相邻的元素在物理地址上也是相邻的。一维数组是简单的按照下标的顺序,连续存储的。二维数组在内存中是按行存放的,即先放第1行,再放第2行…每行中的元素是按列下标由小到大的次序存放
  • 数组的初始化
    数组的初始化就是在声明数组时给部分或全部元素赋初值。对于基本类型的数组,初始化过程就是给数组元素赋值,对于对象数组,每个元素都是某个类的一个对象,初始化就是调用该对象的默认构造函数
    定义数组时:
    • 如果列出全部元素的初值,可以不用说明元素个数
    • 当指定的初值个数小于数组大小时,剩下的数组元素会被赋予0值
    • 如果没有指定任何一个元素的初值
      • 对于静态生存期的数组,每个元素仍然会被赋予0值
      • 对于动态生存期的数组,每个元素的初值都是不确定的
    • 声明为常量的数组,必须给定初值
    // 数组的初始化
    // 列出全部元素的初值
    int a[3] = {1, 1, 1};
    // 列出全部元素的初值,可以不用说明元素个数
    int a[] = {1, 1, 1};
    // 指定的初值个数小于数组大小时,剩下的数组元素会被赋予0值
    float fa[5] = {1.0, 2.0, 3.0};
    // 声明为常量的数组
    const float fa[5] = {1.0, 2.0, 3.0};
    

1.3 数组作为函数参数

用数组元素作为调用函数的参数,则实参和形参都应该是数组名,且类型要相同。和普通变量作参数不同,使用数组名传递数据时,传递的是地址,也就是说如果在被调函数中对形参数组元素值进行改变,主调函数中实参数组的相应元素值也会改变。

1.4 对象数组

  • 对象数组声明语法格式:

      类名 数组名[常量表达式];
    
  • 访问对象数组元素语法格式:

      数组名[下标表达式].成员名;
    

对象数组的初始化过程,实际上就是调用构造函数对每一个元素对象进行初始化的过程。当一个数组中的元素对象被删除时,系统会调用析构函数来完成扫尾工作。


2. 指针

2.1 内存空间的访问方式

在C++程序中如何利用内存单元存取数据?
一是通过变量名,而是通过地址。具有静态生存期的变量在程序开始运行之前就被分配了内存空间。具有动态生存期的变量,是在程序运行时遇到变量声明语句时被分配内存空间的。

2.2 指针变量的声明

指针也是一种数据类型,具有指针类型的变量称为指针变量。指针变量是用于存放内存单元地址的。通过变量名访问一个变量是直接的,而通过指针访问一个变量是间接的。声明指针的语法格式为:

数据类型 *标识符;

这里 * 表示声明的是一个指针类型的变量

int * ptr;  // 定义了一个指向int型数据的指针变量

2.3 与地址相关的运算 “*” 和 “&”

  • “*” 称为指针运算符,表示获取指针所指向的变量的值
  • “&” 称为取地址运算符,用来得到一个对象的地址
// * 出现在声明语句中,在被声明的变量名之前,表示声明的是指针
int * p;           //声明p是一个int型指针
// * 出现在执行语句中或声明语句的初始化表达式中,表示访问指针所指向对象的内容
cout << *p;        // 输出指针p所指向的内容
// & 出现在变量声明语句中位于被声明的变量左边时,表示声明的是引用
int &rf;           // 声明一个int型的引用rf
// & 在给变量赋初值时出现在等号右边或在执行语句中作为一元运算符出现时,表示取对象的地址
int a, b;
int * pa, *pb = &b;
pa = &a;

2.4 指针的赋值

指针赋值有两种方法:

  • 在定义指针的同时进行初始化赋值。语法形式为:

      存储类型 数据类型 * 指针名 = 初始地址;
    
  • 在定义之后,单独使用赋值语句。语法格式为:

      指针名 = 地址;
    

一个数组,可以用它的名称来直接表示它的起始地址。数组名称实际上就是一个不能被赋值的指针,即指针常量

int a[10];      //定义int型数组
int *ptr = a;   //定义并初始化int型指针

关于指针的类型,还应该注意:

  • 可以声明指向常量的指针,此时不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。
    int a;
    const int *p1 = &a;  //p1是指向常量的指针
    int b;
    p1 = &b;   //正确,p1本身的值可以改变
    *p1 = 1;   //错误,不能通过p1改变所指的对象
    
  • 可以声明指针类型的常量,这是指针本身的值不能被改变。
    int * const p2 = &a;  //声明p2是指针常量
    p2 = &b;              //错误,p2是指针常量,值不能改变
    
  • 一般情况下,指针的值只能赋给相同类型的指针。但是任何类型的指针都可以赋值给void类型指针。(void指针一般只在指针所指向的数据类型不确定时使用)。

2.5 指针运算

  • 指针是一种数据类型。与其他数据类型一样,指针变量也可以参与部分运算,包括算术运算、关系运算和逻辑运算。指针可以和整数进行加减运算,比如有指针p1和整数n1,则p1+n1表示指针p1当前所指位置后方第n1个数的地址,p1-n1表示指针p1当前所指位置前方第n1个数的地址。“指针++”或“指针- -”表示指针当前所指下一个或前一个数据的地址
  • *(p1+n1)表示p1当前所指后方第n1个数的内容,也可以写作p1[n1]
  • 一般来讲,指针的算术运算是和数组的使用相联系的,因为只有在使用数组时,才会得到连续分布的可操作内存空间
  • 0专用于表示空指针,也就是一个不指向任何有效地址的指针

2.6 用指针处理数组元素

int array[5];

声明了一个存放5个int类型数的一维数组,数组名array就是数组的首地址(第一个元素的地址),即array和&array[0]相同。数组中5个整数顺序存放,因此,通过数组名这个地址常量和简单的算术运算就可以访问数组元素。数组中下标为 i 的元素就是*(数组名+ i ),例如,*array就是array[0],*(array+3)就是array[3]

2.7 指针数组

如果一个数组的每个元素都是指针变量,这个数组就是指针数组。声明一维指针数组的语法形式为:

数据类型 * 数组名[下标表达式];
int *pa[3];

声明了一个int类型的指针数组pa,其中有3个元素,每个元素都是一个指向int型数据的指针。

2.8 用指针作为函数参数

子函数运行过程中,通过形参指针对数据值的改变也同样影响着实参指针所指向的数据值。C语言中,以指针作为函数的形参有三个作用:

  • 使实参与形参指针指向共同的内存空间,以达到参数双向传递的目的。C++中通过引用实现该功能。
  • 减少函数调用时数据传递的开销。C++中有时通过引用实现,有时使用指针
  • 指向函数的指针传递函数代码的首地址

2.9 指针型函数

当一个函数的返回值是指针类型时,这个函数就是指针型函数。使用指针型函数的最主要的目的就是要在函数结束时把大量的数据从被调函数返回到主调函数中。指针型函数的一般定义形式为:

数据类型 * 函数名(参数表){
	函数体
}

数据类型表明函数返回指针的类型;函数名和 “*” 标识了一个指针型的函数;参数表中是函数的形参列表。

2.10 指向函数的指针

函数指针就是专门用来存放函数代码首地址的变量。声明函数指针的一般语法为:

数据类型 (*函数指针名)(形参表)

数据类型说明函数指针所指函数的返回值类型;*函数指针名指明一个函数指针的名称;形参表列出来该指针所指函数的形参类型和个数。
由于对函数指针的定义在形式上比较复杂,所以一般使用typedef,例如:

typedef int(*Functions)(double);

声明了Functions “有一个double形参,返回类型为int的函数指针”类型的别名。所以需要声明这一类型的变量时,可以直接使用:

Functions funcPtr;

声明了一个具有该类型的名称为funcPtr的函数指针。
函数指针在使用之前要进行赋值,是指针指向一个已经存在的函数代码的起始地址,一般语法为:

函数指针名 = 函数名;

通过指针访问类的静态数据成员示例:

#include<iostream>
using namespace std;

//Point类定义
class Point {
public:
	Point(int x = 0, int y = 0) :x(x), y(y) {	//Point类构造函数
		count++;
	}
	Point(const Point &p) :x(p.x), y(p.y) {		//Point类复制构造函数
		count++;
	}
	~Point() {									//析构函数
		count--;
	}
	int getX() const{							//获取x的成员函数
		return x;
	}
	int getY() const {							//获取y的成员函数
		return y;
	}
	static int count;							//静态成员
	
private:
	int x, y;
};

int Point::count = 0;

int main() {
	//通过指针访问类的静态数据成员
	int* ptr = &Point::count;									//定义指向Point类静态成员count的指针ptr
	Point a(4, 5);												//定义Point对象a
	cout << "Point A: " << a.getX() << "," << a.getY() << " ";	//获取A点的坐标
	cout << "Object count=" << *ptr << endl;					//计算对象个数

	Point b(a);													//定义Point对象b
	cout << "Point B: " << b.getX() << "," << b.getY() << " ";	//获取B点的坐标
	cout << "Object count=" << *ptr << endl;					//计算对象个数
	return 0;
}

运行结果为:
在这里插入图片描述

2.11 对象指针

对象指针就是用于存放对象地址的变量。声明对象指针的一般语法为:

类名 *对象指针名;

使用对象指针访问对象成员的语法形式为:

对象指针名->成员名;

(*对象指针名).成员名

3. 动态分配内存

建立和删除堆对象使用两个运算符:new 和 delete

  • 运算符 new 的功能是动态分配内存,或者称为动态创建堆对象。如果内存申请成功,new 运算符便返回一个指向新分配内存首地址的类型的指针,可以通过这个指针对堆对象进行访问;如果申请失败,会抛出异常。语法格式为:

      new 数据类型(初始化参数列表);
    
  • 运算符 delete 用来删除由 new 建立的对象,释放指针所指向的内存空间。语法格式为:

      delete 指针名;
    
  • 运算符 new 也可以创建数组类型的对象。用 new 建立的数组,用 delete 删除时在指针名前面要加“[]",即“delete[] 指针名 ;” 创建数组类型对象语法格式为:

      new 类型名[数组长度];
    

4. 用vector创建数组对象

数组是继承于C语言的一种表示群体数据的方法,具有简单、高效的优点,但无论是静态数组,还是用new动态创建的数组,都难以检测下标越界的错误。为此,C++提供了被封装的动态数组–vector。用vector定义动态数组的形式为:

vector<元素类型>数组对象名(数组长度);
int x = 10;
vector<int>arr(x);  //定义了一个大小为10的int型动态数组对象arr

与普通数组不同的是,用vector定义的数组对象的所有元素都会被初始化。如果数组的元素类型为基本数据类型,则所有元素都会被以0初始化,如果数组元素为类类型,则会调用类的默认构造函数初始化。另外,初值也可以自己指定,但只能为所有元素指定相同初值,形式为:

vector<元素类型>数组对象名(数组长度,元素初值);

对vector数组对象元素的访问形式,与普通数组一致:

数组对象名[下标表达式]

但是vector数组对象的名字表示的就是一个数组对象,而非数组的首地址,因为数组对象不是数组,而是封装了数组的对象。vector定义的数组对象具有一个重要的函数成员 size(),它会返回数组的大小


课程链接:https://www.bilibili.com/video/BV1iF411Y74v

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Mecaly/article/details/128012272

2018年计算机零基础生物工程专业跨考重庆大学计算机考研经验贴_a389965626的博客-爱代码爱编程

2018年计算机零基础生物工程专业跨考重庆大学计算机考研经验贴 **在2018年3月底考研复试完之后,我写了一篇重大计算机考研的初试复试经验贴,为了方便学弟学妹们能够搜索到考研的相关信息,为了方便同学们能够搜到一些重

东南大学2019年计算机学院初试经验+复试笔试回忆,复习经验+复试面试回忆。-爱代码爱编程

写这篇文章的初衷就是当时自己初试复试找了好多经验贴,但是认认真真比较仔细介绍从初试到复试的全过程的看来看去就那么几篇,所以就自己写一篇吧,如果能帮到正在为梦想前行的你们那真是我莫大的荣幸。 初试经验 我考的是东南大学的计

c++语言程序设计郑莉 学习笔记-爱代码爱编程

1.流类对象  11章会讲     2.带类的c 第2讲 c++11 2011年出现的 c++14在c11基础上修复漏洞   3.cout输出流类的一个对象  cout << “helloworld”  给一个流对象重载运算符   4.include 预编译处理 包含库 5.using namespace std 命令空间,防止

《c++面向对象程序设计(第4版)》学习笔记-6-爱代码爱编程

此份笔记建议在完整阅读郑莉老师、董渊老师、何江舟老师所编写的《C++语言程序设计(第4版)》后食用,风味更佳! 最后,由于本人水平有限,笔记中仍存在错误但还没有被检查出来的地方,欢迎大家批评与指正。 第6

C++ 学习路线:快速入门到进阶-爱代码爱编程

C/C++ 是一门底层、细粒度、功能强大、学习曲线陡峭的语言,虽然在Python等新语言的冲击下略显龙钟老态,但随着AIoT设备的兴起,以及C++社区不断推出新的版本,这门语言又重新焕发了生机。 本文把C++学习划分为入门、熟练、进阶三个阶段,每步提供相应的学习方法和资源,并归纳了每部分需要掌握的知识点供大家复习自检,希望能够帮助大家更好地掌握这门语言。

C++学习笔记(三)——面向对象的程序设计-爱代码爱编程

目录 一、类和对象基础 基本知识 1.概念 2.使用类的成员变量和成员函数: 3.类成员可访问的范围 4.构造函数 5.复制构造函数 6.类型转换构造函数 7.析构函数 8.委托构造函数、  9.前向引用声明 提高 1.this指针 2.静态成员变量 3.成员对象和封闭类 4.常量对象和常量成员函数 5.友元 运算符重载

C++学习笔记 20200828-爱代码爱编程

C++学习笔记_20200828 From:学堂在线 慕课课程《C++语言程序设计》 郑莉 清华大学 文章目录 C++学习笔记_20200828第二章 C++简单程序设计2.2.1 C++的特点和程序实例2.2.2 C++字符集和词法记号C++ 字符集:C++构词法标识符的构成规则2.3.1 基本数据类型、常量、变量C++能够处理的基本数据类型程序

精心为学弟学妹准备的C语言与C++学习路线、书籍、视频推荐和资料,值得收藏!-爱代码爱编程

C语言 有人说:“C生万物,编程之本”,这一点都没有错! C语言是最接近计算机的语言,很多时间,我们都会发现,C语言是非常有必要学习的。 刚开始就是泡书,然后就是抄代码,上机调试,模仿修改,看 n 遍,量变引起质变就会培养出编程思维!!! 数据类型、变量、内存布局、指针基础;字符串、一维数组、二维数组;一级指针,二级指针,三级指针,N级指针概念,指

别再问我推荐什么书籍和网课,这次把私藏很久的资料都贡献了(上),建议收藏!-爱代码爱编程

平时有不少读者朋友问,有没有学习书籍网上课程推荐?今天结合自己学习经历与身边几个朋友的经历总结了一份程序员相关的书籍和网课。 程序员必备资源,值得收藏!点击下载 1、 C语言 书籍 第一本书《C程序设计语言》,机械工业出版社,作者Brian W. Kernighan / (美)Dennis M. Ritchie。C 语言之父写的,入门经典书籍,建议

11个思维导图知识点整理帮你决胜考研(基础课和计算机专业课)| 寻找C站宝藏-爱代码爱编程

本文给大家推荐一下我在考研期间整理的各个学科的思维导图笔记, 几乎涵盖了相关学科的所有知识点和相应的做题技巧, 相信肯定会对你的考研有所帮助!  基础课资源包括考研高等数学/线性代数的整理, 同时将中值定理单独整理出来了. 考研政治整理了那四门课目的内容, 其中一门因为政治敏感无法作为文章发出, 但是导图资源中是包含其内容的. 计算机专业课资

清华郑莉C++语言程序设计学习笔记(5)-模板与群体数据、泛型程序设计与C++标准模板库-爱代码爱编程

第九章 模板与群体数据 9.1 模板 9.1.1 函数模板 函数模板作用:使编译器给自动生成函数。函数模板定义语法: 1、语法形式:template <模板参数表> 函数定义 2、模板参数表的内容: 类型参数:class(或typename)标识符 常量参数:类型说明符 标识符 模板参数:template <参数表> clas

清华郑莉C++语言程序设计学习笔记(6)- 流类库与输入/输出、异常处理-爱代码爱编程

第十一章 流类库与输入/输出 11.1 I/O流的概念及流类库结构 当程序与外界环境进行信息交换时,存在着两个对象,一个是程序中的对象,另一个是文件对象。流:是一种抽象,它负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。流对象与文件操作:程序建立一个流对象,指定这个流对象与某个文件对象建立连接,程序操作流对象,流对象通过文件系统对所链接

清华郑莉C++语言程序设计学习笔记(3)- 数组、指针、字符串-爱代码爱编程

第六章 数组、指针、字符串 6.1 数组的定义与初始化 6.1.1 数组的定义与使用 定义:类型说明符 数组名[常量表达式][常量表达式] 数组名的构成方法与一般变量名相同,例如int a[5][3]表示二维数组,第一维有5个下标(0~4),第二维有3个下标(0-2)。使用:先定义,后使用,大多数时候逐个引用数组元素。 6.1.2 数组的存储与初始

清华郑莉C++语言程序设计学习笔记(2)-类与对象、数据的共享与保护-爱代码爱编程

第四章 类与对象 4.1 导学 对象:现实中对象的模拟,具有属性和行为。定义对象时,通过构造函数初始化;删除对象时,通过析构函数释放资源。类:同一类对象的共同属性和行为。 结构体、联合体、枚举类 4.2 面向对象程序的基本特点 抽象:对同一类对象的共同属性和行为进行概括,形成类。首先注意问题的本质及描述,其次是实现过程和细节。数据抽象:描述某类对象

c++语言程序设计(第5版 郑莉、董渊)学习笔记(自用~)_pluto周的博客-爱代码爱编程

C++语言程序设计 第5版 1.前言2.内容第一章 绪论1.1语言发展1.1.1 概述 机器语言——>汇编语言——>高级语言(包括C++)1.1.2 面向对象结构化程序设计(面向过程的程序设计方法)面向对象的方法1.2 信息存储1.2.1 二进制1.2.2 进制转换1.2.3 信息存储单位1.2.4 二进制数编码表示(原、反、补)1.2

剖分(树形差分)_wyw___的博客-爱代码爱编程

E-剖分_牛客小白月赛62 (nowcoder.com) 题目描述 牛牛有一颗包含n个结点的二叉树,这些结点编号为1 ...n。这颗树被定义为:1、以结点1为根。 2、编号为α结点的两个儿子编号分别为:2 xa和2×巴+ 1。3、每个结点的权重初始都为0。 牛牛接下来会对这颗树进行m次操作,操作的格式是以下四种之—: 1、op a(这里op = 1)代表