1. 认识C++和C的区别

简介: 1. 认识C++和C的区别

认识C++和C的区别

C++最简单的程序

头文件包含问题

#include <iostream>   //不需要.h 直接包含
int main()
{
  return 0;    
}
  • 创建的项目源文件后缀是.cpp
  • 头文件的包含不同
  • 不需要.h 直接包含
  • C语言的标准库头文件
  • 依然按照原来方式包含,一定程序C++兼容C语言
  • C++包含方式: c+原来的头文件,去掉.h
#include <ctime>
  • 自己的写头文件: 按照C语言教的方式包含

完整代码

#include <iostream>
#include <stdio.h>
#include <ctime>
#include <cstdlib>
#include "myhead.h"     //自己写的依旧是按照原来方式
int main() 
{
  printf("C语言的函数!\n");
  return 0;
}

C++命名空间

什么是命名空间

可以提高标识符使用,可以避免命名污染

如何创建命名空间

namespace 空间名
{
  //变量
    //函数
    //结构体
    //类
}
//用namespace 声明一个东西

怎么访问命名空间

  • ::  作用域分辨符
  • 访问空间中的成员: 空间名::成员名
  • 用来区分全局变量和局部变量
  • ::全局变量
#include <iostream>
#include <cstdio>
namespace MM 
{
  int age = 1;
  void print() 
  {
    printf("MM\n");
   }
}
namespace Boy 
{
  int age = 2;
}
int g_num = 1001;
int main() 
{
  printf("%d\n", MM::age);
  printf("%d\n", Boy::age);
  int g_num = 1;
  printf("全局变量:%d\n", ::g_num);
  return 0;
}
  • 省略前缀的方式去调用
//using namespace  空间名;   //要省略的空间名
//注意点:有作用域
#include <iostream>
#include <cstdio>
namespace MM 
{
  int age = 1;
  void print() 
  {
    printf("MM\n");
   }
}
namespace Boy 
{
  int age = 2;
}
int g_num = 1001;
int main() 
{
  printf("%d\n", MM::age);
  printf("%d\n", Boy::age);
  int g_num = 1;
  printf("全局变量:%d\n", ::g_num);
  MM::print();
  using namespace MM;       //省略前缀的调用方式
  print();
  using namespace Boy;
  //printf("%d\n", age);        //二义性问题:有两个选择,不知道找谁
  printf("%d\n", Boy::age);
  printf("%d\n", MM::age);
  return 0;
}

命名空间嵌套

namespace A 
{
  int a=1;
  namespace B 
  {
    int b = 1;
  }
}
void test()
{
  //剥洋葱
  A::a = 1;
  A::B::b = 2;
  using namespace A::B;
  b = 3;
}

先声明后实现

//其他写法: 先声明后实现的一种写法
namespace Data
{
  void print();
  struct student;
}
//必须空间名限定
void Data::print() 
{
}
struct Data::student 
{
  int age;
  int num;
};

标准的命名空间std

  • C++所有的函数和类都是属于标准命名空间
  • 不写using namespace std; 意味着所有C++标准库中的东西都需要加上std::
using namespace std;        //习惯性的操作

C++函数新思想

函数重载

什么是函数重载

C++允许同名不同参数的函数存在,C语言不允许同名函数存在

不同参数的三个体现

  • 数目不同
  • 类型不同
  • 顺序不同:前提条件是存在不同类型
#include <iostream>
using namespace std;
//类型不同
int Max(int a, int b) 
{
  return a > b ? a : b;
}
float Max(float a, float b) 
{
  return a > b ? a : b;
}
//顺序不同
// error C2084: 函数“int Max(int,int)”已有主体
//int Max(int b, int a) 
//{
//
//}
void  print(int a, char c) 
{
}
void print(char a, int c) 
{
}
//数目不同
void print(int a, int b, int c) 
{
}
//想当然了
//double就是末尾加个d  错误的
//char就是加个c 错误的
int main() 
{
  printf("%d\n", Max(1, 2));
  printf("%.1f\n", Max(1.1f, 2.2f));   //错误,C++对于类型要求比C语言严格
  1L;   //long
  1.1f; //float
  1u;     //unsiged;
  //默认的小数是double;
  return 0;
}

函数重载和函数返回值一点毛线关系都没有。

函数缺省

什么是函数缺省

函数缺省就是给形参赋初始值,当不传参的时候使用的是默认值

函数缺省规则

  • 只能从右往左缺省,中间不能有空着的
  • 多文件中,.h文件缺省了,cpp不需要缺省(声明做了缺省,实现就不需要缺省)

缺省的好处

实现函数的不同形态的调用,针对不同需求做不同实现

//loadimage

//putimage

