基础
后缀.cpp。(C Plus Plus)
编译 C++程序时,gcc命令也可以使用,不过要增加-lstdc++选项,否则会发生链接错误。
对象
Student stu;
栈上创建一个Student
类的实例对象stu
。
Student *pStu = new Student;
堆上创建一个Student
类的实例对象pStu
。
使用stu.name
访问对象变量。
使用pStu -> name
访问对象指针的对象变量。
class Student{
public:
//成员变量
char *name;
int age;
float score;
//成员函数
void say(); //函数声明
};
//函数定义
void Student::say(){
cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
}
函数
//函数定义
void Student::say(){
cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
}
但当成员函数定义在类外时,所有文件均可以实现,因此就必须在函数名前面加上类名予以限定,同时这个定义此函数的文件不能引用实现文件,否则会报重复引用的错误。::
被称为域解析符(也称作用域运算符或作用域限定符),用来连接类名和函数名,指明当前函数属于哪个类。
在类体内定义函数称为内联函数(inline),仅适合短小简单的函数。
如果类外函数想定义成内敛函数使用inline
关键字。
命名空间
为避免多人协同开发全局变量命名冲突,C++提供命名空间。
namespace Li {
FILE fp = NULL;
}
namespace Han {
FILE fp = NULL;
}
使用变量、函数时要指明它们所在的命名空间。以上面的 fp 变量为例,可以这样来使用:
Li::fp = fopen("one.txt", "r"); //使用小李定义的变量 fp
Han::fp = fopen("two.txt", "rb+");//使用小韩定义的变量 fp
::是一个新符号,称为域解析操作符,在 C++中用来指明要使用的命名空间
除了直接使用域解析操作符,还可以采用 using 关键字声明,例如:
using Li::fp;
//using namespace Li; 也可
fp = fopen("one.txt", "r"); //使用小李定义的变量 fp
Han :: fp = fopen("two.txt", "rb+"); //使用小韩定义的变量 fp
对于不带.h 的头文件,所有的符号都位于命名空间 std 中,使用时需要声明命名空间 std;带.h 的头文件,没有使用任何命名空间,所有符号都位于全局作用域。
而为了使用cout
等函数,都需要统一using namespace std
。
iostream
iostream 是 Input Output Stream 的缩写,意思是“输入输出流”。
cout<<name<<"的年龄是"<<age<<",成绩是"<<score<<endl;
cout
打印函数,<<name<<
双尖括号包含变量,"的年龄是"
双引号包含文本,endl
结尾。endl
表示end of line
与\n
含义一样。
cin
输入函数,接>>
。
cin
与cout
为iostream
的内置对象,而不是关键字。在C++中推荐使用他们,替代printf
和scanf
。
数组
Student allStu[100];
创建一个 allStu 数组,它拥有100个元素,每个元素都是 Student 类型的对象。
变量的定义
C89和C99是两套不同的C语言标准,在C89中要求变量必须定义在函数开头,而作为C89的升级C99,则没有此要求。而在我们常用的XCode中,就没有此要求,只要变量实在使用前定义就可以,不用定义在开头。另外,此要求不针对C++。
bool类型
C语言没有彻底从语法上支持真假,只是0为假,非0为真。而在C++中则引入bool类型,占1字节,true
表示真,flase
表示假。只是用cout
输出时,还是0
和1
,在java
中可以输出ture
和false
。
const 在C和C++中有趣的不同处理
const int m = 10;
int n = m;
这一段代码在C和C++中含义并不相同。如果使用C语言的环境来编译,则相当于先取出m
所在内存取出数据10
,再将10
赋值给n
。而对于C++编译来说,const
更像#define
,将10
等价替换m
。
因为常量通常不可修改,所以这两种方式最后的结果相同。
但对于特殊情况,例如修改常量。当使用指针的方式,修改常量的内容后:
const int n = 10;
int *p = (int*)&n;
*p = 99;
int m = n;
在C中,m等于99,而在C++中,m等于10。
实际开发中并不会出现这种强行修改常量的情况,只是说明
const
在C++中类似于#define
的处理。
C和C++中const
的作用域相同,都是当前文件,不同的是可见范围。在C语言中整个程序可见,在其他文件中使用extern
声明后就可以使用。而C++中仅限于当前文件,其他文件不可见,因此可以定义在头文件中,多次引用也不会出错。
内存
C语言中使用malloc()
分配内存,使用free()
释放内存。
int *p = (int*)malloc(sizeof(int) * 10);
free(p);
在C++中使用new
和delete
来构造和析构。
int *p2 = new int[10];
delete [] p2;
内联函数
使用inline
关键字来定义内联函数。内联函数适用于函数体比较小的函数,在某些情况下适用于替换宏定义。例如:
#define SQ(y) y*y
如果传入SQ(n+1)
那么结果就是2n+1
而不是n+1
的平方。而使用内联函数可以很好的解决这个问题,如下:
inline int SQ(int y){ return y*y };
当然,也可以多食用括号来解决宏定义的问题,如下:
#define SQ(y) (y)*(y)
推荐使用内联函数。能替代宏定义才更能提现内联函数的作用。
声明的时候不需要使用inline
关键字来指明是否是内联函数,而在实现的时候使用inline
来指明。
函数默认参数
函数可以有默认参数,这点类似于Swift,不同于OC。
void func(int a, b=10, c=@"msg"){ }
func(5,2); //可以只传一个或者两个参数
注意有多个形参时有默认的参数都放在后边,没有的放在前面。
此写法为错:void func(int a, b=10, c=@"msg", int d){ }
同时注意,如果在一个文件中,在声明中指定默认参数,在实现时同样指定默认参数,即时指定的一样,编译器也会报默认参数赋值两遍的错。但如果声明和实现不在一个文件,则不会报错。而且,如果同文件中声明中默认B参数,实现默认C参数,也不会报错。
函数重载
函数名相同,参数不同,返回值无所谓的函数。
void Swap(int a,int b)
会被重命名为_Swap_int_int
;void Swap(float a,float b)
会被重命名为_Swap_float_float
。
函数重载只是语法上的,实际上他们是不同的函数,占用不同的内存,不一样的入口地址。
C与C++混编
因为C++中void Swap(int a,int b)
会被重命名为_Swap_int_int
,而C中会被重命名为_Swap
,所以C++中直接调用自定义的C方法会报错。
#ifdef __cplusplus
extern "C" void display();
#else
void display();
#endif
网友评论