C++语言对C语言的扩展(一)

概述:众所周知c++语言是面向对象语言,而C语言是面向过程语言,过程和对象语言有什么主要区别呢?

面向过程

系列文章目录


前言

一、面向过程和面向对象的概念

面向过程:
面向过程是一种以过程为中心的编程思想。 通过分析出解决问题所需要的步骤, 然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 面向过程编程思想的核心:功能分解,自顶向下,逐层细化(程序=数据结构+算 法)。
面向对象:
在面向对象中,算法与数据结构被看做是一个整体,称作对象,现实世界中任何类 的对象都具有一定的属性和操作,也总能用数据结构与算法两者合一地来描述。但是实现了模块化,便于以后的开发维护等工作。

二、c++对c的拓展

1.1作用域运算符

通常情况下,如果有两个同名变量,一个是全局变量,另一个是局部变量,那么局 部变量在其作用域内具有较高的优先权,它将屏蔽全局变量。
注:对于同名的局部变量和全局变量,对局部变量来说在他作用域中有着一定的优先权,访问的时候不会访问到全局变量;加上全局变量作用域便可消除,比如::a表示全局变量下的a变量而不是全局变量,所以说作用域运算符是去访问对应作用域下的变量或者函数。
代码如下:


int a = 100;
void test01()
{
	int a = 10;
	cout << a << endl;
	cout << ::a << endl;
}

1.2C++命名空间

命名空间:在 c++中,名称(name)可以是符号常量、变量、函数、结构、枚举、类和对象 等等。工程越大,名称互相冲突性的可能性越大。另外使用多个厂商的类库时,也 可能导致名称冲突。为了避免,在大规模程序的设计中,以及在程序员使用各种各 样的 C++库时,这些标识符的命名发生冲突,标准 C++引入关键字 namespace(命 名空间/名字空间/名称空间),可以更好地控制标识符的作用域。
命名空间的使用代码如下:

int a = 23;
int b = 28;
namespace test_space {/*创建一个命名空间用关键字namespace*/
	int a = 1;
	int b = 2;/*命名空间中定义变量和函数*/
	void test() {
		cout << "love" << endl;
	}
}
void test()/*全局变量中定义函数和变量*/
{
	cout << "hello world" << endl;
}
void test01()
{
	cout << ::a << endl;
	cout << ::b << endl;/*输出全局作用域下的a和b*/

	cout << test_space::a << endl;
	cout << test_space::b << endl;/*输出全局作用域下的a和b*/

	::test();/*调用全局函数*/
	test_space::test();/*调用作用域下的函数*/
}

注:
1,命名空间是开放的,即可以随时把新的成员加入已有的命名空间中,。
2,命名空间只能全局范围内定义
3,命名空间可嵌套命名空间
4,当然声明和实现可以分开
5,无名命名空间(只有关键字namespace),意味着命名空间中的标识符只能在本文件内访问,相当于给这个标 识符加上了 static,使得其可以作为内部连接

1.3using声明

using 声明可使得指定的标识符可用

namespace A{ 
int paramA = 20; 
int paramB = 30;
 void funcA()
 {
  cout << "hello funcA" << endl;
 } 
 void funcB()
 {
  cout << "hello funcA" << endl; 
  } 
 }
 void test()
 { 
 	//1. 通过命名空间域运算符 cout << A::paramA << endl;
 	 A::funcA(); //2. using 声明
 	 using A::paramA; using A::funcA; cout << paramA << endl;
 	  //cout << paramB << endl; //不可直接访问 
 	 funcA(); 
 	 //3. 同名冲突 //int paramA = 20; //相同作用域注意同名冲突
  }

注:当using声明遇到函数重载的时候如果命名空间包含一组用相同名字重载的函数,using 声明就声明了这个重载函数 的所有集合

1.4全局变量检测性增强

#include <stdio.h>
int a =10;/*当做定义*/
int a;/*C语言中当做声明(没有赋值)*/

int main()
{
	return 0;
}
/*C语言编译器可以通过编译*/
/*但是c++编译器无法通过编译,会出现重定义的报错*/

1.5struct加强

在C语言中struct中不能出现函数,并且在定义变量时候需要加上关键字struct
但是在c++中完全可以加上函数内容,以及定义变量时候不需要写struct(要是真的想要在C语言struct里面存在函数只能放函数指针)


struct test_s {
	int a;
	int b;
	void (*test)();
};
void test()
{
	printf("hello world\n");
}

在c++中可以放函数体内容


struct test_s {
	int a;
	int b;
	void test()
	{
		printf("hello world\n");
	}
};

1.6新增"bool"类型

标准 c++的 bool 类型有两种内建的常量 true(转换为整数 1)和 false(转换为整数 0) 表示状态。这三个名字都是关键字。 bool 类型只有两个值,true(1 值),false(0 值) bool 类型占 1 个字节大小 给 bool 类型赋值时,非 0 值会自动转换为 true(1),0 值会自动转换 false(0)


void test()
{
	bool b_test = false;

	b_test = 10;/*非0时自动转换为true*/
	cout << sizeof(bool) << endl;/*输出大小为1个字节*/
}