#include <iostream>
using namespace std;
//函数缺省
void printData(int a=1, float b = 1.11f, double c=1.11 , char d = 'A') 
{
  printf("%d\t%f\t%lf\t%c\n", a, b, c, d);
}
int main() 
{
  printData();          //所有形参都是默认值
  printData(9);         //a=9,其他值用默认值
  printData(9, 2.22f);      //a=9 b=2.22 其他默认值
  printData(9, 2.22f, 9.9);   //a=9,b=2.22 c=9.9 其他默认值
  printData(9, 2.22f, 9.9,'D'); //所有的值用的是传入的值
  return 0;
}

C++标准输入和输出

注意点: 目前大家学会即可,不需要问为什么!!!!!后续在IO流会详细讲这些

标准输出

  • cout +  <<  一起完成的
  • 换行: endl替换"\n"
#include <iostream>
using namespace std;       //缺省std前缀的
struct MM 
{
  char name[20];
  int age;
  int num;
};
int main() 
{
  //单个数据输出
    //没有写using namespace std; 必须加前缀
  std::cout << "ILoveyou";    
  cout << 1;
  //多个数据的输出
  cout << "\n";
  cout << "姓名\t" << "年龄\t" << "编号\n";
  struct MM mm = { "mm",18,1001 };
  cout << mm.name << "\t" << mm.age << "\t" << mm.num << "\n";
  //和上面一行代码效果一样
  cout << mm.name << "\t";
  cout << mm.age << "\t";
  cout << mm.num << "\n";
  cout << endl;       //等效:cout<<"\n";
    //一样的是std命名空间中的
  std::cout << std::endl;   
  return 0;
}

标准输入

  • cin + >> 一起完成
  • 输入不需要任何的格式控制字符
#include <iostream>
using namespace std;       //缺省std前缀的
struct MM 
{
  char name[20];
  int age;
  int num;
};
int main() 
{
  cout << "请输入一个整数:";
  int num;
  cin >> num;     //变量名
  cout << num << endl;
  cout << "请输入一个字符串:";
  char str[20];
  while (getchar() != '\n');    //存在跳过显现:清空缓冲区
  //setbuf(stdin, NULL);        //影响汉字输入,汉字的文件操作出现问题  
  //fflush(stdin);          //C++中已经淘汰了,有时候使用没有效果
  cin >> str;             //数组名
  cout << str << endl;
  cout << "input num and str:";
  cin >> num >> str;
  cout << num << "\t" << str << endl;
  cout << "input name,age,num:";
  struct MM temp;
  cin >> temp.name >> temp.age >> temp.num;
  cout << "姓名\t年龄\t编号" << endl;
  cout << temp.name << "\t" << temp.age << "\t" << temp.num << endl;
  return 0;
}

新基本数据类型

bool类型

  • 占用内存是1个字节
  • 打印出来的值是: 0或者1  非零值表示成立
  • 通常用的是false和true做初始化
#include <iostream>
void testBool()
{
  bool bNum = 5;
  std::cout << bNum << std::endl;
  //一般是会用都用关键字初始化
  bNum = false;
  bNum = true;
  //用途:
  //做开关
  //做标记-->查找类的操作
  //做函数返回值
  while (true); //死循环
}
int main() 
{
  testBool();
  return 0;
}

引用类型

希望同学把引用类型理解为一个起别名的用法

  • 左值引用
  • 当做函数参数: 直接修改实参,防止拷贝本产生
  • 当做返回值: 增加左值使用
  • const属性限定问题
  • 右值引用
  • 给右值起别名
  • 当做函数参数: 函数只能传入右值
  • 想要传入左值,使用move函数移动
#include <iostream>
using namespace std;
//No.2  引用类型
void Modify(int& x)  //int& x=b;
{
  x = 9999;
}
//返回引用等效返回一个变量
//warning C4172: 返回局部变量或临时变量的地址: a
int g_num = 1001;
int& getValue() 
{
  return g_num;
}
int getData() 
{
  return g_num;
}
void printString(const char* str)  //char* str="Iloveyou"
{
  cout << str << endl;
}
void modifyNum(const int& num) 
{
  //num++;  //常引用不能做++
  cout << num << endl;
}
void modifyNum2(int&& num)  //只能传入右值
{
  num++;          //提供修改接口
  cout << num << endl;
}
void testNew() 
{
  int a = 1;
  int& b = a;
  b = 1001;
  cout << a << endl;
  //当做函数返回值:增加左值使用好处
  //当做函数参数:防止拷贝本的产生
  Modify(b);
  cout << a << endl;
  //getData() = 1003;  错误,返回是一个值,不是一个变量,不能充当运算符左值
  getValue() = 9999;   //g_num=9999;
  cout << g_num << endl;
  //常量起别名
  //C++对于const属性要求更为严格
  //1.用常引用
  const int& xx = 13;
  cout << xx << endl;
  //error C2440: “初始化”: 无法从“const char [9]”转换为“char *”
  const char* pstr = "ILoveyou";
  printString("ILoveyou");
  char array[10] = "LLLL";
  printString(array);
  //常引用不能修改
  //2.右值引用 &&  --->提供修改接口
  int&& yy = 134;
  yy = 55;
  const int c_num = 112;  //常属性的变量,依旧是左值
  //int&& zz = c_num;   //错误
  modifyNum(1);
  modifyNum2(23);
  //左值变成右值
  int data = 1001;
  int&& data2 = move(data);       //移动函数:把左值变成右值
  int value = 1234;
  //modifyNum2(value);      //错误,用右值引用当做函数参数,不能传左值
  modifyNum2(move(value));        //移动语义(完美转发)
}
int main() 
{
  testNew();
  return 0;
}

