C++ 基础语法 一

C++ 基础语法 一

文章目录

  • C++ 基础语法 一
    • const 限定符
    • 常量指针
    • 类型别名
    • auto
    • decltype
    • QString
    • vector
    • 迭代器
    • 指针和数组
    • 显示转换
      • static_cast
      • const_cast
    • 函数
      • 尽量使用常量引用
      • 数组形参
      • 不要返回局部对象的引用和指针
      • 返回数组指针
    • C++四种转换
    • 内联函数
    • constexpr函数
    • 函数指针

const 限定符

const对象一旦创建后 他的值就不能再改变 所以const对象必须初始化,常量特征只有是在执行改变其值才会发挥作用,默认情况下,const对象仅在文件内有效,多个文件内有同名const 变量其实是等同于不同文件分别定义了独立变量。如果要多个文件共享一个const变量 需要使用 extern

exten const int bufSize = 512 该常量可以被其他文件访问

常量指针

         int i=42;int *const curErr = &i;  // 把 * 放在const 前面代表这个指针是一个常量,不能改变指正本身的值 而非指向的那个值cout<<curErr<<" "<<*curErr<<endl;// 0x61fe14 42i=5;cout<<curErr<<" "<<*curErr<<endl;// 0x61fe14 5const double pi = 3.1415926;const double *const pip = &pi; // pip是一个常量对象的常量指针

类型别名

typedef double wages;    //wages 是double的别名
using si = sales_item;   // si是sales_item的别名

auto

// 使用auto 也能在一条语句中声明多个变量,因为声明语句只有一个基本数据类型,所以该语句中所有的变量的初始基本数据类型必须都一样auto i = 0,*p = &i; // 正确auto sz = 0,pi = 3.14;  // 错误 sz和pi类型不一致

decltype

选择并返回操作数的数据类型

decltype(f()) sum = x // sum类型就是函数f的返回类型

QString

      string s1 = "hello ";string s2 = "world";string s3 = s1+s2;cout<<&s1<<" "<<&s2<<" "<<&s3<<endl;s1 += s2;  // 直接在s1后面追加 不会创建对象cout<<&s1<<" "<<&s2<<endl;当把string对象和字符字面值以及字符串字面值混在一条语句使用时,必须确保每个加法运算符的
两侧只有有一个是string,字符串的字面值不是string 是 const char []

string s1("hello world!!!");int punct_cnt = 0;for(auto c : s1){if(ispunct(c)){punct_cnt++;}} 统计是标点符号的个数// 通过引用修改范围变量的本身的值
string s1("hello world!!!");for(auto &c : s1){c = toupper(c);}cout<<s1<<endl;

vector

本身是模板而非类型,由vector生成的类型必须包含vector中元素的类型,例如vector,模板本身不是类或函数 ,相反可以将模板看做为编译器生成类或函数编写的一份说明。编译器根据模板创建的类或函数的过程称为实例化。

      // 如果初始化时使用了花括号的形式但是提供的值又不能用来初始化,这时候就要考虑用这样的值
来构造vector对象了。vector<int> v1{10}; //初始化v1 有一个元素 就是10printf("%d\n",v1.size());vector<string> v2{10}; // 10个空字符串printf("%d\n",v2.size());

迭代器

标准库类型使用iterator和const_iterator来表示迭代器类型

vector<int>::iterator it;  // it 可以读写vector<int>的元素string::iterator it2;  // it2 可以读写string的元素vector<int>::const_iterator it3; // it3 只能读元素 不能写元素string::const_iterator it4; // it4 只能读元素 不能写元素

const_iterator 和常量指针差不多 能读取但不能修改它所指的元素值 ,相反iterator可读可写。为了方便我们得到const_iterator 类型返回值 ,C++11提供了两个新函数 分别是cbegin 和 cend;

指针和数组

在C++语言中指针和数组有着非常密切的联系 ,使用数组的时候编译器会把他转换为指针,在很多用到数组名字的地方,编译器都会自动的将其转换为一个指向数组首元素的指针。指向数组的指针拥有更多功能,数组的指针全部支持,特别注意尾后指针不能执行解引用和递增操作

         int arr[] = {1,2,3,4,5};for(int * b = arr;b!=arr+5;b++){cout<<*b<<" ";}int arr[] = {1,2,3,4,5,6,7,8,9,10};int *beg = begin(arr); //beg 指向arr的第一个元素 begin 是定义在iterator头文件中的一个函数 ,用来返回一个指向arr首元素的指针int *last = end(arr); //last 指向arr的尾元素的下一个位置 end 是定义在iterator头文件中的一个函数 ,用来返回一个指向arr尾元素的下一个位置的指针while (beg != last){cout<<*beg<<endl;++beg;}

c标准库string函数 ,使用此类函数的指针必须指向以空字符作为结束的数组,例如:

