笔者正在学习C++ primer plus,因此该博客将作为读书笔记,记录学习心得,不定期更新内容。欢迎批评指正。
单独编译
- 头文件:放置结构声明,函数原型,类的声明等
- 源代码文件:函数的定义,类的函数定义等
- 源代码文件:调用相关的函数,结构等
头文件常包含:函数原型,使用#define 或const的符号常量,结构声明,类声明,模块声明,内联函数。
在编译器中,一般不要把头文件加入到项目列表中,也不要在源代码文件中使用#include包含源代码文件。
头文件只是视为一种文本文档,在使用#include之后,插入到对应的代码块处。
头文件管理
在同一个文件中只能将同一个头文件包含一次。故此需要使用相应的语法避免多次包含。
//func.h
#ifndef FUNC_H //如果之前没有引入过FUNC_H才进行下面的操作
#define FUNC_H //对该文件进行命名
...
#endif
此处有一个问题:在大型的工程项目中,#include语句到底是应该放在头文件内,还是源文件好一些?期待各位的讨论与指教。
存储持续性,作用域scope,链接性linkage
持续性 | 常用场景 |
---|---|
自动存储 | 在函数或代码块内定义的变量 |
静态存储 | 在函数外定义的变量或使用了关键字static定义的变量 |
线程存储 | 并行处理中常见 |
动态存储 | 用new分配的内存 |
持续性:描述变量的存活寿命,即内存空间是否被收回。
作用域(scope):描述变量在文件多大的范围内可见。
链接性(linkage):描述变量如何在不同的文件或代码块或函数,是否可共享。
注:{ }即为一个代码块
自动,静态变量比较
链接性分类:
- 外部:外部文件可调用
- 内部:本文件可调用
- 不具有:当前的代码块或函数内可用
外部变量在使用时,只能有一个定义。在其他文件使用时,需要加extern。
存储说明符号 | 特点 |
---|---|
auto(c++11已删除) | 自动类型 |
register | 自动变量 |
static | 静态变量 |
extern | 外部引用变量 |
thread_local | 多线程 |
mutable | 即使是const(结构或类),其中的某个变量仍可修改 |
const符号介绍
int no_1=1; //外部链接性的静态变量
static int no_2=1; //内部链接性的静态变量
const int no_3=1; //内部链接性的静态常量
extern const int no_4=1; //外部链接性的静态变量
定位 new运算符
new函数动态分配用法:
int *p=new int ;
int *p=new int [n];
delete p;
delete [] p;
定位new运算符。(重载函数)
#include<new>
char buffer[1000]
int main
{
...
double *p1=new(buffer) double[10]; //用char数组的内存存储double数据
int *p2=new(buffer) int [10]; //覆盖了第一条语句的double数据,从char数组的起始位置,存储变量
int *p3=new(buffer+10*sizeof(int))int [20]; //接着上一条语句继续存储数据
}
定位new分配的空间,实际上是已经分配过的自动变量存储区,并不是动态分配的空间。所以不可以使用delete进行释放。
名称空间
名称空间主要用于解决大型程序开发过程中的变量名称问题。
- 声明区域:可以在其中进行声明的区域,例如全局变量的声明区域为整个文件,局部变量为对应的代码块。
- 潜在作用域:从声明之后到,代码块结束或者文件结束的区域。
具体使用方法有三种:
using namespace std; //using编译指令
using std::cout; //using声明指令
std::cout; //直接引用指令
using声明指令只引入一个变量;而using编译指令则引入了整个名称空间。
如果引入的变量与文件的局部变量有重复,using声明指令会报错,而using编译指令**会用局部变量覆盖掉名称空间的变量。**因此using声明指令安全性更高于using编译指令。
//work.h
#include<iostream.h>
namespace SALES
{
using std:: cout;
using std:: cin;
using std:: endl;
const int QUARTERS=4;
struct Sales
{
double sales[QUARTERS]={0,0,0,0};
double max;
double average;
double min;
};
void setSales(Sales & s,const double ar[],int n);
void setSales(Sales & s);
void showSales(const Sales & s);
}
//work.cpp
#include"work.h"
//#include<iostream>
namespace SALES
{
void setSales(Sales & s,const double ar[],int n)
{
double sum=0;
double max=ar[0];
double min=ar[0];
for (int i=0;i<n;i++)
{
s.sales[i]=ar[i];
sum+=ar[i];
if(ar[i]>max)
max=ar[i];
if(ar[i]<min)
min=ar[i];
}
s.average=sum/n;
s.max=max;
s.min=min;
}
void setSales(Sales & s)
{
cout<<"pleae input the number 1~3"<<endl;
int n;
cin>>n;
double *p=new double [n];
for(int i=0;i<n;i++)
{
cout<<"pleae input the number"<<endl;
cin>>p[i];
}
setSales(s,p,n);
}
void showSales(const Sales & s)
{
for(int i=0;i<4;i++)
{
cout<<s.sales[i]<<" ";
}
cout<<endl<<"max:";
cout<<s.max<<" min:";
cout<<s.min<<" average";
cout<<s.average<<endl;
}
}
//main.cpp
//#include <iostream>
#include "work.h"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv)
{
using namespace SALES;
Sales a,b;
double ar[3]={1.0,3.2,4.5};
//setSales(a,ar,3);
setSales(b);
//showSales(a);
showSales(b);
return 0;
}