C++基本概念(指针,数组(一维二维),结构体,类和对象)
易混淆概念
-
指针
计算机储存数据时必须跟踪的3种基本属性。
- 信息存储在何处
- 存储的值是多少
- 存储信息的类型是什么
指针是一个变量,其存储的是值的地址,而不是值本身。
常见的变量,使用取地址符号(&)即可获得变量的地址。
而 * 被称为间接值(indirect velue)或者是解除引用运算符。将其引用于指针,即可知道该地址存储的值。
举例:
int update = 6;
int *P_update;
P_update = &update;
int变量update和指针变量P_update只不过是同一枚硬币的两面。
-
关于指针的声明
//指针的声明,必须要指定指针所指向的数据类型
//原因很简单,char和double类型使用的字节数是不一样的
int * pr;
其中 int * 可以看做一种类型,指向int的指针。
-
C++11中,使用new来分配空间
new将找到一个长度正确的内存块,并将返回该内存块的地址。
int * pr = new int;
系统已经给指向int类型的指针pr分配了符合int长度的空间,完成初始化,程序不会报错并发生内存泄漏。
-
C++11中,使用delete释放内存
int * pr = new int;
/****
****/
delete pr;
务必要记住释放内存
-
使用new来创建动态数组,并释放空间
int * psome = new int [10];
delete [] psome;
动态数组,及为可以在程序运行中,需要数组的时候创建,不需要的时候,不创建。
可以在程序运行中选择要创建数组的长度。这就叫动态联编。
使用delete的时候务必要注意。
- 不要使用delete来释放不是new分配的内存
- 不要使用delete释放同一个内存块两次
- 如果使用new【】为数组分配内存,则应该使用delete【】来释放
- 如果使用new为一个实体分配内存,则应该使用delete释放
一定要注意
-
如何使用动态数组
牢记,指针等于数组名,不需要大括号
double * pr = new double [3];
pr[0] = 0.2;
pr[1] = 0.3;
pr[2] = 0.4;
//数组名和指针没有区别
-
指针,数组及指针算术
数组名为数组第一个元素的地址。
double wages[3] = {1.000,2.000,3.000};
short stack[1] = {3,2,1};
double * pw =wages;//注意,数组名为数组第一个元素的地址,就是一个单纯的wages,不需要大括号
short *pr = &wages[0];
显然
现在模拟输出
pw存储的是地址100,pw+1,因为pw是指向double类型的指针,所以pw+1存储的地址是108.
*pw显然是1.000,*(pw+1)是2.000,务必区别*(pw+1)和*pw+1,前者是2.000,后者是3.000
运算顺序不一样。
而pr就不一样了,pr因为是指向short类型的指针,所以pr+1,地址加2
其余同理。
-
函数与数组
数组名被视为地址,int wapes[4],指针名为wapes,就是地址,可以直接int * ps = wapes;
//一维数组
int data[4] = {1,2,3,4};
int sum(int data[],int size);
int sum(int *p,int size);//sum(data,4)可读性一般
//二维数组
int data[3][4] = {{1,2,3,4},{3,4,5,6},{8,5,2,3}} ;
int sum(int (*arg)[4]),int size);
int sum(int data[][4],int size);//可读性比较强
二维数组
在C++中,没有提供二维数组,在C++中创建的二维数组,可以理解为:创建每个元素都是数组的数组。
比如:int maxtemps[4][5];
maxtemps包含四个元素的数组,每个元素都是一个由5个整数组成的数组。
那么在一位数组中,我们知道,数组名(wages【4】的wages)代表第一个元素的地址。
在二维数组中,具体存储数据的是maxtemps[X][Y];
而maxtemps[X][Y]的数组名是maxtemps[X],这就代表了maxtemps[X][Y]的第一个元素的地址是maxtemps[X]。
二维数组,比如max[4][5],如果我只要第一行的元素,将max[0]的地址传出即可
int * pr = max[0];
pr[0]:第一行第一列元素的地址,pr[1]:第一行第二列元素的地址
传参的时候也是
XXX.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
double pr[4][5];
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
XXX.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
pr[0][0]=0;
double * oiu = pr[0];
qDebug()<<"二维数组pr[0]"<<pr[0];
qDebug()<<"double类型的指针"<<oiu;
qDebug()<<"二维数组pr[1]"<<pr[1];
qDebug()<<"二维数组pr[2]"<<pr[2];
qDebug()<<"二维数组pr[3]"<<pr[4];
qDebug()<<"二维数组pr[0][0]"<<pr[0][0];
}
MainWindow::~MainWindow()
{
delete ui;
}
输出如下:
-
结构体C++
可以存储大量数据,并且存储元素的类型可以不一样。
//最标准的结构体
struct inflatable//关键字struct加上结构体名称
{
char name[20];
float volume;
double prices;
};//声明结束需要冒号
关于结构体的初始化
inflatable guest =
{
"Glorious Gloria";
1.88;
29.99;
};
具体访问
guest.name就是查看name的内容,其余同理
如果我们使用typedef的话
//定义结构体
struct Student
{
int a;
};
//于是就定义了结构体类型Student
//声明变量时直接Student stu2;
//如果在c++中如果用typedef的话,又会造成区别:
struct Student
{
int a;
}stu1;//stu1是一个变量
//使用时可以直接访问stu1.a
typedef struct Student2
{
int a;
}stu2;//stu2是一个结构体类型=struct Student
//但是stu2则必须先 stu2 s2;声明一个变量
//然后 s2.a=10;
那么既然如此,我们来看看C里面是怎么样做的
//此处为C++代码
struct Student
{
int age;
char s;
};
//如果要定义一个该结构体变量,就需要:struct Student st1;
//如果是C++的话,直接Student st1;
//以下内容和C++一样
typedef struct Student
{
int age;
char s;
}Stu;
那么我们定义该结构体变量的时候,就可以使用
Stu st1;
st1.age;
综上我们可以看出,typedef的作用,就是将struct Student用Stu这种简单的形式代替而已。
二者在结构的没有typedef下的情况是不一样的,是有区别的。C++显然更加简单
-
结构体的其他内容
1,使用new创建动态结构
struct things
{
int good;
double bad;
};
thing grunose = {3,4.53};
things * pt = &grunose;
//显然,grunose.good = 3,grunose.bad = 4.53;
//显然,pt—>good = 3;pt—>bad= 4.53;
动态即意味着实在程序运行中需要设置的内容,而不是一开始静态编译好的