C++基础一

一、命名空间

namespace即“命名空间”,也称“名称空间” 、”名字空间”。

如果两个人写的库文件中出现同名的变量或函数(不可避免),使用起来就有问题了。为了解决这个问题,引入了名字空间这个概念。

命名空间:实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。

命名空间的作用:是建立一些互相分隔的作用域,把一些全局实体分隔开来。

命名空间的作用类似于操作系统中的目录和文件的关系,由于文件很多,不便管理,而且容易重名,于是人们设立若干子目录,把文件分别放到不同的子目录中,不同子目录中的文件可以同名。调用文件时应指出文件路径。

1. 定义命名空间

  namespace name {}
namespace  namespaceA
{
	int a = 10;
}

namespace  namespaceB
{
	int a = 20;
	namespace namespaceC
	{
		struct Teacher
		{
			char name[32];
			int age ;
		};
	}
}

2.使用命名空间

void main()
{
	using namespace namespaceA;
	using namespace namespaceB;
	cout<<namespaceA::a<<endl;
	cout<<namespaceB::a<<endl;

	//显示的, 写全
	{
		namespaceB::namespaceC::Teacher t1;
		t1.age = 33;
	}
	
//	using namespaceB::namespaceC::Teacher  ;
//	Teacher t2;
//	t2.age = 36;
	system("pause");
}

二、register关键字

register关键字 请求编译器让变量a直接放在寄存器里面,速度快 register int a = 0;

三、struct 关键字

struct 关键字 class关键字 完成的功能是一样的 。区别后面介绍 抛砖

class  c1
{
public:
protected:
private:
};

struct Teacher
{
public:
	char name[32];
	int age;
protected:
		int a;
};

void main51()
{
	Teacher t1; //
	t1.age = 10;
	printf("hello...\n");
	system("pause");
}

四、C语言和C++语言变量和函数的区别

C++中所有的变量和函数都必须有类型,C语言中的默认类型在C++中是不合法的。
函数 f 的返回值是什么类型,参数又是什么类型?
函数 g 可以接受多少个参数?

c语言代码:

// i 没有写类型,可以是任意类型
int fun1(i){
	printf("%d\n", i);
	return 0;
}
// i 没有写类型,可以是任意类型
int fun2(i){
	printf("%s\n", i);
	return 0;
}
//没有写参数,代表可以传任何类型的实参
int fun3(){ 
	printf("fun33333333333333333\n");
	return 0;
}

//C语言,如果函数没有参数,建议写void,代表没有参数
int fun4(void){
	printf("fun4444444444444\n");
	return 0;
}

g(){
	return 10;
}

int main(){

	fun1(10);
	fun2("abc");
	fun3(1, 2, "abc");
	printf("g = %d\n", g());

	return 0;
}

以上c代码c编译器编译可通过,c++编译器无法编译通过。
在C语言中,int fun() 表示返回值为int,接受任意参数的函数,int fun(void) 表示返回值为int的无参函数。
在C++ 中,int fun() 和int fun(void) 具有相同的意义,都表示返回值为int的无参函数

五、Bool类型关键字

1. C++中的布尔类型
C++在C语言的基本类型系统之上增加了bool,bool可取的值只有true和false。
理论上bool只占用一个字节,如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现。

bool类型只有true(非0)和false(0)两个值。
C++编译器会在赋值时将非0值转换为true,0值转换为false。

六、三目运算符功能增强

在C语言中,表达式的结果,放在什么地方?寄存器。
在C语言中, 表达式的返回值 是变量的值。

在C++中, 表达式返回的是变量的本身。

int main()
{
	int a = 10;
	int b = 20;

	int var = 100;
	var = 101;

	//返回一个最小数 并且给最小数赋值成30
	//三目运算符是一个表达式 ,表达式不可能做左值
	(a < b ? a : b )= 30;        //C++ 可以这样赋值  因为在C++中, 表达式返回的是变量的本身 

	//int z = (a < b ? a : b );  //C语音的做法 表达式不可能做左值

	printf("a = %d, b = %d\n", a, b);

	system("pause");

	return 0;
}

七、C++ inline函数

介绍内联函数之前,有必要介绍一下预处理宏。内联函数的功能和预处理宏的功能相似。相信大家都用过预处理宏,我们会经常定义一些宏,如:#define TABLE_COMP(x) ((x)>0?(x):0) 就定义了一个宏。

内联函数要实现的大概就是上面这样的宏定义。

inline int myfunc(int a, int b)注意内联函数要和函数体的实现,写在一块。

此部分装载,原文连接:内联函数

1.C++引用inline原因
在我们的系统中可能经常会有一些场景:for循环调用一个工具处理函数或则是递归调用一些算法。我们知道调用一个任意函数都会为这个函数创建栈空间,如果频繁的调用小函数会消耗大量的栈空间,对内存造成很大的压力,甚至会导致内存枯竭。C++为了解决这个问题也就创造了内联函数,也就是inline。