C++结构体类型

  • 类型名不在需要struct关键字了
  • C++结构体可以给成员直接赋初始值
  • C++结构体可以包含函数
  • 其实C++结构体的处理就是按照类的方式处理(后续在意)
  • 用了构造函数时候C++结构体和C语言结构体处理方案是完全不同的
#include <iostream>
using namespace std;
//描述的是事物特征和行为
struct MM 
{
  char name[20]="MM";
  int age=111;
  int num=1001;
  void initData(const char* str, int age, int num);   //在结构体声明
  void printData() 
  {
    cout << name << "\t" << age << "\t" << num << endl;
  }
};
//在外面实现,必须结构体名限定
void MM::initData(const char* str,int age,int num) 
{
  strcpy_s(name,20, str);
  //同名问题
  MM::age = age;
  MM::num = num;
}
int main() 
{
  //No.1 类型不需要struct
  MM mm;
  //cout << mm.name << "\t" << mm.age << "\t" << mm.num << endl;
  mm.printData();
  MM mm2 = { "mm2",18,1030 };
  //cout << mm2.name << "\t" << mm2.age << "\t" << mm2.num << endl;
  mm2.printData();
  mm2.initData("小芳", 18, 1004);
  mm2.printData();
  return 0;
}

C++枚举类型

#include <iostream>
using namespace std;
enum State {Open,Close};
enum class Color
{
  Red,
  Blue
};
void print(int state)
{
  cout << state << endl;
}
void printEnum(Color color) 
{
  //cout << color << endl;  不能直接打印
}
void testEnum() 
{
  print(1);
  print(Open);
  //C++的枚举类型不能当做一个简单的int类型
  //print(Color::Red);  //访问必须要用枚举类型名限定
  printEnum(Color::Red);
}
int main() 
{
  testEnum() 
  return 0;
}

C++string类型

C++string本身是一个类,所以大家本节课只要学会使用即可,不需要问问什么

  • 头文件: #include  
  • 注意点和cstring区别,这个是C语言头文件
  • 没有用using namespace std ; string类型需要改为std::string
  • 掌握string常用方式
  • 创建方式
  • 基本操作(比较,连接)
  • 转C语言char*

微软帮助文档:basic_string 类 | Microsoft Docs

#include <iostream>
#include <string>
using namespace std;
int main() 
{
  //std::string str;
  //No.1创建
  string str1;
  str1 = "ILoveyoudsfasdfasdfasdfasdfasd";
  cout << str1 << endl;
  string str2 = "ILoveyousdfsdafads";
  cout << str2 << endl;
  string str3(str2);
  string str4 = str2;
  cout << str3 << endl;
  cout << str4 << endl;
  //No.2 基本操作
  cout << (str3 == str4) << endl;
  cout << (str3 >= str4) << endl;
  string password;
  cin >> password;
  cout << password;
  //原理是:运算符重载 后面会讲
  //比较直接比
  if (password == string("12345")) 
  {
    cout << endl << "密码正确" << endl;
  }
  int a = (int)1.3;   //C语言强制类型转换
  int b = int(1.34);    //C++强制类型转换
  //连接直接加法
  string name = "张三";
  string info = name + "很帅";
  cout << info << endl;
  //上述复杂的用法
  cout << info.compare(name) << endl;  //和strcmp 返回值一样
  cout << info.append(name) << endl;
  //下标的方式访问
  cout << info.length() << endl;     //当前长度
  cout << info.size() << endl;
  for (int i = 0; i < info.length(); i++) 
  {
    cout << info[i];
  }
  cout << endl;
  for (int i = 0; i < info.length(); i++)
  {
    cout << info.at(i);
  }
  cout << endl;
  cout << info.capacity() << endl;   //容量
  //和C语言string.h有区别的 char* 
  // 不能用%s的方式打印
  //printf("%s\n", info);
  // 图形库中传char* 函数 都不能直接用string类型
  //提供两个函数: c_str() data();
  printf("%s\n", info.c_str());
  printf("%s\n", info.data());
  return 0;
}

C++自动推断类型

  • auto类型
  • decltype类型
