Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C++基本语法

C++基本语法

作者头像
歪歪梯
发布于 2020-08-17 09:35:48
发布于 2020-08-17 09:35:48
1.1K00
代码可运行
举报
文章被收录于专栏:歪歪梯Club歪歪梯Club
运行总次数:0
代码可运行

引言

C++ primer plus的知识笔记,以下内容基于c++11标准

指针与&、*

&在c++中的一种作用为取出当前变量在内存的逻辑地址 *在c++中的一种作用为取出当前逻辑地址对应的内存空间的值 c++中提供指针变量存储对象的地址,指针的运算会被编译器优化为地址的运算,比如一个int类型的指针 p+1的值实际是p指向的地址+1个int所占空间大小后的逻辑地址 指针语法为 typename * variable,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a = 5;
int * p = &a;
*p == 5;//true

而对于结构体指针,可以使用->来操作成员,如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct data{
    int a = 1;
}
data d1 = {
    a:2
};
data * dp1 = &d1;
d1.a = 3;
dp1->a = 5;
(*dp1).a = 6;

宏定义与内联函数

c++中可以在文件头使用#define进行宏定义,编译器在编译时会将代码里特定字符串替换为宏定义以后的结果,这也是内联函数的实现原理(第6版书中255页,8.1小节),所以内联函数会比较占据内存(多个代码副本),也就是调用内联函数的地方,会被编译器替换为内联函数的执行代码,与宏定义的函数区别是,内联函数更加的严谨,其限定了参数类型及返回值类型 比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define eetal 1
int a = eetal;//compile as int a = 1;
#define sum(x,y) (x+y)
int b = sum(1,2);//compile as int b = (1+2)
inline int sum(int a,int b){
           return a+b;
}

因为宏定义会对文本替换,一般用于定义常量等,为了避免重复宏定义,c++提供了#ifndef(if not define缩写)命令来判断当前是否进行了某个名称的宏定义,可以根据结果进行处理 如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 #ifndef eetal
     //code
 #endif

同时还有用于判断宏定义的#if

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define a 5
#if a>5
    ...
#endif

以上代码代表如果没有定义过eetal这个宏变量,则会执行#ifndef和最近的endif之间的代码

类型别名

与宏定义类似的,c++还提供了typedef可以对类型取别名和定义一些函数指针的别名 比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef int iint;
typedef void (*functionPointer)(int a);//接下来代码中

在上述代码之后的代码中使用iint定义变量等价于使用int 使用functionPointer作为类型可以定义指向 返回值为void,只有一个int形参的函数指针 c++11标准给using指令也加入了取别名的用法(真希望可以废弃一些旧的用法,太多重复的东西)。上述代码等价于

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using iint = int;
using functionPointer = void (*)(int a);

泛型

c++的泛型通过template来设定,泛型方法代表该方法尚未注册实际代码,只有在代码里调用了该方法时,会通过隐式触发或者显示定义或者主动触发来创建对应的方法实例 方法的匹配规则为 代码中指定泛型方法>普通方法>显示声明>泛型方法 如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//在一些标准好像typename也会写为class,如下的两种写法swap01和swap02一样
template<class T> void swap02(T &a,T &b){
    T temp = b;
    b = a;
    a = temp;
}

template<typename T> void swap01(T &a,T &b){
    T temp = b;
    b = a;
    a = temp;
}

//泛型的显示声明,匹配规则(代码中指定泛型方法>普通方法>显示声明>泛型方法)
template<> void swap01<int>(int &a,int &b);

此时调用如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a,b;
swap01(a,b);
//普通调用,先匹配显示声明

double c,d;
swap01(c,d);
//显示声明不匹配类型,触发隐式生成double泛型的方法实例匹配

char e,f;
swap01<char>(e,f);
//主动指定方法泛型为char

decltype

因为泛型会导致方法的不安全,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<typename T> void sum(T &a,T &b){
    ? c = a+b;
    //do something
}

因为c++重载了运算符,string类型也可以使用+拼接,那如何确定泛型变量运算返回值的类型呢?于是有了decltype

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
decltype(a+b) c = a+b;

上述代码代表,如果a+b的表达式合法,c的类型即为他们运算后值的类型,deltype还有一个特殊用法来创建引用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int a;
decltype((a)) sa = a;//equals to  int & sa = a;

上述代码代表sa的类型为 a的类型 的引用类型,即变量sa此时是a的一个引用

const与mutable

const

const代表常量定义(java里的final),不可修改。因为cpp里面的指针类型定义比较特殊,所以const的位置代表不同含义,如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const int v = 0;//v cantnot be change anymore

struct data{
    int a;
};

....

data t1 = {
    a = 0;
},t2 = {
    a = 3;
};

const data * p1 = &t1;
//p1->a = 4     cannot work, error
//p1 = p2      it work

data * const p2 = &t2;
//p2->a = 4     it work
//p2 = p1      cannot work, error

如上述代码,p1可以修改指向的地址,但是无法通过p1修改单元内容 p2不可修改指向的地址,但是可以通过p2修改单元内容

mutable