char ca[] = {'C','+','+'}; //不是一个以空字符结束的字符串
cout<<strlen(ca)<<endl;    //严重错误 strlen是一个计算以空字符结束的字符串长度的函数,但是ca不是一个以空字符结束的字符串,
strlen函数将有可能沿着ca之后的内存继续查找,直到找到一个空字符为止

不能直接用string对象直接初始化指向字符的指针。为了完成该功能,string专门提供了一个名为c_str 成员函数

char * string = s // 错误 不能用string对象初始化char*
const char * str = s.c_str()   // 正确

可以使用数组初始化vector对象 ,允许使用数组来初始化vector对象 。要实现这一目的只需要指明拷贝区域的首元素地质和尾后地址就行。

int int_arr[] = {1,2,3,4,5,6,7,8,9,0};
vecotr<int> ivec(begin(int_arr),end(int_arr));]

最外层的循环控制变量声明成引用类型 ,这是为了避免数组被自动转换成指针 ,如果不用引用类型 编译器会初始化row 时会指向数组首元素的指针 这样便是得到int * ,显然内循环就不合法了,要使用范围for语句处理多维数组 除了最内层的循环外,其他的所有的循环变量都应该是引用类型

int ia[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};for(auto &row : ia){  for (auto col : row){cout<<col<<endl;}}

显示转换

一个命名的强制转换具有如下形式: cast-name<type> (expression);

case-name 是 static_cast dynamic_cast const_cast reinterpret_case

static_cast

任何具有明确意义的类型转换,只要不包含底层的const,都可以使用static_cast。通过一个运算对象强制转换成double类型就能使表达式执行浮点数除法

// 进行强制类型转换double slope = static_cast<double>(5)/2;    

static_cast 对于编译器无自动执行的类型转换也非常有用。例如我们可以使用static_cast 找回存在的void* 指针 强制转换结果将与原始的地址值相等。

        int d = 3.14;void * p = &d;  // void * 指针可以存放任意对象的地址double *dp = static_cast<double*>(p); // 不能直接赋值,需要强制类型转换

const_cast

const_cast只能改变运算对象的底层const

    const char *pc;char *pcc = const_cast<char*>(pc);  // const_cast 只能改变底层const 通过p写值是未定义的行为

对于将常量对象转换成非常量对象的行为,我们一般称其去const 性质,一旦去掉了某个对象的const性质,编译器就不在阻止我们对该对象进行写操作。只有const_cast 能改变表达式的常量属性。

函数

尽量使用常量引用

把函数不会改变的形参定义成普通的引用是一种比较常见的问题,这么做会给函数调用者带来一个误导即函数可以修改他的实参值。此外使用引用而非常量引用会极大的显示函数所能接受的实参类型。我们不能把const对象 ,字面值或者需要类型转化的对象传递给普通的引用形参。

数组形参

数组的两个特殊性质:不允许拷贝数组以及使用数组时会将其转换成指针,因为不能直接拷贝数组,所以不能使用值传递的方式使用数组参数,因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际传递的是指向数组首元素的指针。

当和其他使用数组的代码一样,以数组作为形参的函数必须确保使用数组不会越界。当函数不需要对数组元素执行写操作的时候,数组形参应该是指向const的指针,只有当函数确实要改变元素的时候,才把形参定义成指向非常量的指针

void print(int (&arr)[10]){ // c++ 允许将变量定义成数组的引用for(auto i:arr){cout<<i<<" ";}
}

