【c++基础】第一章 C到C++过度阶段
创始人
2024-04-15 02:48:18
0

第一章 C到C++过度阶段

  • 第一个C++程序:
  • 使用`namespace+名字`
  • using关键字
  • `bool`类型
  • string字符串
  • 结构体struct
  • 结构体成员函数指针的获取方式
  • `const`关键字:
  • 内联函数
  • 函数缺省值:
  • 函数重载:
  • 引用(quote)
  • 开辟空间

第一个C++程序:

//输入输出流,c++标准头里没有.h
#include 
//标准名字空间,避免同名多人协作开发标识符冲突的问题
using namespace std;int main(int argc, char const *argv[])
{int i;cout << "Hello world!!!" << endl; //输出cin >> i;//输入return 0;
}

编译:

g++ hello.c //g++是gcc的提升,g++可以编译的,gcc有的不可

使用namespace+名字

namespace A{int a=50;void showInfo(){cout <<"我在A中"<< endl;}//名字空间也可以互相嵌套namespace B{int a=200;void showInfo(){cout <<"我在A中的B中"<< endl;}}
}
namespace B{int a=100;void showInfo(){cout <<"我在B中"<< endl;}
}int main(){//使用::域名信息符,访问指定空间的变量和函数//使用方式:名字空间::变量/函数cout << A::a << endl;cout << B::a << endl;cout << A::B::a << endl;A::showInfo();B::showInfo();A::B::showInfo();return 0;
}

名字空间,相当于对全局作用域进行分隔。

using关键字

  1. using+具体某个域中的标识:指定具体导入 如:using std::cout; using std::endl;
  2. using+namespace+名字空间:指定某个空间全部导入 如:using namespace std;
  3. 起别名 , 相当于typedef 的作用 如:using uint32=int;

bool类型

只有两个值(1true、0false)

#include using namespace std;int main()
{bool ok;ok = true;cout << ok <

string字符串

std::string

边界检查:str.at(110);//解决越界问题

#include using namespace std;
using std::string;int main()
{string str="yao";//    cout << str[100] << endl;//越界,不提示
//    cout << str.at(100) << endl;//越界,提示错误const char *c_str =str.c_str();//使用c指针访问字符串cout << c_str << endl;//yaocout << str.front() << endl;//字符串第一位API 即:ycout << str.back() << endl;//字符串最后一位API 即:ocout << str.length() << endl;//字符串的长度API 即:3cout << str.size() << endl;//字符串的大小API(不同于c字符串,没有'\0') 即:3string str1="liang";cout << str+str1 << endl;//追加字符串str+=str1;cout << str << endl;//yaoliangstr.append(str1);//API追加字符串cout << str << endl;//yaoliangliangreturn 0;
}

结构体struct

  1. 可以定义函数,直接复制,不像c中声明
  2. 具有封装性,默认public,也可设置成private(私有的)
  3. class是struct衍生而来,默认是private
#include using namespace std;struct stu{
public:string name="yaoliang";static int salary;int age;void write_code(){cout << "writing" << endl;}
};//结构体大小
//1.与非代码段和非静态区相关,函数在代码段(所以不计算),static修饰的变量在静态区(所以不计算)
//2.string 的大小为32,在64位系统,以8字节对齐int main()
{stu s;s.age=18;cout << s.age << endl;//18cout << s.name << endl;//yaoliangs.write_code();//write.ingcout << sizeof(stu) << endl;//40   (字符串32位+int(8字节对齐))return 0;
}

结构体成员函数指针的获取方式

&的扩展