mutable用于标记结构体中不想受结构体的const限制的成员,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const struct data{
    int a = 1;
    mutable int b = 0;
}
data * d = new data();
d->b = 3;//ok
//d->a = 5;error

上述代码创建了一个结构体data,因为其以const修饰,成员a不能被修改,而因为成员b以mutable修饰,不受限制可以修改

volatile

与java一样消除内存屏障用的,标记告诉编译器不要缓存该变量到寄存器或者线程缓存,每次从内存读取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
volatile int a;

thread_local

用于创建存放在当前线程作用域的对象,该对象存放在当前线程内存,在当前线程存活时间里保持存活

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
thread_local int a = 1;

register

在c++11标准里代表默认,类似java的default(在以前标准为通知编译器尽量存储到寄存器,不过c++11改了)

auto

在c++11标准代表类型推断,必须在定义时为变量完成初始化,否则无法推断(在旧版本标准为默认,即当前的register作用)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
auto a = 1;
//auto b; error

static与extern

在c++中,在文件的函数外部,及全局便写的变量为全局变量,其他连接的工程文件在代码里可以通过extern关键字引入其他文件的全局变量。 而static代表标记变量为静态的全局变量,不能被extern发现 全局变量的生命周期时整个程序运行期间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//1.cpp
int A = 100;
static int B = 5;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//2.cpp
extern int A;//100
//extern int B; error

枚举

c++的枚举存储整数,不指定默认第一个为0后续每个依次递增,整数不能直接赋值给枚举变量,需要通过构造,而枚举变量可以直接赋值给整数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum langs{java, cpp};// 0 and 1
//enum langs{java=3, cpp=100};// 3 and 100
langs newLang = langs(1);//cpp
langs anotherLang = java;
int howMuch = anotherLang;//0

new与delete

cpp中也是使用new来创建对象(在cpp中比较习惯称为分配内存,c里还有malloc,calloc,realloc),同时提供释放内存的指令,这会造成很多危险,但是也带来性能的提升

使用new申请内存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<new>
int * p = new int();//只申请一个int的空间,返回地址
int * ap = new int[5];//申请一个5个int元素的数值空间,返回第一个元素地址
int * p2 = new(p) int();//指定要分配空间的首地址,此种方式要引入new头文件

如上代码,其中ap为数组头,而p2指定了首地址为p1,这样代表其分配的空间覆盖了p1的空间,当尝试申请的内存不够时,在c++11中会抛出异常(以前是返回空地址0)

使用delete释放内存

对于普通指针,使用delete 指针删除,而对于数组类型的指针,应当使用delete[]来调用数组各个元素的析构函数(基本类型只是释放),因为p1已经被p2覆盖,所以释放了p2就不能再去释放p1,因为内存已经被回收了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
delete p2;
delete[] ap;

命名空间

c++因为大部分代码还是存在面向过程,放在全局的变量的做法,为了方便管理避免重名,引入命名空间,通过命名空间归类方法和变量,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace std{
istream cin;
ostream cout;
}

上述代码创建了一个std的命名空间,里面的对象通过 命名空间::成员名称 使用,比如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::cin;
std::cout;

通过使用using命令,指定将命名空间内容加入当前代码块,则可以省略命名空间,如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using namespace std;
cin;
cout;

命名空间还可以嵌套

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
namespace yyt{
    namespace std{
        istream cin;
        ostream cout;
    }
}
....
yyt::std::cin;

对于本文件的全局变量,可以使用匿名命名空间访问成员,如

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<iostream>
namespace eetal{
    int a = 10;
}
int a = 5;
int main(){
    int a = 3;
    std::cout<<a<<endl;//3
    std::cout<<::a<<endl;//5
    std::cout<<eetal::a<<endl;//10
    return 0;
}

文件IO

文件IO需要通过引入头文件fstream

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#inlcude<fstream>
//输出流ofstream
ofstream outPutStream;
outPutStream.open("test.txt");//will clear old content
outPutStream.write("aaas",4);//writer max 4 characters
outPutStream.flush();
outPutStream.close();

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//输入流ifstream,
 ifstream inputStream;
 inputStream.open("test.txt");
 char str[5];
 inputStream.read(str,4);//read max 4 characters
 inputStream.close();

array和vector初探

array是有界的,vactor无界(自动增长),并且可以直接像数组一样使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<array>
#include<vector>