下面我们看一个使用内联函数的例子:

#include <stdio.h>
//函数定义为inline即:内联函数
inline char* dbtest(int a) {
    return (i % 2 > 0) ? "奇" : "偶";
} 

int main()
{
   int i = 0;
   for (i=1; i < 100; i++) {
       printf("i:%d    奇偶性:%s /n", i, dbtest(i));    
   }
}

上面的函数通过一个循环,然后循环的调用dbtest()函数,如果dbtest函数不声明为inline,系统会调用一百次dbtest函数,创建100次栈空间。

但是这里我们将dbtest函数声明成inline函数之后,任何调用dbtest(i)的地方都换成了(i%2>0)?”奇”:”偶”,这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。

2.inline函数使用限制与建议
inline函数虽然对内存有极大的优化,但是也不是随处可用的,我们发现inline函数有点类似于编译器把调用函数的地方改为一份函数代码的副本调用替代,而不用调用一次函数。

所以,inline只适合涵数体内代码简单的涵数使用,不能包含复杂的结构控制语句例如while、switch,并且不能内联函数本身不能是直接递归函数(即,自己内部还调用自己的函数)。

inline函数也不是一定会生效,这个修饰只是对编译器的一个建议,所以最后能否真正内联,看编译器的意思,它如果认为函数不复杂,能在调用点展开,就会真正内联,并不是说声明了内联就会内联,声明内联只是一个建议而已。

其次,因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义。

声明跟定义要一致:如果在每个文件里都实现一次该内联函数的话,那么,最好保证每个定义都是一样的,否则,将会引起未定义的行为。如果不是每个文件里的定义都一样,那么,编译器展开的是哪一个,那要看具体的编译器而定。所以,最好将内联函数定义放在头文件中。

3. inline使用注意点
类中成员函数与inline

定义在类中的成员函数默认都是内联的,如果在类定义时就在类内给出函数定义,那当然最好。如果在类中未给出成员函数定义,而又想内联该函数的话,那在类外定义上要加上inline,否则就认为不是内联的。

比如:

class A
{
    public:void Foo(int x, int y) {  } // 自动地成为内联函数
}

将成员函数的定义体放在类声明之中虽然能带来书写上的方便,但不是一种良好的编程风格,上例应该改成:

// 头文件
class A
{
    public:
    void Foo(int x, int y);
}

// 定义文件

inline void A::Foo(int x, int y){} 

inline 是一种“用于实现的关键字"

关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。

如下风格的函数Foo 不能成为内联函数:

inline void Foo(int x, int y); // inline 仅与函数声明放在一起

void Foo(int x, int y){}

正确的写法应该是:

void Foo(int x, int y);

inline void Foo(int x, int y) {} // inline 与函数定义体放在一起

所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。

4.慎用inline

不是所有的函数都要用inline,内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。 如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。

八、函数的默认参数

C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值。

函数默认参数的规则:
只有参数列表后面部分的参数才可以提供默认参数值。
一旦在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数值。

//1 调用的时候若 你填写参数,使用你填写的,不填写默认,是下面参数 = 
void myPrint(int x = 3)
{
	cout<<"x"<<x<<endl;
}
//2 在默认参数规则 ,如果默认参数出现,那么右边的都必须有默认参数
void myPrint2( int m, int n, int x = 3, int y = 4)
//void myPrint2( int m, int n, int x = 3, int y )   这个编译器报错,因为y没有默认参数
{
	cout<<"x"<<x<<endl;
}

void main_默认参数()
{
	
	myPrint(4);
	myPrint(); 

	//
	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

九、函数的占位参数

函数占位参数 :
占位参数只有参数类型声明,而没有参数名声明,一般情况下,在函数体内部无法使用占位参数。

//函数占位参数 函数调用时,必须写够参数
void func1(int a, int b, int)
{
	cout<<"a"<<a<<" b"<<b<<endl;
}
void main_占位参数()
{
	
	//func1(1, 2); //err调用不起来
	func1(1, 2, 3); // 函数调用时,必须写够参数

	cout<<"hello..."<<endl;
	system("pause");
	return ;
}

十、默认参数和占位参数

可以将占位参数与默认参数结合起来使用
意义:为以后程序的扩展留下线索 。兼容C语言程序中可能出现的不规范写法。

//C++可以声明占位符参数,占位符参数一般用于程序扩展和对C代码的兼容
void  func2(int a, int b, int =0)   //int =0  占位参数和默认参数一起时,下面调用就可以调用起来
{
	cout<<"a="<<a<<";b="<<b<<endl;
}

void main()
{
	func2(1, 2); //0k   //因为上面是默认参数和占位参数在一起,可以调用起来。
	func2(1, 2, 3); //ok
	
	cout<<"hello..."<<endl;
	system("pause");
	return ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值