c++ 常量, 指针和常量, 引用, 结构体

常量

c++提供了常量的概念, const就是为了直接表述"不变化的值"这样一个概念.因为不允许赋值,常量就必须初始化.

const int model = 10;//model是个常量
const int v[] = {1, 2, 3, 4};//v[i]是个常量
const int x;//错误:没有初始化

编译器可以靠多种方式利用一个对象是常量的这一性质.例如,对于常量的初始式是常量表达式;如果是这样,那么这个常量就可以在编译时求值.进一步说,如果编译器知道了某const的所有使用,它甚至可以不为该const分配空间.

const int c1 = 1;//不需要分配空间
const int c2 = 2;
const int c3 = my_f(3);//编译时不知道c3的值, 需要分配空间
extern const int c4;//编译时不知道c4的值, 需要分配空间
const int* p = &c2;//因为c2的地址被取用,所以c2需要分配空间

const最常见的用途就是作为数组的界或者作为分情况标号

const int a = 42;
const int b = 99;
const int max = 128;

int v[max];

void f(int i) {
  switch (i) {
    case a: //...
      break;
    case b: //...
      break;
    default:
      break;
  }
}

指针和常量

需要记住的是只有*const的声明运算符,而没有const*的声明运算符, 所以const出现在*之前都修饰的是基础类型(如:int,double等)

char* const p1;  //到char的const指针
char const* p2;  //到const char的指针
const char* p3;  //到const char的指针

引用

一个引用就是某对象的另一个名字.引用的主要用途是为了描述函数的参数和返回类型.特别是函数的重载.

另外,对一个const T&初始式不必是一个左值,甚至类型可以不是T

double& dr = 1;//错误 要求左值
const double& cdr = 1;//ok
//对后一个初始化的解释是
double temp = double(1);//首先创建一个临时变量
cosnt double& cdr = temp;//将这个临时变量作为cdr的初始式

指向void的指针

一个指向任何对象类型的指针都可以赋值给类型为void*的变量,void*可以赋值给另一个void*,两个void*可以比较相等与否,而且可以显示地将void*转换到另一个类型。其他操作都是不安全的,因为编译器不知道实际被指的是哪种对象。因此,对void*做其他任何操作都将引起编译错误。要使用void*,我们就必须显式地将它转换到某个指向特定类型的指针。

void f(int* pi) {
  void* pv = pi;  //可以;从int*到void*的隐式转换式
  *pv;            //错误,void*不能间接引用
  pv++;           //错误,void*不能增量(不知道被值对象的大小)
  int* pi2 = static_cast<int*>(pv); //显示转换为int*

  double* pd1 = pv; //错误
  double* pd2 = pi; //错误
  double* pd3 = static_cast<double*>(pv); //不安全

}

到函数的指针和成员的指针都不能赋给void*

结构

数组是相同类型的元素的一个聚集。一个struct则是任意类型元素的一个聚集

struct address {
  const char* name;
  long int number;
  const char* street;
  const char* town;
  char state[2];
  long zip;
};  //address是定义的新类型的名字(就跟int一样)

void f() {//赋值方式
  address jd;
  jd.name = "Morty";
  jd.number = 61;

  address bb = {"Morty", 61, "South st", "NewYork", {'N', 'J'}, 7974};
}   

void print_addr(address* p) {//通过指针间接访问
  std::cout << p->name << (*p).name;
}

address s(address next) {//作为函数的返回类型
  return next;
}

struct类型名字出现之后立马就可以使用了,不必等到完整的声明之后。

struct Link {
  Link* p;
  Link* n;
};

在完整声明被看到之前,不能去声明这个结构类型的新对象

struct Link {
  Link labs; //错误
};

 想允许两个以上的结构类型互相引用,我们可以先将一个名字声明为结构的名字。

struct List;

struct Link {
  Link* pre;
  Link* suc;
  List* member_of;
};

struct List {
  Link* head;
};

两个结构总是不同的类型,即使它们有着相同的成员

struct S1 {
  int a;
};

struct S2 {
  int a;
};

S1 x;
S2 y = x;//错误,类型不匹配

 

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值