int size = 5;
vector<double> doublevWithSize(size);//size is a variable
array<int,5> array1;//cannot use variable the size must is const
doublevWithSize[0] = array1[0];
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 歪歪梯Club 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
☺初识c++(语法篇)☺
这时如果访问ne内的a:可以ns::ne::a;或者可以不完全展开即 using namespace ns::ne。
羑悻的小杀马特.
2025/01/23
590
☺初识c++(语法篇)☺
什么?C/C++面试过不了?因为你还没看过这个!
(为了方便记忆可以想成)被 const 修饰(在 const 后面)的值不可改变,如下文使用例子中的 p2、p3。
杨源鑫
2020/06/04
3.7K0
C++入门
C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式 等。熟悉C语言之后,对C++学习有一定的帮助,本章节主要目标: 1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用 域方面、IO方面、函数方面、指针方面、宏方面等。 2. 为后续类和对象学习打基础
绝活蛋炒饭
2024/12/16
1300
C++入门
《逆袭进大厂》之C++篇49问49答
,这些都是我自己整理的秋招笔记,一把屎一把尿慢慢总结出来的那种,这些笔记可以说对我帮助良多。
DeROy
2021/02/05
2K0
《逆袭进大厂》之C++篇49问49答
C++初阶-入门基础语法
2. 使用C++输入输出更方便,不需增加数据格式控制,比如:整形--%d,字符--%c
用户9645905
2022/11/30
7330
C++初阶-入门基础语法
【C++】——入门基础知识超详解
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
小李很执着
2024/06/15
1430
【C++】——入门基础知识超详解
手撕C++入门基础
在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
凯子坚持C
2024/09/23
1430
手撕C++入门基础
C++入门基础,看这篇就足够了!
C++是在C语言的基础上,又容纳了许多面向对象的编程思想,并增加了许多有用的库,以及编程范式,如果以及学习C语言后,对C++的学习也是很有帮助的。 C++补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用域方面,IO方面,函数方面,指针方面,宏方面
Yui_
2024/10/16
5080
C++入门基础,看这篇就足够了!
【C++】C++入门必备知识详细讲解
首先我们先要知道,C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库。本章将会带大家了解,C++是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。
YoungMLet
2024/03/01
1570
【C++】C++入门必备知识详细讲解
C++入门
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
waves浪游
2024/11/01
1160
C++入门
【C++】Chapter 0:当你学习C++之前首先需要了解的
C 与 C++ 的关系可以概括为:C++ 是 C 语言的超集(C with Classes),即 C++ 兼容大部分 C 语法,但提供了更多高级特性。它们之间的关系主要体现在以下几个方面:
Skrrapper
2025/02/20
1030
【C++】Chapter 0:当你学习C++之前首先需要了解的
C++入门必备知识(你真的入门C++了吗?)
注:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。
利刃大大
2023/04/12
5060
C++入门必备知识(你真的入门C++了吗?)
一文掌握C++基本语法
1. C++关键字 2. 命名空间 变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。 使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。 2.1 命名空间定义 使用namespace关键字,后面跟命名空间的名字,然后用{}将成员括起来即可,和C语言的结构体类似 存在多个相同的命名空间的时候,编译器编译的时候会把他们合并,如下面 命名空间可以嵌套 PS:命名空间定义
老九君
2022/05/16
2.1K0
一文掌握C++基本语法
C++第二弹 -- C++基础语法下(引用 内联函数 auto关键字 范围for 指针空值)
C++11 标准的发布带来了许多新的语言特性,这些特性极大地提升了 C++ 的开发效率和代码质量。本文将深入探讨 C++11 中几个重要的特性,包括 引用、内联函数、auto 关键字、基于范围的 for 循环以及指针空值 nullptr。
用户11317877
2024/10/16
1300
C++第二弹 -- C++基础语法下(引用 内联函数 auto关键字 范围for 指针空值)
【C++】——入门基础知识
C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。熟悉C语言之后,对C++学习有一定的帮助: 1. 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用 域方面、IO方面、函数方面、指针方面、宏方面等。 2. 为后续类和对象学习打基础。
小李很执着
2024/06/15
1340
【C++】——入门基础知识
C++复习篇
2.指针const 1) 底层const(位于*左侧) const int *p : const修饰*p为常量,也就是说该指针指向的对象内容是个常量,只能改变指向的地址.但是可以通过其他方式修改对象内容 例如:
诺谦
2019/05/24
1.4K0
C++入门(下)
呀哈喽,我是结衣 今天我们的目标就是连接上一篇博客继续来讲C++的新事物,再剧透一下我们下一篇博客就是C++的类和对象了,这可是相当让人伤脑筋的东西啊。好了,今天的干货要来了哦~ 我们的C++入门都是以C++11为标准的哦。
Yui_
2024/10/15
880
C++入门(下)
C++打怪升级(三)- 内联函数 、auto、范围for循环
在C语言中,我们通常会把完成特定功能的代码封装为一个函数,这样的函数可能完成者复杂的功能从而具有较多的代码长度,同时也有着许许多多的只完成简单功能的函数,这些函数内部通常只有几行代码。 比如: 完成交换功能的函数
怠惰的未禾
2023/04/27
5420
C++打怪升级(三)- 内联函数 、auto、范围for循环
我的C++奇迹之旅:内联函数和auto关键推导和指针空值
内联函数是一种编译器优化技术,它可以将函数的代码直接插入到函数调用的地方,而不是通过函数调用的方式。这样可以减少函数调用的开销,提高程序的执行效率。
学习起来吧
2024/04/09
2140
我的C++奇迹之旅:内联函数和auto关键推导和指针空值
C++入门
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这
Jamo
2024/01/28
2120
C++入门
相关推荐
☺初识c++(语法篇)☺
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验