C++基础1:从c过渡到c++

1. Hello World

C plus plus – C语言的超集
C++可以完全引用C
写代码之前的准备:
(1)安装编译环境:yum install gcc-c++ -y
(2)设置缩进: cd /etc/vimrc >> set autoindent
(3)设置行号:set nu

  • 源代码:001_HelloWorld.cpp
 // 第一个C++程序
    #include <iostream>
    using namespace std;
    int main(){
        cout<< "Hello world" <<endl; 
    }
    
  • 编译:g++ HelloWorld.cpp -o HelloWorld
  • 执行:./HelloWorld
  • 结果:Hello world

麻雀虽小,五脏俱全。

2. c++和c语言的差别

HelloWorld.cpp,看C++与C的基本区别:

  1. 文件后缀名.cpp
  2. 头文件#include <iostream>
  3. 命名空间 using namespace std;
  4. 标准输出流cout、输出运算符<<、换行控制器endl ;注意方向;
  5. 函数重载
  6. 动态内存分配

2.1 源文件后缀

  • C/C++头文件后缀名区别
c*.h
c++*.h *.hpp
  • C/C++源文件后缀名区别
c*.c
c++*.cpp *.cc *.cxx
  • 不同编译器C++源文件后缀名区别
平台可用后缀名
Unix*.C, *.cc, *.cxx, *.c
GNU C++*.C, *.cc, *.cxx, *.cpp, *.c++
Borland C++*.cpp
Microsoft Visual C++*.cpp, *.cxx, *.cc

2.2.引用头文件

C++头文件使用C标准库,在C标准库文件名前加上字母c,并且省略后缀名.h,例如:
注意:<>表示引用库里面的头文件,“”自定义的头文件;

cc++
#include <stdio.h>#include <iosteam> /#include <cstdio>
#include <stdlib.h>#include <cstdlib>
#include <string.h>#include <cstring>
#include <math.h>#include <cmath>

有些C++编译器同时支持以上两种头文件,但有些不。请使用C++标准方式


  • 类定义与类实现分离
  • 头文件 – 声明
    方式:#pragma once或者#ifnde...#endif
    作用:防止头文件二次编译
  • 源文件 -- 实现
    引用头文件:#include <>(标准库函数)/#include ""(自定义/第三方函数)

在C++书籍中为了方便.h.cpp不做分离,但是项目开发中,需要分开。

2.3 . 命名空间(同名且参数相同)

cc++
不支持命名空间支持命名空间

(1)命名空间的作用:避免全局变量、函数、类的命名冲突(因为名字相同而编译失败)。
(2) 定义命名空间

 namespace 空间名 {
        // 定义类/函数
    }
  • 引用命名空间
    • using指令(using directive)

      using namespace 空间名;
      

      例如使用标准命名空间std

      using namespace std;
      
    • using声明(using declaration)

      using 空间名::标识符;
      

      例如使用标准命名空间stdcout

      using std::cout;
      

(3 ) 案例:命名空间的简单应用
a.作用,用途:
用来解决函数名相同,函数参数也相同
b.声明的方法:

namespace oldFunc{   //(1.1)函数名相同,函数参数也相同;用命名空间进行区分
void Func(int n){
	cout << "int n "  << n << endl;
}
}

c.调用的方案:
方案1:在main()函数之前进行命名空间的声明;

using namespace oldFunc;  //方案1:进行命名空间的声明;

方案2:在调用的时候加上命名空间

newFunc::Func(100);    //方案2:在调用的时候加上命名空间

方案3: 如果有命名空间,则进行匹配;没有的话,则是标准命名空间;

cout <<("abc")<< endl; //如果有命名空间,则进行匹配;没有的话,则是标准命名空间;

(完整代码见004_namespace.cpp)

#include <iostream>
using namespace std;

namespace oldFunc{   //(1.1)函数名相同,函数参数也相同;用命名空间进行区分
void Func(int n){
	cout << "int n "  << n << endl;
	}
}


namespace oldFunc{
void Func(double n){
	cout << "double n " << n << endl;
}
void Func(int n, int m){
	for(int i = 0; i < m; ++i){
		cout   << n << " " ;
}
	cout<<endl;
}
}

namespace newFunc{  //(1.1)函数名相同,函数参数也相同;用命名空间进行区分
void Func(int m){
	cout << "int m "  << m << endl;
}

}

