1.关于全局变量和局部变量(global & local)
#include <iostream>
using namespace std;
int a = 10;
int avar = 10;
int main()
{
int avar = 20;
::avar = 30; // 做用域运算符
cout << "local scope avar is" << avar << endl;
cout << "global scop avar is" << ::avar << endl;
return 0;
}
2.关于const和extern变量
test1.cpp
----------------------------
#include <iostream>
using namespace std;
string username = "jellon";
extern const int maxvalue = 512;
test2.cpp
---------------------------
#include <iostream>
using namespace std;
const int bufferSize = 512;
extern string username;//use username from test1
extern const int maxvalue; // use maxvalue from test1
int main()
{
cout << "bufferSize:" << bufferSize << endl;
/*
与C语言中的#define做用相似
优势:有类型限制,能够做为常量在出如今程序的任何地方。
例:const int bufSize = 512;
一但定义,就必须初始化而且不能再改变其值。
非const变量默认为在其它文件中能够访问,即默认为extern。
而const变量必定要声明为extern,才能在其余文件中访问
*/
cout << "username from test1.cpp :" << username << endl;
cout << "username from test1.cpp :" << maxvalue << endl;
}
3.关于reference引用&
#include <iostream>
using namespace std;
int main()
{
int ival = 1024;
int &refval = ival;
cout << "reference:" << refval << endl;
int &refval2; //error
int &refval3 = 10; //error
}
引用就是对象的另外一个名字。
引用必须用与该引用同类型的对象初始化。
4.关于typedef
用来定义类型的同义词。
typedef <已经有的类型> <新的类型名>
#include <iostream>
using namespace std;
int main() {
typedef double wages;
typedef int exam_score;
typedef wages salary;
typedef char CH10[10];// (数组)
}
5.关于函数
1)函数的声明
函数声明也称函数模型(或函数原型)。在主调函数中,若是要调用另外一个函数,则须在本函数或本文件中的开头将要被调用的函数事先做一声明。声明函数,就是告诉编译器函数的返回类型、名称和形参表构成,以便编译系统对函数的调用进行检查。
函数声明的通常格式为:函数类型 函数名(形式参数表);
例如:设有一函数的定义为:
double func1(double a, int b, float c)
{
函数体
}
正确完整的函数声明应为:
double func1(double x, int y, float z);
//末尾要加上分号
2)函数调用:
在C++中,除了主函数main由系统自动调用外,其余函数都是由主函数直接或间接调用的。函数调用的语法格式为:
函数名 (实际参数表);
常见的函数调用有下列两种:
方式一:将函数调用做为一条表达式语句使用,而不使用其返回值。若函数调用带有返回值,则这个值将会自动丢失。
例如:max(3,5);
方式二:对于具备返回值的函数来讲,把函数调用语句看做语句一部分,使用函数的返回值参与相应的运算或执行相应的操做。
例如:
int a=max(3,5);
int a=max(3,5)+1;
cout<<max(3,5)<<endl;
if(f1(a,b) cout<<”true”<<endl;
int a=2;
a=max(max(a,3),5);
当调用一个函数时,整个调用过程分为三步进行:
第一步是参数传递;
第二步是函数体执行;
第三步是返回,即返回到函数调用表达式的位置。
3)参数传递:
参数传递称为“实虚结合”,即实参向形参传递信息,使形参具备确切地含义(即具备对应的存储空间和初值)。这种传递又分为两种不一样的方式,一种是按值传递,另外一种是地址传递或引用传递。
A.按值传递
#include <iostream>
using namespace std;
void swap(int, int);
int main() {
int a = 3, b = 4;
cout << "a=" << a << ",b=" <<b<<endl;
swap(a,b);
cout << "a=" << a << ",b=" << b << endl;
return 0;
}
void swap(int x, int y) {
int t = x;
x = y;
y = t;
}
运行结果:
a=3,b=4
a=3,b=4
B. 引用传递
#include <iostream>
using namespace std;
void swap(int *, int *);
int main() {
int a = 3, b = 4;
cout << "a=" << a << ",b=" << b << endl;
swap(a, b);
cout << "a=" << a << ",b=" << b << endl;
return 0;
}
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
运行结果:
a=3,b=4
a=4,b=3
4)关于函数重载:
函数名相同
参数列表不一样
例:
int circle ( int i );
double circle ( double b);
类型的自动转换以匹配
例子:
#include <iostream>
using namespace std;
int circle ( int i );
double circle ( double i );
int main(){
cout << circle(10) << endl;
cout << circle(32.2) << endl;
}
int circle ( int i ){
return i * 20;
}
double circle (double i){
return i / 2.0;
}
5)带默认参数的函数:
例:long Area ( int length = 1, int width = 1)
{
return length*width;
}
表示两个参数默认值都为1。
调用以下:
Area (3, 5); //求长为3,宽为5的面积
Area (3); //求长为3,宽为默认值1的面积
Area (); //求长宽都为默认值1时的面积
函数参数的默认值:
void fun(int a, int b, int c=100)
在调用此函数时可写成
fun(2,4,6),还可写成fun(2,4)。
请注意:赋予缺省值的参数必须放在形参表列中的最右端。例如:
6)内联函数:
内联扩展(inline expansion)简称为内联(inline),内联函数也称为内嵌函数。当在一个函数的定义或声明前加上关键字inline则就把该函数定义为内联函数,它主要是解决程序的运行效率。
计算机在执行通常函数的调用时,不管该函数多么简单或复杂,都要通过参数传递、执行函数体和返回等操做,这些操做都须要必定的时间开销。若把一个函数定义为内联函数后,在程序编译阶段,编译器就会把每次调用该函数的地方都直接替换为该函数体中的代码,由此省去函数的调用及相应的保存现场、参数传递和返回操做,从而加快整个程序的执行速度。
例子:
#include <iostream>
using namespace std;
inline float circle(float r)
{
return 3.14*r*r;
}
#define circle(r) 3.14*r*r
int main(){
cout << circle(10) << endl;
}
6.数组的概念和声明
数组是一段连续的内存单元
声明:char str[10];
用下标来访问,从0到n-1。
做为一个地址,数组名能够赋值给一个合适类型的指针变量。
如:char *s;
s = str;
s[0] = ‘z’;
7.指针运算和地址运算
1)指针的基本概念
声明:
int *a, *b; //声明a、b为整形指针变量
char *r, *s; //声明r、s为字符型指针变量
Account *u; //声明指针u用来存放一个Account对象
2)操做符&和*
&是取地址操做符
*是取值操做符
如:int *ap = &m[3];
给整形指针ap赋于整形数组m[3]的地址,这样ap就指向了m[3]。
注意:&仅仅适用于存储在内存中的数据,不可用于常量,寄存器变量或者表达
只能用指向相同类型的指针给另外一个指针赋值,而在不一样类型的指针之间进行赋值是错误的。好比:
int a,b;
int *p1=&a,*p2=p1; //正确
而:
int a;
int *p1=&a;
double *p2=p1; //错误
3)void指针和const指针
在C++语言中,能够声明指向void类型的指针。指向void类型的指针称为void指针。此外,在声明指针时,还能够用关键字const进行修饰,用关键字const修饰的指针称为const指针。
A.void指针
C++语言容许使用空类型(void)指针,即不指定指针指向一个固定的类型,它的定义格式为: void *p;
表示指针变量p不指向一个肯定的类型数据,它的做用仅仅是用来存放一个地址。
void指针它能够指向任何类型的C++数据。也就是说,能够用任何类型的指针直接给void指针赋值。不过,若是须要将void指针的值赋给其余类型的指针,则须要进行强制类型转换。好比:
int a;
int *p1=&a;
void *p2=p1;
int *p4=(int *)p2;
B.const指针
关键字const放在不一样的位置表示的意义也不相同:
关键字const放在指针类型前,就是声明一个指向常量的指针。此时,在程序中不能经过指针来改变它所指向的值,可是指针自己的值能够改变,即指针能够指向其余数据。
关键字const放在“*”号和指针名之间,就是声明一个指针常量(也称常指针)。所以,指针自己的值不可改变,也即它不能再指向其余数据,但它所指向的数据的值能够改变。
关键字const在上述两个地方都加,则是声明一个指向常量的指针常量,指针自己的值不可改变,它所指向的数据的值也不能经过指针改变。
4)指针运算
地址运算
也称为指针运算,实际上就是用指针对内存的访问。
指针+整数,产生一个指针;
指针-整数,产生一个指针;
指针-指针,产生一个整数。
已知p1和p2指向同一个数组的元素,则下面的语句实现什么功能:p1 += p2 – p1;
5)指针和动态分配到存储空间
new运算符
Delete运算符
应用程序数据所占的内存能够分为3类:静态(常量)存储区、栈、堆。在程序运行开始前就分配的存储空间都在静态存储区中;局部变量分配的存储空间在栈中;动态内存分配的存储空间在堆中,堆也称为自由存储单元。new运算符与delete运算符一块儿使用,就能够直接进行动态内存的申请和释放(也称为建立和删除)
6)malloc
函数malloc 的原型以下:
void * malloc(size_t size);
用malloc 申请一块长度为length 的整数类型的内存:
int *p = (int *) malloc(sizeof(int) * length);
两个要点是“类型转换”和“sizeof”。
7)free
函数free 的原型以下:
void free( void * memblock );
例:
free(p);
8)new运算符
new运算符用于申请所需的内存单元,返回指定类型的一个指针。
它的语法格式为:指针=new 数据类型;
例如:
int *p;
p = new int;
系统自动根据int类型的空间大小开辟一个内存单元,用来保存int型数据,并将地址保存在指针p中。
例如:
int *p;
p = new int[10];
则系统为指针p分配了整型数组的内存,数组中有10个元素
9)delete运算符
delete运算符是释放new申请到的内存。也即,当程序中再也不须要使用运算符new建立的某个内存单元时,就必须用运算符delete来删除它。
它的语法格式为:
delete 指针; //释放非数组内存单元
delete[] 指针; //释放数组内存单元
10)申请和释放
例如:对int型内存单元的申请和释放。
int *p;
p=new int; //申请内存单元
*p=1;
delete p; //释放内存单元
例如:对数组内存单元的申请和释放。
int *p;
p=new int[10];
delete[] p;
注意事项:
在程序中对应于每次使用运算符new,都应该相应地使用运算符delete来释放申请的内存。而且对应于每一个运算符new,只能调用一次delete来释放内存,不然有可能致使系统崩溃。
运算符delete必须用于先前new分配的有效指针,而不能用于未定义的其余任何类型的指针。
C++语言保留了C语言中的两个库函数:malloc()与free()。这两个函数也是实现动态内存分配做用的,其功能分别与运算符new和delete类似。可是最好不要将库函数和运算符混合使用,不然可能致使系统崩溃
对比:
int *p1 = (int *)malloc(sizeof(int) * length); int *p2 = new int[length];