1.7C语言和c++中const

1.7.1C语言中的const

const int a = 10;//不要把a看成常量 
 //a的本质 是变量 只是 只读变量
//c语言的const修饰全局变量 默认是(外部链接的) 
//外部链接:其他源文件 可以使用 3
const int num = 100;//只读的全局变量 内存放在文字常量区(内存空间只读)
extern const int num;

//对fun.c中的num进行声明(不要赋值)
extern const int num;

void test()
{
    printf("num = %d\n",num);
    //num = 200;//err num只读

    //C语言中const 修饰变量名 说明变量名为只读(用户不能通过变量名data进行赋值)
    const int data = 100;//局部只读变量 内存在栈区(内存可读可写)
    //data = 200;//err

    printf("data = %d\n",data);
    //但是:如果知道data的地址 可以通过地址间接的修改data所对应空间的内容
    int *p = (int *)&data;
    *p = 2000;
    printf("data = %d\n",data);//ok 200
}

总结:在c语言中
1、const修饰全局变量num 变量名只读 内存空间在文 字常量区(只读)、不能通过num的地址 修改空间内容
2、const修饰局部变量data 变量名只读 内存空间栈区 (可读可写),可以通过data地址 间接的修改空间内容

1.7.2,c++中的const

struct test_s {
	int a;
	int b;
};

void test()
{
	/*c++中 对于基础类型 系统不会给data开辟空间 data放到符号表中*/
	const int num = 10;
	/*、c++中当 对data 取地址的时候 系统就会给data开辟空间*/
	cout << num << endl;
	int* p = (int *)&num;

	*p = 1000;
	cout << *p << endl;
	cout << num << endl;
	/*num的值并不会改变因为每次去读num的值的时候都是去符号表找data并不会在内存空间去找*/

	/*当以变量的形式 初始化 const修饰的变量 系统会为其开辟空间*/
	int b = 100;
	const int a = b;
	int* p1 = (int*)&num;

	*p1 = 1000;
	cout << *p1 << endl;
	cout << a << endl;

	/* 自定义数据类型(结构体、对象) 系统会分配空间*/
	const test_s s = {10,10};
	test_s* p2 = (test_s*)&s;
	p2->a = 1000;
	p2->b = 10000;
	cout << s.a << endl;
	cout << s.b <<  endl;/*会改变对应数据的值*/
}

在这里插入图片描述
c++总结
1、const int data = 10;//data先放入符号表
2、如果对data取地址 系统才会给data开辟空间
3、const int a = b;//b是变量名 系统直接给a开辟空间 而 不放入符号表
4、cosnt 修饰自定义数据 系统为自定义数据开辟空间

1.7.3const和define的区别:

1,const有相对应的类型可以方便编译器检查语法错误,而define没有类型
2,const注重作用域,而define是整个文件结束

1.8 c++对c的一个重要扩展——引用

概述:在C语言和c++语言中对指针的概念以及使用都一样但是C++中引入了一个重要的应用概念也可以给函数传递地址,这就是按引用传递.都知道变量其实就是一段有名字的内存空间,引用就是给变量起别名,也就是给这段内存起别名。
基本语法:
基本语法: Type& ref = val; 注意事项: &在此不是求 地址运算,而是起标识作用。

1.8.1给普通变量起别名:

	int a = 100;/*给普通变量起别名*/
	int& b = a;/*基本语法:类型 &起的别名 = 原本的名字*/
	/*注:引用必须要初始化不能直接起别名如int &b;*/

1.8.2给数组起别名

	int arry[10] = {0};/*给数组起别名*/
	int(&test)[10] = arry;/*需要注意括号以及数组元素*/
	/*注:用typedef也可以实现对数组起别名*/

1.8.3函数传参的三种方式:

/*函数值传递*/
void test01(int a,int b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
/*函数指针(地址传递)*/
void test02(int *a,int *b)
{
	int temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
/*函数引用传递*/
void test03(int &a,int &b)
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}
注:如果按照上述代码,只有引用传递和地址传递才能真正改变参数的值

1.8.4函数返回引用:

int& test()
{
	static int a = 10;/*只能返回静态变量的值*/
	int b = 10;
	return a;/*不能返回b(局部变量)*/
}

注意:不能返回局部变量的引用。
这样的话函数就可以作为左值来使用

int& test()
{
	static int a = 10;/*只能返回静态变量的值*/
	int b = 10;
	return a;/*不能返回b(局部变量)*/
}
test() = 100;/*函数作为左值的时候,必须返回引用*/

1.8.5引用的本质:

引用的本质在 c++内部实现是一个指针常量. Type& ref = val; // Type* const ref = &val; c++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间 大小与指针相同,只是这个过程是编译器内部实现,用户不可见。
常量指针和指针常量的区别:
常量指针是指——指向常量的指针,由于他指向的是常量所以他指向的值不能改变,但是他的指向是可以改变的。
指针常量是指——指针本身是常量,也就是他的值不能改变,所以地址不能改变(也就是指向不能改变),但是他指向的变量的大小是可以改变的。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值