f(int &arr[10]) arr是引用数组
f(int (&arr)[10] arr是具有10个整数的整形数组的引用

C++ 引用的数组和数组的引用-CSDN博客

不要返回局部对象的引用和指针

函数完成之后,他所占用的存储空间也会随之被释放,因此函数终止意味着局部变量的引用将指向不在有效的内存区域。main 函数不能调用自己

返回数组指针

数组不能拷贝,所以函数不能返回数组,不过,函数可以返回数组的指针或引用,想要定义一个返回数组的指针或引用的函数比较繁琐,但是有一些方法可以简化这一任务,其中最直接的方法就是使用类型别名

C++四种转换

内联函数

  1. 内联函数可以避免函数调用的开销,将函数指定为内联函数 ,通常就是将它在每一个调用点上内联的展开 例如
    1. cout<<shorterString(s1,s2) <<endl;在编译过程中会自动展开成’cout << (s1.size()<s2.size() ? s1 : s2)<<endl;
  2. 内联说明只是向编译器发出的一个请求,编译器可以忽略这个请求。
  3. 内联机制用于优化规模较小,流程直接的频繁调用的函数,很多编译器都不支持内联的递归调用

constexpr函数

  1. constexper 函数是指用于常量表达式的函数,函数的返回类型及其所有的形参的类型都得是字面值类型。而且函数体中必须有且仅有一条return 语句
    • constexper int new_sz() {return 42;}
  2. 执行该语句时,编译器对把constexper函数的调用替换成其结果值,为了能在编译过程中随时展开,constexper函数被隐式的指定为内联函数,constexper函数体内也可包含其他语句,只要这些语句在运行时不进行任何操作就行。
    • constexper size_t scale(size_t cnt) return {new_sz() * cnt;} 如果arg是常量表达式,则scale(arg) 也是常量表达式
  3. 把内联函数和constexper函数 放在头文件内,内联函数和constexper函数可以在程序中多次定义,他的多个定义必须完全一致

函数指针

  1. 函数指针指向的是函数而非对象,和其他指针一样,函数指针指向某种特定类型,函数的类型由他返回类型和形参类型共同决定,与函数名无关。
    • 比较两个string 对象长度bool lengthCompare(const string& ,const string &);该函数类型是bool (const string &,const string &)。 想要声明一个可以指向该函数的指针,只需要用指针替换函数名即可// pf 指向一个函数,该函数的参数是两个const string 的引用,返回值是bool类型bool (*pf) (const string &,const string &);pf 两端的括号必不可少,如果不写这对括号,则pf是一个返回值为bool指针的函数
  2. 当我们把函数名作为一个值使用时,该函数自动的转换成指针。
    • 按照如下形式我们可以将lengthCompare的地址赋值给pf;pf = lengthCompare; pf指向名为lengthCompare的函数pf = &lengthCompare; 等价的赋值语句,取地址符是可选的
    • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
  3. 我们可以为函数指针赋值一个nullptr 或者 值为0的整形常量表达式,表示该指针没有指向任何函数。
  4. 重载函数的指针,当我们使用重载函数时,上下文必须清晰地界定到底应该选用那个函数,编译器会通过函数的形参列表和返回值确定选用那个函数,指针类型必须与重载函数中某一个精确匹配
  5. 函数指针形参和数组类似,虽然不能定义函数类型的形参,但是形参可以是指向函数的指针,此时,形参看起来是函数类型,实际上却是当成指针使用。
第三个形参是函数类型,他会自动转换成指向函数的指针 
void userBigger(const string& s1,const string& s2 , bool pf(const string & , const string &)); 等价声明:显示的将形参定义成指向函数的指针 
void userBigger(const string& s1,const string& s2 , bool*pf)(const string & , const string &)); 我们可以直接把函数作为实参使用,此时他会自动转换成该函数的指针 
userBigger(s1,s2,lengthCompare) 自动将函数lengthCompare 转换成指向该函数的指针
  1. 返回指向函数的指针,我们必须把返回的类型写成指针类型,编译器不会自动的将函数返回类型当成对应的指针类型处理,与往常一样要想声明一个返回函数指针的函数,最简单的办法是使用类型别名。
using F = int(int*,int); 
F是函数类型,不是指针 
using PF = int(*)(int*,int); 
PF是函数指针 ---- 这里和函数类型的形参不一样,返回类型不会自动的转换成指针,我们必须显式的将返回类型指定为指针 PF f1(int) 正确 F* f1(int) 正确 显式指定返回值类型指向函数的指针 
F f1(int) 错误 不能返回一个函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/58896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tensorflow案例4--人脸识别(损失函数选取,调用VGG16模型以及改进写法)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 这个模型结构算上之前的pytorch版本的&#xff0c;算是花了不少时间&#xff0c;但是效果一直没有达到理想情况&#xff0c;主要是验证集和训练集准确率…

力扣每日一题 超级饮料的最大强化能量 动态规划(dp)

来自未来的体育科学家给你两个整数数组 energyDrinkA 和 energyDrinkB&#xff0c;数组长度都等于 n。这两个数组分别代表 A、B 两种不同能量饮料每小时所能提供的强化能量。 你需要每小时饮用一种能量饮料来 最大化 你的总强化能量。然而&#xff0c;如果从一种能量饮料切换到…

全国产 V7 690T+FT6678 高性能实时信号处理平台设计原理

1、概述 全国产 V7 690TFT6678 高性能实时信号处理平台组成如图 1 所示&#xff0c;包含 1 片SMQ7VX690TFFG1761 和两片 FT-6678&#xff08;国防科大&#xff09;的 DSP&#xff0c;总共 3 个主芯片&#xff1b;每个主芯片外部各搭配 1 组 64bit 的 DDR3 内存模组以及各芯片启…

0.STM32F1移植到F0的各种经验总结

1.结构体的声明需放在函数的最前面 源代码&#xff1a; /*开启时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructu…

Linux高阶——1027—守护进程

1、守护进程的基本流程 1、父进程创建子进程&#xff0c;父进程退出 守护进程是孤儿进程&#xff0c;但是是工程师人为创建的孤儿进程&#xff0c;低开销模式运行&#xff0c;对系统没有压力 2、子进程&#xff08;守护进程&#xff09;脱离控制终端&#xff0c;创建新会话 …

