从C到C++的过渡(1)

一、第一个C++程序

1、编译器:g++,如果用gcc,需要带上-lstdc++,指定其使用标准C++的运行库。
2、源文件扩展名:.cpp/.cc/.C/.cxx/.c++,最好用.cpp,兼容性好。
3、头文件:#include ,大多数的标准库头文件都没有.h后缀,在/usr/include/c++目录下。
4、输出:cout —— 标准输出对象
    输入:cin —— 标准输入对象
    插入运算符:<<
    提取运算符:>>
5、std:所有标准库的函数、对象、类型都位于std名字空间中。

#include <iostream>

int main(){
	std::cout << "Hello,world!" << std::endl;
	
	int i;
	double d;
	char s[256];
	//scanf("%d%lf%s",&i,&d,s);
	std::cin >> i >> d >> s;
	//printf("%d %lf %s\n", i, d, s);
	std::cout << i << ' ' << d << ' ' << s << '\n';

	return 0;
}

二、名字空间

名字空间用来对程序中的标识符(类型、函数、变量)按照某种逻辑规则划分成若干组。

2.1 定义名字空间

namespace 名字空间名{
  名字空间成员;
}

2.2 使用名字空间

(1)作用域限定符:名字空间名::名字空间成员,表示访问特定名字空间中的特定成员。
(2)名字空间指令:using namespace 名字空间名;
    在该条指令之后的代码对指令所指的名字空间中的所有成员都可见。可直接访问这些成员,无需加“::”。
(3)名字空间声明:using 名字空间名::名字空间成员;
    将指定名字空间中的某个成员引入当前作用域,可直接访问这些成员,无需加“::”。
(4)匿名名字空间
    如果一个标识符没有被显示地定义在任何名字空间中,编译器会将其缺省地置于匿名名字空间中。对匿名名字空间中的成员通过“::名字空间成员”的形式访问。
(5)名字空间合并
(6)名字空间嵌套

namespace ns1{
  namespace ns2{
    namespace ns3{
      void foo(){ ... };
    }
  }
}
ns1::ns2::ns3::foo();
using namespace ns1::ns2::ns3;
foo();
#include <iostream>
using namespace std;
//namespace{
	void print(int money){
		cout << money << endl;
	}
//}

//农行名字空间
namespace abc{
	int balance=0;
	void save(int money){
		balance += money;
	}
	void draw(int money){
		balance -= money;
	}
}
namespace abc{
	void salary(int money){
		balance += money;
	}
	void print(int money){
		cout << "农行:";
		::print(money);//访问匿名名字空间中的
	}
}

//建行名字空间
namespace ccb{
	int balance = 0;
	void save(int money){
		balance += money;
	}
	void draw(int money){
		balance -= money;
	}
	void salary(int money){
		balance += money;
	}
}

int main(){
	using namespace abc;//名字空间指令
	save(5000);
	cout << "农行:"  << balance << endl;
	draw(3000);
	cout << "农行:"  << balance << endl;
	
	ccb::save(8000);
	cout << "建行:" << ccb::balance << endl;
	ccb::draw(5000);
	cout << "建行:" << ccb::balance << endl;
	using ccb::salary;//名字空间声明
	salary(6000);
	cout << "建行:" << ccb::balance << endl;
	abc::print(balance);
	return 0;
}

三、C++中的结构体、联合和枚举

3.1 C++中的结构体

(1)定义结构体型变量时,可以省略struct关键字。
(2)结构体内部可以定义函数——成员函数。
(3)sizeof(空结构)—— 1。

//struct.c
/*用gcc编译器编译出来的结果是sizeof(struct A) = 0,sizeof(a) = 0,0xbf814a87,但如果用g++的编译器,则结果大小都为1.
*/
#include <stdio.h>

int main(){
	struct A{};
	printf("sizeof(struct A) = %d\n",sizeof(struct A));
	struct A a;
	printf("sizeof(a) = %d\n", sizeof(a));
	struct A* pa = &a;
	printf("%p\n",pa);
}
//struct.cpp
#include <iostream>
using namespace std;

struct Student{
	char name[128];
	int age;
	void who(){
		cout << "我叫" << name << ",今年" << age << "岁了。" << endl;
	}
};

int main(){
	Student student = {"张飞", 25}, *ps = &student;
	student.who();
	ps->who();

	struct A{};
	cout << sizeof(A) << endl;
	return 0;
}

3.2 C++中的联合

增加了匿名联合的概念。借用联合语法的形式,描述一些变量在内存中的布局方式。

#include <iostream>
using namespace std;

int main(){
	//匿名联合
	union{
		int x;
		char c[4]/* = {'A', 'B', 'C', 'D'}*/;
	};
	cout << (void*)&x << ' ' << (void*)c << endl;
	x = 0x12345678;
	for (int i = 0;i < 4;++i){
		cout << hex << (int)c[i] << ' ';
	}
	cout << endl;
	return 0;
}
/*
联合体union的存放顺序是所有成员都从低地址开始存放。小端模式是低字节存放在低地址,高字节存放在高地址;大端模式是高字节存放在低地址,低字节
存放在高地址。可以这么看,内存地址从低到高,小端模式就是顺时针旋转,大端模式就是逆时针旋转。
*/