#include <iostream>
using namespace std;
struct MM 
{
  int age;
};
MM g_MM = { 12 };
MM* createMM() 
{
  MM* p=&g_MM;
  return p;
}
int Max(int a, int b) 
{
  return a > b ? a : b;
}
void print(int(*Max)(int, int), int a, int b) 
{
  cout << Max(a, b) << endl;
}
void printData(int(*)(int, int), int, int) 
{
  cout << "另一个函数" << endl;
}
int main() 
{
  //auto 类型自动推断: 一定要有赋值 所以不能单独定义变量
  //auto a;  没有赋值 推断不出来
  auto a = 1;       //int 
  a = 134;
  auto pMM = createMM();
  cout << pMM->age << endl;
  auto pFunc = print;   //void (*)(int(*)(int, int), int , int ) 
  pFunc(Max, 1, 3);
  pFunc = printData;
  pFunc(Max, 1, 3);
  int* p = nullptr;     //新的空 等效C语言NULL
  //decltype 不需要赋值
  decltype(123) num = 123;    //decltype(123) 表示一个int类型
  //函数指针必须取地址
  decltype(&print) ppFunc;
  ppFunc = printData;
  //推断一个int
  decltype(num) Num = num;
  decltype(&num) pNum = &num; //当你们用的时候,不知道类型,推断定义变量去赋值
  return 0;
}

C++动态内存申请

C申请的内存是自由存储区的,C语言的堆区内存,所以C类的对象内存不能用malloc申请

// IMAGE *

  • new申请内存
  • 申请单个变量内存
  • 申请一段内存
  • 申请内存可以手动初始化
  • 申请内存后可以再分配
  • delete释放内存
  • 释放单个变量内存:delete  指针名;
  • 释放一段变量内存: delete[] 指针名;
#include <iostream>
using namespace std;
struct MM 
{
  char name[20];
  int age;
  int num;
};
void testOne() 
{
  int* pInt = new int;
  *pInt = 123;
  cout << pInt[0] << endl;
  delete pInt;
  pInt = nullptr;
  char* pc = new char;
  delete pc;
  int* pNum = new int(1234);  //申请并且初始化
  cout << pNum[0] << endl;
  delete pNum;
  MM* pMM = new MM({ "name",12,1101 });
  cout << pMM->name << "\t" << pMM->age << "\t" << pMM->num << endl;
}
void testTwo() 
{
  //一段内存的申请
  int size = 4;
  int* pArray = new int[size];    //int pArray[4];
  MM* pMM = new MM[4];        //MM pMM[4];
  delete[] pArray;
  delete[] pMM;
  pArray = nullptr;
  pMM = nullptr;
  int* pNum = new int[4]{ 1, 2, 3, 4 };
  for (int i = 0; i < 4; i++) 
  {
    cout << pNum[i] << "\t";
  }
  cout << endl;
  delete[] pNum;
  pNum = nullptr;
}
void testThree() 
{
  char* pMem = new char[1024];
  //在原来上面拿个20字节存整数
  int* pInt = new(pMem + 0) int[5]{ 1,2,3,4,5 };
  //在原来上面拿出20个存字符
  char* pChar = new(pMem + 20) char[20]{"ILoveyou"};
  //等效:char* pChar = new(pInt + 5) char[20]{"ILoveyou"};
  delete[] pMem;
  pMem = nullptr;
}
int main() 
{
  testOne();
  testTwo();
  testThree();
  return 0;
}
目录
相关文章
|
5月前
|
存储 C++ Cloud Native
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
云原生部署问题之C++ 中的 nullptr 和 NULL 区别如何解决
65 0
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
6月前
|
存储 安全 C++
C++中的引用和指针:区别与应用
引用和指针在C++中都有其独特的优势和应用场景。引用更适合简洁、安全的代码,而指针提供了更大的灵活性和动态内存管理的能力。在实际编程中,根据需求选择适当的类型,能够编写出高效、可维护的代码。理解并正确使用这两种类型,是掌握C++编程的关键一步。
81 1
|
2月前
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
65 10
|
2月前
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
24 0
|
4月前
|
存储 编译器 C语言
C++内存管理(区别C语言)深度对比
C++内存管理(区别C语言)深度对比
85 5
|
5月前
|
Web App开发 Rust 分布式计算
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
|
5月前
|
Rust 安全 编译器
Rust与C++的区别及使用问题之Rust中的bound check对性能产生影响的问题如何解决
Rust与C++的区别及使用问题之Rust中的bound check对性能产生影响的问题如何解决
|
5月前
|
Rust 测试技术 编译器
Rust与C++的区别及使用问题之Rust项目中组织目录结构的问题如何解决
Rust与C++的区别及使用问题之Rust项目中组织目录结构的问题如何解决
|
4月前
|
缓存 C++ Windows
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别