#include using namespace std;
struct Stu{string name;int age;void show_stuInfo(){cout << "姓名:" << name << ",年龄:" << age << endl;}
};void show_Info(){cout << "加油!!!" << endl;
}int main()
{int a=10;int *p=&a;cout << *p << endl;int arr[3]={1,2,3};int (*parr)[3]=&arr;cout << **parr <

在c++中的作用域:全局作用域,局部作用域(包括语句块作用域),类域,名字空间作用域

const关键字:

int a=100;
printf("%d\n",*p);
const int *p=&a;//指针可变,a值不能变
int const *p=&a;//指针可变,a值不能变
int * const p=&a;//指针不可变,a值可以改变
const int * const p=&a;//都不可改变
总结:const修饰指针,看*,*前+const,数值不变,*后+const,指针指向不变
#include using namespace std;//所以在c++中,用下面这个
const int my_max = 1024;
//(在编译阶段替换,优于#define MAX 1024(在预处理阶段,不安全,error不好找))int main()
{const int a=10;int *p=(int *)&a;*p=500;cout << " a = " << a << endl;//10cout << " *p = " << *p << endl;//500//原因:编译优化:const修饰的变量承接的是一个常量值,//编译器在编译阶段,将自动把a当作一个常量const int volatile b=20;//volatile 防止编译优化,可以随时改变int *q=(int *)&b;*q=200;cout << " b = " << b << endl;cout << " *q = " << *q << endl;return 0;
}

内联函数

条件:不能耗时,不能循环,不能递归,代码精简(3不1精)

功能:解决C中宏函数的问题。

宏函数的优势:没有函数调用的过程,没有函数栈帧的开辟,没有函数的跳转

内联函数的作用:大大提高了程序的运行效率,但是也有代价的,最终可执行代码膨胀

#include using namespace std;
#define min_i(x,y)    ((x)<=(y)?(x):(y))
#define min_t(type,x,y) ({type _x = x;type _y = y;_x<_y?_x:_y;})
#define min(x,y)    ({\const typeof(x)  _x = (x);\const typeof(y) _y = (y);\_x<_y?_x:_y;\})
//内联函数
inline int my_min(int x,int y){return x

define和inline的区别:

  1. 内联函数在编译时展开,define在预处理阶段展开
  2. 内联函数直接嵌入到目标代码中,宏只做一个简单的文本替换
  3. 内联函数在编译阶段有类型检测,语法处理等功能,而宏没有
  4. inline是函数,宏不是

函数缺省值:

#include using namespace std;int add(int a=2,int b=1){//从右往左依次赋值,不能跳跃,原因入栈先后顺序return a+b;
}int main()
{int a=10,b=20;cout << add(a,b) << endl;//结果为:30cout << add(a) << endl;//结果为:11,采用缺省cout << add() << endl;//结果为:3,采用缺省return 0;
}

函数重载:

是函数调用的灵活实现,也是多态的一种(同名函数的不同实现《执行逻辑的不同》)。

底层机制:根据不同的**参数类型,参数个数不同,与返回值无关,函数名相同**,则会在底层的程序的代码段的符号表中生成一个新的函数名,当使用不同的实参调用时,寻找匹配的函数调用。

#include using namespace std;int add(int a,int b){return a+b;
}float add(float a,float b){return a+b;
}string add(string a,string b){return a+b;
}//int add(int a,int b,int c=1){
//    return a+b;
//}//与上面的int add(int a,int b)存在二义性,不能同时存在int main()
{cout << add(1,2) << endl;cout << add(3.14f,5.12f) << endl;cout << add("yao","liang") << endl;return 0;
}

注意:使用缺省值,注意二义性

引用(quote)

出现原因:避免程序中出现野指针的现象,因为野指针在代码维护中,很难发现问题

底层实现:类型 * const 指针变量 = &变量

#include using namespace std;int add(int * const a,int * const b){return *a+*b;
}
int main()
{int a=10,b=20;cout << add(&a,&b) << endl;return 0;
}

语法形式:类型名& 引用变量 = 某个变量

#include using namespace std;int add(int * const a,int * const b){return *a+*b;
}int add(int& a,int& b){return a+b;
}int main()
{int a=10,b=20;cout << add(&a,&b) << endl;cout << add(a,b) << endl;cout << "a的地址:" << &a << endl;//0x4444int * const c=&a;cout << "c的地址:" << c << endl;//0x4444int& c=a;//c没有自己的空间,相当于a的别名,相当于int * const &c = a;cout << "c的地址:" << &c << endl;//0x4444return 0;
}