3.3 C++中的枚举

C++中的枚举是一个独立的数据类型。

C:
enum E {a, b, c};
enum E e;
e = a;
e = 1000;

C++:
enum E {a, b, c};
E e;
e = a;
e = b;
e = c;
e = 1000;//ERROR!
e = 1;//ERROR!
#include <iostream>
using namespace std;

int main(){
	enum E {a, b, c};
	E e;
	e = a;
	e = b;
	e = c;
	//e = 1000;
	//e = 1;
	return 0;
}

四、C++的布尔类型

bool b = true;
b = false;
cout << sizeof(b) << endl;//1
b = 100;
b = 1.234;
b = "hello";
b = 'A';
#include <iostream>
using namespace std;

int main(){
	bool b = true;
	cout << sizeof(b) << endl;
	cout << b << endl;
	b = false;
	cout << b << endl;
	b = 3.14;
	cout << b << endl;
	char* p = NULL;
	b = p;
	cout << b << endl;
	cout << boolalpha << b <<endl;
	return 0;
}
/*运行后的结果:
1
1
0
1
0
false
*/

五、C++中的运算符别名

C++中的运算符,可以用其他关键字转换,以下列出部分常用运算符的转换。
&& —— and
|| —— or
& —— bitand
| —— bitor
^ —— xor
{ —— <%
} —— %>
[ —— <:
] —— :>


六、C++中的函数

6.1 重载

    在同一个作用域中,函数名相同,参数表不同的函数,构成重载函数关系。
    C++编译器会对程序中的函数做换名,将参数表中的类型信息汇合到函数名中,以保证函数名的唯一。通过extern “C”,可以要求编译器不做C++换名,以方便在C语言的模块中使用C++编译生成的代码。
    nm:linux中的命令,用于显示库文件或可执行文件的符号表。

#include <iostream>
using namespace std;

void foo(int a){
	cout << "foo(int)" << endl;
}
void bar(int a){}
//int foo(int a){}
void foo(int a,double b){
	cout << "foo(int,double)" << endl;
}
void foo(double a,int b){
	cout << "foo(double,int)" << endl;
}
//int foo(int b,double a){}

int main(){
	foo(100);
	foo(100, 1.23);
	foo(1.23, 100);
	//foo(100, 100);
	return 0;
}
#include <iostream>
using namespace std;

namespace ns1{
	int foo(int a){
		cout << "ns1::foo(int)" << endl;
		return a;
	}	
};
namespace ns2{
	double foo(double a){
		cout << "ns2::foo(double)" << endl;
		return a;
	}
};

int main(void){
	using namespace ns1;
	using namespace ns2;
	cout << foo(10) << endl;
	cout << foo(1.23) << endl;
	using ns1::foo;
	cout << foo(10) << endl;
	cout << foo(1.23) << endl;
	using ns2::foo;
	cout << foo(10) << endl;
	cout << foo(1.23) << endl;
	return 0;
}
/*
运行结果:
ns1::foo(int)
10
ns2::foo(double)
1.23
ns1::foo(int)
10
ns1::foo(int)
1
ns1::foo(int)
10
ns2::foo(double)
1.23
*/
//math.cpp 
//g++ -c math.cpp
extern "C" {
	int add(int a,int b){
		return a + b;
	}

	int sub(int a,int b){
		return a - b;
	}
}

//calc.c 
//gcc calc.c math.o -lstdc++
#include <stdio.h>

int add(int,int);
int main(){
	printf("%d\n",add(10,20));
	return 0;
}

6.2 缺省参数和哑元参数

(1)如果调用一个函数时,没有提供实参,那么对应形参就取缺省值。
(2)如果一个参数带有缺省值,那么它后边的所有参数必须都带有缺省值。
(3)如果一个函数声明和定义分开,那么缺省参数只能放在声明中。
(4)避免和重载发生歧义。
(5)只有类型而没有名字的形参,谓之哑元。

#include <iostream>
using namespace std;

void foo(int a = 10, double b = 0.01, const char* c = "xxx");
void foo(){}
void bar(int){
	cout << "bar(int)" << endl;
}
void bar(int, double){
	cout << "bar(int,double)" << endl;
}

int main(){
	foo(1, 3.14, "Hello");
	foo(1, 3.14);
	foo(1);
	//foo();//歧义
	bar(100);
	bar(100, 1.23);
	return 0;
}
void foo(int a/* = 10*/, double b /*= 0.01*/, const char* c/* = "xxx"*/){
	cout << a << ' ' << b << ' ' << c << endl;
}

6.3 内联

(1)编译器用函数的二进制代码替换函数调用语句,减少函数调用的时间开销。这种优化策略称为内联。
(2)频繁调用的简单函数适合内联,而稀少调用的复杂函数不适合内联。
(3)递归函数无法内联。
(4)通过inline关键字,可以建议编译器对指定函数进行内联,但是仅仅是建议而已。inline void foo(int x,int y){ … }

#include <iostream>
using namespace std;

void  testg(){
    cout<<"hello"<<endl;
}

inline void  testgg(){
    cout<<"world"<<endl;
}

int main(){
    testg();
    testgg();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值