c++一些记录

typedef和#define

看到变量类型的wchar_t 时,说到宽字符实际上是这么来的,typedef short int wchar_t;
了解typedef的时候看到了#define

typedef

在C/C++语言中,typedef常用来定义一个标识符及关键字的别名,它是语言编译过程的一部分,但它并不实际分配内存空间,实例像:

typedef int INT;
typedef int ARRAY[10];
typedef (int*) pINT;

typedef可以增强程序的可读性,以及标识符的灵活性,但它也有“非直观性”等缺点。

#define

#define为一宏定义语句,通常用它来定义常量(包括无参量与带参量),以及用来实现那些“表面似和善、背后一长串”的宏,它本身并不在编

译过程中进行,而是在这之前(预处理过程)就已经完成了,但也因此难以发现潜在的错误及其它代码维护问题,它的实例像:

#define INT int
#define TRUE 1
#define Add(a,b) ((a)+(b));
#define Loop_10 for (int i=0; i<10; i++)

typedef与#define的区别

从以上的概念便也能基本清楚,typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名),而#define原本在C中是为了定义常量
为了尽可能地兼容,一般都遵循#define定义“可读”的常量以及一些宏语句的任务,而typedef则常用来定义关键字、冗长的类型的别名。

宏定义只是简单的字符串代换(原地扩展),而typedef则不是原地扩展,它的新名字具有一定的封装性,以致于新命名的标识符具有更易定义变

量的功能。比如:

typedef (int*) pINT;
以及下面这行:
#define pINT2 int*

效果相同?实则不同!实践中见差别:pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。

https://blog.csdn.net/boiled_water123/article/details/100184251
https://blog.csdn.net/superhoy/article/details/53504472

关于全局变量和局部变量的初始化问题

c++一些记录
虽说全局会自动,但还是一定记得定义和初始化全局局部变量就对了,别忘了初始化变量,,参考

命名空间namesapce

经常见到using namespace std,啥意思?
命名空间旨在解决不同文件、不同库下的名字冲突问题,就像常见的文件管理系统一样,不同文件夹下允许存在同名文件。
因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。

namespace namespace_name {
   // 代码声明
}

#include <iostream>
using namespace std;
 
// 第一个命名空间
namespace first_space{
   void func(){
      cout << "Inside first_space" << endl;
   }
}
// 第二个命名空间
namespace second_space{
   void func(){
      cout << "Inside second_space" << endl;
   }
}
int main ()
{
 
   // 调用第一个命名空间中的函数
   first_space::func();
   
   // 调用第二个命名空间中的函数
   second_space::func(); 
 
   return 0;
}

使用命名空间别名
可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。如
namespace Television //声明命名空间,名为Television
{ … }
可以用一个较短而易记的别名代替它。如:
namespace TV=Television; //别名TV与原名Television等价
也可以说,别名TV指向原名Television,在原来出现Television的位置都可以无条件地用TV来代替。

using指令

using后面的命名空间成员名必须是由命名空间限定的名字。例如:
using nsl::Student;
以上语句声明:在本作用域(using语句所在的作用域)中会用到命名空间ns1中的成员Student,在本作用域中如果使用该命名空间成员时,不必再用命名空间限定。例如在用上面的using声明后,在其后程序中出现的Student就是隐含地指nsl::Student。
using声明的有效范围是从using语句开始到using所在的作用域结束。如果在以上的using语句之后有以下语句:
Student studl(101,”Wang”,18); //此处的Student相当于ns1::Student
上面的语句相当于
nsl::Student studl(101,”Wang”,18);

如果是using namespace xxx,则是遇到同该xxx命名空间下所有的变量、函数等都隐含了不用在写前面的命名空间名则默认选取该命名空间下的变量、函数、类等
还有嵌套的命名空间等,可见下:

https://www.runoob.com/cplusplus/cpp-namespaces.html

[C++]static和const区别、以及static const

#include<bits/stdc++.h>
using namespace std;
class testClass{
	public:
		static int _datai;//不能在类内初始化 
		const int _dataj=2; //可以在类中声明常量成员 必须初始化 (c++11实现,之前不能进行初始化)
		enum{_datak=3};     //(c++11之前可以用枚举类型实现常量成员)
		static const int _datac=4;//定义静态常量成员 
}; 
int testClass::_datai=1; //对于static成员变量只能在类外初始化 


int main(){
	testClass a;
	testClass b;
	cout<<"对象a调用常量成员:"<<a._dataj<<endl; //2
	cout<<"对象a调用枚举常量:"<<a._datak<<endl;//3 
	cout<<"对象a调用静态常量成员:"<<a._datac<<endl;//4 
	
	cout<<"对象a调用静态成员:"<<a._datai<<endl; //1
	b._datai=5;
	cout<<"对象a再次调用静态成员:"<<a._datai<<endl;  //5
	
	cout<<"类名调用静态成员:"<<testClass::_datai<<endl;//1     
	cout<<"类名调用静态常量成员:"<<testClass::_datac<<endl;//4
}

类的静态成员确实很牛,不管是否实例化都已经存在于内存中可以通过类名::静态成员直接调用,如果实例化了,相当于另起炉灶。
static变量还有内部链接性质,和外部链接性(当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性)相对
没有this指针,和python的静态函数没有self感觉差不多嘛

  1. static

    static局部变量 将一个变量声明为函数的局部变量,那么这个局部变量在		函数执行完成之后不会被释放,而是继续保留在内存中,因此其值在下次调用时仍维持上次的值;
    static 全局变量 表示一个变量在当前文件的全局内可访问
    static 函数 表示一个函数只能在当前文件中被访问
    static 类成员变量 表示这个成员为全类所共有
    static 类成员函数 表示这个函数为全类所共有,而且只能访问静态成员变量,且因为可以通过类名直接调用,几乎就是全局函数但仅限于当前文件。
    
  2. const

const 常量:定义时就初始化,以后不能更改。
const 形参:func(const int a){};该形参在函数里不能改变
const修饰类成员函数:该函数对成员变量只能进行只读操作

3.static const 或者 const static
性质同const 且加上static的性质,且可以在类声明中初始化。比如可以通过类名调用。

https://blog.csdn.net/wangjianxin97/article/details/88788099
https://blog.csdn.net/wangjianxin97/article/details/89316081

上一篇:C. Maximize the Intersections


下一篇:《Codeforces Global Round 16》