引用优点:防止指针传址造成的不良影响,

注意:不要返回局部的返回值,引用作为函数返回值时,可以作为左值使用

#include using namespace std;static int f = 100;int& add(int& a,int& b){f=a+b;return f;
}int main()
{int a=10,b=20;cout << add(a,b) << endl;//30add(a,b)=1000;cout << f << endl;//1000return 0;
}

指针与引用的对比:

#include static int *fun;int *func(int * const a,int * const b) {int sum=*a+*b;fun=∑return fun;
}int main(int argc, const char *argv[])
{/*your code*/int x=10,y=20;printf("%d\n",*func(&x,&y));*func(&x,&y)=100;printf("%d\n",*fun);return 0;
}

实例(数值交换):

#include using namespace std;void swapfunc(int& a,int& b){int temp=a;a=b;b=temp;
}int main()
{int x=10,y=20;cout << "x = " << x << ",y = " << y << endl;//x=10,y=20swapfunc(x,y);cout << "x = " << x << ",y = " << y << endl;//x=20,y=10return 0;
}

常引用:

#include using namespace std;string func(const string & s){
//    s="yao";return s;
}int main()
{string str="yaoliang";cout << "str = " << func(str) << endl;return 0;
}

总结:

从编译器上:

  • 引用是指针的升级

从语法形式上:

  • 引用变量是引用空间的变量别名
  • 引用引用的是一块合法的空间
  • 指针可以是野指针,十分灵活,在c++中可能会把程序写飞
  • 指针可以进行无限次的赋值
  • 引用只能赋值一次int * const a = &b; <==>int &a = b

开辟空间

在c中:

int *p=(int *)malloc(sizeof(*p));//申请空间,不初始化
memset(p,0,sizeof(*p));//初始化升级:
int *q=(int *)calloc(0,sizeof(*q));//申请空间直接初始化升级:
int *s=(int *)realloc(ptr,sizeof(int)*5);//给申请空间申请空间
realloc()函数将ptr所指向的内存块的大小更改为字节大小。
内容将在区域的开始到新旧大小的最小值的范围内保持不变。
如果新的大小大于旧的大小,则新增的内存将不会初始化。
如果ptr为NULL,那么对于所有size值,调用等价于malloc(size);
如果size等于零,且ptr不为NULL,则调用等价于free(ptr)。
除非ptr为NULL,否则它一定是由之前对malloc()、calloc()或realloc()的调用返回的。
如果指向的区域被移动,则执行free(ptr)操作。

failure:NULL;

cpp中:

#include using namespace std;int main()
{int *p=new int;//malloccout << *p << endl;  //单纯开辟空间,未初始化int *q=new int();//可在括号中指定初始化的值,calloccout << *q <

new是一个函数,里面调用了malloc();delete同,所以delete和delete[]功能相同,区别在于规范

failure:throw()抛出异常,bad_alloc()

注意:

  • 内置函数中,存在两步,申请与释放,所以delete与delete[]无区别,可以不规范

  • 自定义函数中,new不光是开辟空间,而且在开辟空间后会调用类中的构造函数,对类对象进行初始化

    ​ delete不光是回收空间,而是在回收空间前,先对类对象进行析构,所以必须规范使用

在这里插入图片描述

#include using namespace std;struct stu{string _name;int _age;//结构体或类中的构造函数stu(string name ,int age){_name=name;_age=age;cout << "含参构造"  << endl;}//开辟多个空间stu(){cout << "无参构造" << endl;}//结构体或类的析构~stu(){cout << "析构" << endl;}
};int main()
{stu* s=new stu("yaoliang",19);delete s;stu * ss=new stu[5];delete[] ss;return 0;
}

相关内容

热门资讯

银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...