using namespace oldFunc;  //方案1:进行命名空间的声明;
int main(){
newFunc::Func(100);    //方案2:在调用的时候加上命名空间
	Func(12.5);        
	Func(10,3);
	cout <<("abc")<< ednl; //如果有命名空间,则进行匹配;没有的话,则是标准命名空间;
}



(4)全局命名空间

默认的命名空间,所有名字都在全局命名空间中。
*> 使用方式:直接忽略或者只写::
例如:定义全局函数void test();,默认就是在全局命名空间中,调用方式test()或者::test()

(5)总结

(1) 在C++中,不带.h后缀的头文件所包含和定义的标识符在std空间中;
.h后缀的头文件所包含和定义的标识符在全局命名空间中,不需要声明使用std空间
(2)两种书写方式:
a.如果有声明的话, using namespace old; main()函数调用不用加前缀;
b.如果没有声明,仅仅有 namespace new {// 定义类/函数 }
main()函数调用的时候需要加上new::
(3)全局命名:同一空间,重名的话,采用就近的原则;
::func() (全局对象)

其他注意:cin ,cout ,endl前面的std::可以带也可以不带;


2.4. 函数重载(同名函数的解决)

cc++
不支持重载支持重载

(1)printf().c //出错,出现了相同的(矛盾的声明);
(2)printf().cpp //循序函数重载;
函数重载:函数名相同只有参数(个数或者类型)不相同。

案例: 函数重载在C与C++的编译执行结果
完整代码见 00201_printf.c

 #include <stdio.h>
    void printf(){
        printf("Hello world");
    }
    int main(){
        printf();
    }

完整代码见 00202_printf.cpp

 #include <iostream>
 using namespace std;
    void printf(){
        printf("Hello world");
    }
    int main(){
        printf();

案例3: 函数重载的简单应用

#include <iostream>
using namespace std;

void Func(int n){
	cout << "int n "  << n << endl;
}
void Func(double n){
	cout << "double n " << n << endl;
}
void Func(int n, int m){
	for(int i = 0; i < m; ++i){
		cout   << n << " " ;
}
	cout<<endl;
}

int main(){
	Func(100);
	Func(12.5);
	Func(10,3);
}

2.5 动态内存

#include <stdio.h>
#include <stdlib.h>
int main(){
      int* num = malloc(sizeof(int));
      *num = 100;
      printf("%d\n",*num);
      free(num); 
}
  • dynamic_mem.cpp(c++)
    (完整代码见005_dynamic_mem.cpp)
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main(){
	int  m = 3;
	int *n = new  int[m];  //数组的初始化;
	int n = new int(3);   //数字的初始化;
	for(int i = 0; i < m; ++i){
		n[i] = i + 100;
	}
	for(int i = 0; i < m; ++i){
		printf("%d\n",n[i]);
	}
	delete []n;

}

动态内存区别

CC++
malloc()/free()new/delete

mallocnew 都是 C++ 中用于动态内存分配的函数,但它们之间有一些关键的区别:

  1. 内存分配方式:

    • malloc 是 C 语言中的标准库函数,它只分配所需大小的原始内存块。如果需要初始化为零,则需要手动进行。
    • new 是 C++ 中的操作符,它在分配内存的同时调用构造函数来初始化对象。
  2. 返回类型:

    • malloc 返回 void* 类型的指针,这意味着您需要自己强制转换为适当的类型以便使用。
    • new 返回的是实际类型的指针,无需进行类型转换。
  3. 异常处理:

    • malloc 不提供异常处理机制,如果内存分配失败,它会返回 NULL
    • new 在内存分配失败时会抛出 std::bad_alloc 异常。
  4. 构造函数调用:

    • malloc 不会调用任何构造函数,因此您需要手动初始化分配的内存。
    • new 会在分配内存的同时调用构造函数,确保对象被正确初始化。
  5. 内存管理:

    • malloc 分配的内存需要手动释放,否则会导致内存泄漏。
    • new 分配的内存会在对象生命周期结束时自动调用析构函数并释放内存。
  6. 重载:

    • malloc 不能被重载,因为它不是 C++ 的一部分。
    • new 可以被重载以支持自定义内存分配行为。
  7. 内存对齐:

    • malloc 可能无法保证内存的对齐,这取决于平台和实现。
    • new 通常会保证内存的对齐,以支持某些硬件平台上的高效访问。
  8. 内存大小:

    • malloc 允许分配任意大小的内存块,包括零字节。
    • new 可能会根据特定的数据类型或结构体的大小来分配更大的内存块。
      总之,mallocnew 在功能上有所不同,new 提供了更多的功能和异常处理,而 malloc 则是 C 语言的遗留物。在现代 C++ 代码中,推荐使用 new 来分配和管理动态内存。

问题:

(1) C++仍然可以使用malloc()/free(),但是不建议这么做。malloc需要加上返回值类型;
回答:为它们提供了更好的类型安全性和异常安全性,并且更易于使用和维护。

(2)malloc()申请内存,是否可以使用delete销毁内存?
回答:在C++中,malloc() 函数用于动态分配内存,返回一个 void 指针,可以转换为任何其他类型的指针。而 delete 运算符是用来释放通过 new 运算符分配的内存的。因此,直接使用 delete 来销毁由 malloc() 分配的内存是不正确的,因为这会导致未定义的行为。如果您想使用 delete 来释放由 malloc() 分配的内存,您需要先将 malloc() 返回的指针转换为适当类型的指针,然后再使用 delete。

int* ptr = static_cast<int*>(malloc(sizeof(int) * 10));
// ... 使用 ptr 进行操作
delete[] ptr; // 正确地释放内存

(3) new申请内存,是否可以使用free()销毁内存? no
在C++中,new 关键字用于动态分配内存,返回一个指向该内存的指针。而 free() 函数是C语言中的标准库函数,用于释放由 malloc() 分配的内存。因此,直接使用 free() 来销毁由 new 分配的内存是不正确的,因为这会导致未定义的行为。
如果您想使用 free() 来释放由 new 分配的内存,您需要先将 new 返回的指针转换为 void 指针,然后再调用 free()。

int* ptr = new int[10];
// ... 使用 ptr 进行操作
free(static_cast<void*>(ptr)); // 正确地释放内存

3.c++ 初始化

C++特殊初始化方法

int n=10;
int m(10);
int* n = new int[10]{10,11};

(完整代码见00502_init.cpp)

 #include <iostream>
using namespace std;


int main(){
	int* m = new int(10);  //创建单个对象;
	cout << *m << endl;
//	int* n = new int[10](10);

	int* n = new int[10]{10,11}; //创建数组对象(没有定义的是0)
	for(int i = 0; i < 10;++i){
		cout << n[i] << endl;
	}
}

4 . 类型

  • (1)新增基本类型booltrue/false
  • (2)新增自定义类型class

在C99中stdbool.h中增加三个宏定义booltruefalse。在C++中是内置类型和常量。
如何验证C的bool是宏定义,C++的bool不是宏定义?

  • password.c
#include <stdio.h>
int main(){
      printf("input user name:");
      char name[BUFSIZ];
      scanf("%s",name);
      printf("input 3 number password:");
      int password1;
      scanf("%d",&password1);
      printf("input 3 number password again:");
      int password2;
      scanf("%d",&password2);
      printf("password check:%d\n", password1 == password2);
}
    
  • password.cpp
 #include <iostream>
    #include <cstdio>
    using std::cout;
    using std::cin;
    using std::endl;
    int main(){
          cout << "input user name:";
          char name[BUFSIZ];
          cin >> name;
          cout << "input 3 number password:";
          int password1;
          cin >> password1;
          cout << "input 3 number password again:";
          int password2;
          cin >> password2;
          cout << "password check:" << (password1 == password2) << endl;
    }
    

5. 思想

cc++
面向过程/基于对象

何为面向过程?何为面向对象?

  • 面向过程:强调如何处理(如何解决)
  • 面向对象:强调执行处理的对象(找谁解决)

面向过程与面向对象:厨师与老板

思维区别

  • 将问题按照过程方式来解决?
  • 将问题抽象为一个对象来解决?

6 . 面试

(命名空间)1. 在C++中,不带.h后缀的头文件所包含和定义的标识符在std空间中;
.h后缀的头文件所包含和定义的标识符在全局命名空间中,不需要声明使用std空间

(完整代码见006_new_delete.cpp)

#include <iostream>
using namespace std;
#include <cstdlib>
class Simple{
public:
	Simple(){
		cout << "Simple" << endl;
	}
	~Simple(){
		cout << "~Simple" << endl;
	}
};

int main(){
	Simple* s = new Simple;//(1)自动调用默认构造函数
	delete (s); //(2)自动调用默认析构函数

}

7 扩展阅读

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值