Selective Generation for Language Models 语言模型的选择性生成

生成式语言模型&#xff08;Generative Language Models, GLMs&#xff09;在文本生成任务中取得了显著进展。然而&#xff0c;生成内容的“幻觉”现象&#xff0c;即生成内容与事实或真实语义不符的问题&#xff0c;仍是GLMs在实际应用中的一个重大挑战。为了解决这一问题&…

-bash: ./my_rename.sh: /bin/bash^M: bad interpreter: No such file or directory

在windows上写了一个shell脚本&#xff0c;在Linux上执行时报错&#xff0c;然后看下解决办法&#xff1a; 查了下&#xff0c;其实就是windows系统里文件行尾的换行符和Linux不同引起的&#xff0c; sed -i s/\r$// my.sh用这行代码处理一下&#xff0c;就可以正常运行了。 执…

flutter区别于vue的写法

View.dart 页面渲染&#xff1a; 类似于vue里面使用 <template> <div> <span> <textarea>等标签绘制页面, flutter 里面则是使用不同的控件来绘制页面 样式 与传统vue不同的是 flutter里面没有css/scss样式表&#xff0c; Flutter的理念是万物皆…

idea免费安装步骤,(java集成开发环境)超详细

第一步 点击链接下载 百度网盘 请输入提取码 提取码是idea 下载步骤 可设也可不设置 我就没有设置 下一步 就点击安装就大功告成了

SAP RFC 用户安全授权

一、SAP 通讯用户 对于RFC接口的用户&#xff0c;使用五种用户类型之一的“通讯”类型&#xff0c;这种类型的用户没有登陆SAPGUI的权限。 二、对调用的RFC授权 在通讯用户内部&#xff0c;权限对象&#xff1a;S_RFC中&#xff0c;限制进一步可以调用的RFC函数授权&#xff…

大数据-201 数据挖掘 机器学习理论 - 决策树 局部最优 剪枝 分裂 二叉分裂

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

计算机网络-总线型以太网(ethernet)-知识点小结

广域网与局域网区分: 广域网: 广域网不使用局域网技术, 传输介质 主要是光纤和电话线 常见广域网技术 综合业务数字网&#xff08;ISDN&#xff09;、 帧中继&#xff08;Frame Relay&#xff09;、 异步传输模式 局域网: 以太网--ethernet 简介: 是一种总线型局域网技术&#…

透明加密技术是什么?透明加密技术的原理与应用实践(内含代表性软件分享)

触目惊心&#xff01;10大典型间谍案例回顾 张某离职前搜集大量文件资料&#xff0c;甚至拆开电脑主机拷贝文件 私自存有5200份文件资料 其中标注绝密级的59份 机密级848份 秘密级541份 在当今这个信息化高速发展的时代&#xff0c;透明加密技术已不容忽视。那么&#xff…

C/C++ 每日一练:二叉树的先序遍历

二叉树 binary tree 定义 二叉树是一种树状数据结构&#xff0c;非线性数据结构&#xff0c;代表“祖先”与“后代”之间的派生关系&#xff0c;体现了“一分为二”的分治逻辑。与链表类似&#xff0c;二叉树的基本单元是节点&#xff0c;二叉树的每个节点包含三个主要部分&am…

OpenCV开发笔记(八十二):两图拼接使用渐进色蒙版场景过渡缝隙

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/143432922 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

Unity程序化生成地形

制作地形&#xff1a; 绘制方块逐个绘制方块并加噪波高度删除Gizmos和逐个绘制 1.draw quad using System.Collections; using System.Collections.Generic; using UnityEngine;[RequireComponent(typeof(MeshFilter))] public class mesh_generator : MonoBehaviour {Mesh m…

基于MoviNet检测视频中危险暴力行为

项目源码获取方式见文章末尾&#xff01; 600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【Faster & Mask R-CNN模型实现啤酒瓶瑕疵检测】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生…

Java项目实战II基于Java+Spring Boot+MySQL的桂林旅游景点导游平台(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 基于Java、…

每日读则推(十四)——Meta Movie Gen: the most advanced media foundation models to-date

premiere n.首映,首次公演 v.首次公演(戏剧、音乐、电影) a.首要的,最早的 Today we’re premiering Meta Movie Gen: the most advanced media foundation models to-date. 迄今,到现在为止 …

整数越界详解

目录 一、整数类型的范围 二、整数越界的原因 三、整数越界的示例 1.算术运算导致的整数越界 2.位运算导致的整数越界 3.数据类型转换导致的整数越界 四、整数越界的解决方法 在编程中&#xff0c;整数越界是一个需要特别注意的问题。当整数的计算结果超出了其所能表…