實不相滿,C++關鍵字一直見,一直查,一直忘,繼續一直查,一直忘......
今天就總結下,今後再查也稍微快點,希望記住巴拉。能想到的先就這些哈,歡迎留言補充哦。
關鍵字如下:
同一个内存段可以用来存放几种不同类型的成员,但在每一瞬间只有一个成员起作用,其它的成员不起作用,即不同时都存在和起作用。
共用体变量中起作用的成员是最后一个存放的成员,在存入一个新的成员后,原有的成员就失去作用。
實例:
#include <iostream>
using namespace std;
union test
{
char mark;
long num;
float score;
}a;
int main()
{
cout<<sizeof(a)<<endl;//long 8
a.mark = 'b';
cout<<a.mark<<endl; // 输出'b'
cout<<a.num<<endl; // 98 字符'b'的ACSII值
cout<<a.score<<endl; // 输出错误值
a.num = 10;
cout<<a.mark<<endl; // 输出换行 非常感谢suxin同学的指正
cout<<a.num<<endl; // 输出10
cout<<a.score<<endl; // 输出错误值
a.score = 10.0;
cout<<a.mark<<endl; // 输出空
cout<<a.num<<endl; // 输出错误值
cout<<a.score<<endl; // 输出10
return 0;
}顯示:

有些变量的取值被限定在一个有限的范围内,那么可以使用枚举来列举变量的范围,从而限定变量。那么从0开始自动+1赋值,如果对于赋值的元素,后面的元素在此基础上开始+1赋值。
實例:
#include <stdio.h>
enum WeekDay
{
Monday = 1, //1
Tuesday, //2
Wednesday, //3
Thursday, //4
Friday = 10, //10
Saturday, //11
Sunday //12
}a,b,c,d;
int main(int argc, char *argv[])
{
a = Monday;
b = Friday;
c = Sunday;
printf("%p, %p, %p, %p\n",&a,&b,&c,&d);
printf("%d, %d, %d, %d\n",a,b,c,d);
return 0;
}顯示:

聯合應用:
//union和enum的使用
#include<iostream>
#include<cstring>
using namespace std;
class Token
{
public:
enum TokenKind { INT1, CHAR1, DBL1 };
TokenKind tok;
union TokenValue
{
char cval;
int ival;
double dval;
}val;
};
union number
{ /*定义一个联合*/
int i;
struct
{ /*在联合中定义一个结构*/
char first;
char second;
}half;
}num;
union
{
int i;
char x[2];
}a;
int main()
{
Token first_token;
first_token.tok = Token::INT1;
switch (first_token.tok)
{
case Token::INT1:
first_token.val.ival = 42;
break;
case Token::CHAR1:
first_token.val.cval = '1';
break;
case Token::DBL1:
first_token.val.dval = 3.14;
break;
default:
break;
}
num.i = 0x4241; //联合成员赋值
printf("%c%c\n", num.half.first, num.half.second);
num.half.first = 'a'; /*联合中结构成员赋值*/
num.half.second = 'b';
printf("%x\n", num.i);//以十六进制的方式输出
a.x[0] = 10;
a.x[1] = 1;
printf("%x %d", a.i,a.i);
return 0;
}extern 用于定义全局变量,extern 写在(变量名/函数)之前,代表可被其他文件使用,也可在其他文件里查找。
例如:1.cpp里的变量和函数,可以直接给2.cpp使用,不需要1.h进行连接。但在2.cpp里要extern显式声明。代表2.cpp里可以查找使用其他文件的变量,函数。
a.在1.h中聲明
#pragma once
int n=1;
int add(int,int);
b.在1.cpp中定義
#include <stdio.h>
int add(int i,int j)
{
return i+j;
}c.在2.cpp中引用
#include <stdio.h>
#include "1.h"
extern int n;
extern int add(int,int);
int main(int argc, char* argv[])
{
int m;
m=add(1,2);
printf("%d\n",m);//3
printf("%d\n",n);//1
return 0;
}1.靜態局部變量
int foo(){
//随着第一次函数的调用而初始化,却不随着函数的调用结束而销毁
//且只初始化一次,也就是你第二次调用foo(),不会继续初始化,而会直接跳过。
//静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0(局部变量不会被初始化);
static int i = 1; // note:1
//i就是在栈区分配了,会随着foo的调用结束而释放
//int i = 1; // note:2
i += 1;
return i;
}2.靜態全局變量
//note:3和note:4有什么差异呢?你调用foo(),无论调用几次,他们的结果都是一样的。也就是说在本文件内调用他们是完全相同的
//那么他们的区别是什么呢?文件隔离!
static int i = 1; //note:3
//int i = 1; //note:4
//文件隔離,如果在 a.c文件定義note3, 在b.c文件用 extern int i;會報錯找不到的,而note4就可以
int foo1()
{
i += 1;
return i;
}3.靜態局部函數
//file a.c
void fn()
{
printf("this is non-static func in a");
}
//file b.c
extern void fn(); //我们用extern声明其他文件的fn(),供本文件使用。
int main()
{
fn();
}
//但是若 static void fn() ,會報錯
//1.静态函数不能被其它文件所用;
//2.其它文件中可以定义相同名字的函数,不会发生冲突;
4.靜態數據成員
对于非静态数据成员,每个类对象(实例)都有自己的拷贝。而静态数据成员被当作是类的成员,由该类型的所有对象共享访问,对该类的多个对象来说,静态数据成员只分配一次内存。静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。
#include<iostream>
using namespace std;
class Rectangle
{
private:
int m_w,m_h;
static int s_sum;
public:
Rectangle(int w,int h)
{
this->m_w = w;
this->m_h = h;
s_sum += (this->m_w * this->m_h);
}
void GetSum()
{
//非静态成员函数可以任意地访问静态成员函数和静态数据成员;
cout<<"sum = "<<s_sum<<endl;
}
};
int Rectangle::s_sum = 0; //初始化
int main()
{
//4+4=8 static不佔用內存
cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
Rectangle *rect1 = new Rectangle(3,4);
rect1->GetSum();//12=0+3×4
cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
Rectangle rect2(2,3);
rect2.GetSum();//12+2×3=18 static僅僅初始化一次
cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;
return 0;
}顯示:

5.靜態成員函數
1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
2.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
3.静态成员函数不能访问非静态成员函数和非静态数据成员;
4.调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)
#include<iostream>
using namespace std;
class Rectangle
{
private:
int m_w,m_h;
static int s_sum;
public:
Rectangle(int w,int h)
{
this->m_w = w;
this->m_h = h;
s_sum += (this->m_w * this->m_h);
}
static void GetSum() //这里加上static
//静态成员函数不能访问非静态成员函数和非静态数据成员;
{
cout<<"sum = "<<s_sum<<endl;
cout<<"m_w= "<<m_w<<endl;//error
}
};
int Rectangle::s_sum = 0; //初始化
int main()
{
cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;//8
Rectangle *rect1 = new Rectangle(3,4);
rect1->GetSum();//0+3*4=12
cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;//8
Rectangle rect2(2,3);//12+2*3=18
rect2.GetSum(); //可以用对象名.函数名访问
cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;//8
Rectangle::GetSum(); //也可以可以用类名::函数名访问 18
return 0;
}顯示:

在 c/c++ 中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了 inline 修饰符,表示为内联函数。栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间。
代碼:
#include <stdio.h>
//函数定义为inline即:内联函数
inline const char* dbtest(int a) {
return (a % 2 > 0) ? "奇" : "偶";
}
int main()
{
int i = 0;
//内部的工作就是在每个 for 循环的内部任何调用 dbtest(i) 的地方都换成了 (i%2>0)?"奇":"偶"
//这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗
for (i=1; i < 100; i++) {
printf("i:%d 奇偶性:%s /n", i, dbtest(i));
}
}其次,因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义。因此,将内联函数的定义放在头文件里实现是合适的,省却你为每个文件实现一次的麻烦。
声明跟定义要一致:如果在每个文件里都实现一次该内联函数的话,那么,最好保证每个定义都是一样的,否则,将会引起未定义的行为。如果不是每个文件里的定义都一样,那么,编译器展开的是哪一个,那要看具体的编译器而定。所以,最好将内联函数定义放在头文件中。
1.類內斂
// 头文件
class A
{
public:
void Foo(int x, int y);
}
// 定义文件
inline void A::Foo(int x, int y){}2.實現關鍵字
关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。
inline void Foo(int x, int y); // inline 仅与函数声明放在一起,無作用
void Foo(int x, int y){}
void Foo(int x, int y);
inline void Foo(int x, int y) {} // inline 与函数定义体放在一起參考鏈接:
https://blog.csdn.net/yuyanggo/article/details/49819667
https://blog.csdn.net/majianfei1023/java/article/details/45290467
https://blog.csdn.net/m0_37433067/article/details/72510996