【C/C++】 学习

【C/C++】 学习

  • C
    • GNU、MinGW\Cygwin、GCC、gcc\g++、
    • 程序可在DEV-C++调试,但不能在VC调试
    • 表达式必须含有常量值变量 -- 变量 "length" (已声明 所在行数:13) 的值不可用作常量
    • 然而run code后,length会影响程序的运行
  • C++ 高级技巧
    • 变量命名
    • 类的深入
    • 函数重载(overload)和函数重写(override)的基本规则
      • 函数重载
      • 函数重写
    • C++程序的性能调优

C

GNU、MinGW\Cygwin、GCC、gcc\g++、

  1. GNU是什么
    1990年,GNU计划已经开发出的软件包括了一个功能强大的文字编辑器Emacs 。GCC(GNU Compiler Collection,GNU编译器集合),是一套由 GNU 开发的编程语言编译器。以及大部分UNIX系统的的程序库和工具。唯一依然没有完成的重要组件就是操作系统的内核(称为HURD)。1992年Linux与其他GNU软件结合,完全自由的操作系统正式诞生。

    GNU 包含3个协议条款:

    1. GPL:GNU通用公共许可证(GNU General Public License)
      GPL v3的官方说明:http://www.gnu.org/licenses/gpl-3.0.html,GPL要求软件以源代码的形式发布,并规定任何用户能够以源代码的形式将软件复制或发布给别的用户, 如果用户的软件使用了受 GPL 保护的任何软件的一部分,那么该软件就继承了 GPL 软件,并因此而成为 GPL 软件,也就是说必须随应用程序一起发布源代码, GPL 并不排斥对自由软件进行商业性质的包装和发行,也不限制在自由软件的基础上打包发行其他非自由软件(没明白!)。

    2. LGPL:GNU较宽松公共许可证 (GNU Lesser General Public License )
      由于GPL很难被商业软件所应用,它要求调用它的库的代码也得GPL,全部开放,并且一同发布,不能直接连接。所以后来GNU推出了LGPL许可证。在GPL与LGPL许可证保护下发布源代码的结果很相似,对旧代码所做的任何修改,对于想知道这些代码的人必须是公开的,唯一真正的不同之处在于私人版权代码是否可以与开放源代码相互连接,LGPL允许实体连接私人代码到开放源代码,并可以在任何形式下发布这些合成的二进制代码。只要这些代码是动态连接的就没有限制(???)。(使用动态链接时,即使是程序在运行中调用函数库中的函数时,应用程序本身和函数库也是不同的实体)

    3. GFDL : GNU自由文档许可证(GNU Free Documentation License )的缩写形式。

  2. MinGW、cygwin是什么

    MinGW(Minimalist GNU For Windows)是个精简的Windows平台下的 C/C++、ADA及Fortran编译器,相比Cygwin (Cygwin是一个在windows平台上运行的类UNIX模拟环境,对于学习UNIX/Linux操作环境,或者从UNIX到Windows的应用程序移植,或者进行某些特殊的开发工作,尤其是使用GNU工具集在Windows上进行嵌入式系统开发,非常有用) 而言,MinGW体积要小很多,使用较为方便

    MinGW最大的特点就是编译出来的可执行文件能够独立在Windows上运行。
    MinGW是一个外壳(VISUAL IDE),编译工具是GCC.
    其实MinGW只是把gcc(g++ gdb等)封装一下,便于使用而已.
    综上来说,MinGW具有gcc的所有功能,并且支持几乎所有非类NIX特性的库函数.

    cygwin/gcc和MinGW都是gcc在windows下的编译环境,但是它们有什么区别,在实际工作中如何选择这两种编译器。
    cygwin/gcc完全可以和在linux下的gcc做等号,这个可以从boost库的划分中可以看出来端倪,cygwin下的gcc和linux下的gcc完全使用的是相同的Toolsets。
    所以完全可以和linux一起同步更新gcc版本,而不用担心问题,并且在cygwin/gcc做的东西(不用win32的)可以无缝的用在linux下,没有任何问题。是在windows下开发linux程序的一个很好的选择。但是在cygwin/gcc下编译出来的程序,在windows执行必须依赖cygwin1.dll,并且速度有些慢,如果不想依赖这个东西的化,必须在gcc的编译选项中加入-mno-cygwin。加入这个选项其实gcc编译器就会自动的选择在安装cygwin/gcc时安上的mingw,这个mingw就是gcc的一个交叉编译。
    对于mingw作为gcc在windows上的一个实现,不像cygwin的gcc在一个模拟linux上运行,同时相当一部分linux的工具不能够使用。

    根据以上的分析,如果在windows开发linux程序,cygwin是很好的选择。如果你开发的程序不介意有一个cygwin1.dll的话,也是可以选择cygwin的。如果你是想开发windows下的程序,还要必须用gcc的话,mingw是很好的一个选择

gcc和MinGW的异同
MinGW ,GNU 是什么

  1. gcc和g++的区别

    gcc与g++编译器的程序文件分别为:/usr/bin/g++和/usr/bin/gcc。

    gcc 和 GCC 是两个不同的东西,GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。gcc是GCC中的GUN C Compiler(C 编译器);g++是GCC中的GUN C++ Compiler(C++编译器)。

    首先需要强调一点,gcc与g++都可以编译C和C++源程序,对于.c文件gcc当做c语言处理,g++当做c++处理;对于.cpp文件gcc和g++均当做c++处理。C++是C的超集,但是两者对语法的要求标准是不一样的,C++对语法的要求更加严格一些,更加规则。

    • 预处理阶段,gcc与g++对.c和.cpp产生的效果是一样的,即该阶段两者都可以正常进行。

    • 编译阶段,g++实质上是调用的是gcc,因此在编译阶段两者是一样的,但是gcc程序不能自动将c++程序使用的库文件进行链接。在此阶段虽然不需要对库文件进行链接,但是同样需要识别C++使用的库文件,从而对库文件进行申明,因此gcc在编译阶段直接编译C++程序会报错。而g++可以成功编译生成汇编语言代码

    • 汇编阶段,都是利用as程序将汇编语言代码.s译为机器代码.o,因此也完全一样。

    • 链接阶段gcc无法将C++程序生成的.o文件转化为可执行程序,因为gcc程序不能自动将c++程序使用的库文件进行链接,而g++可以正常进行。

    因此,gcc与g++在执行C程序的过程中所做工作是一样的(g++调用了gcc来完成各项工作),都可以正常运行。gcc和g++的区别主要是在对cpp文件的编译和链接过程中,因为cpp和c文件中库文件的命名方式不同,g++既可以编译C又可以编译C++是因为g++在内部做了处理,默认编译C++程序,但如果遇到C程序,它会直接调用gcc去编译。

    extern "C"对于gcc和g++的效果是一样的。extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般之包括函数名。

     但是为了能够是gcc能正常完成C++的编译,需要在编译和链接阶段采用
     lstdc++参数,其余操作不变。g++的使用完全同gcc,只是不需要加- lstdc++参数,
     如: g++ -E hello.c -o hello.i    g++ hello.cpp -o hello       
     gcc -S -lstdc++ hello.ii -o hello.s(hello.ii是hello.cpp经过预处理产生的)     
     gcc -lstdc++ hello.cpp -o hello  
    

gcc编译器与g++编译器的区别

程序可在DEV-C++调试,但不能在VC调试

#include
#include

int main(){
     
	time_t t;        //声明time_t类型变量
    struct tm *start_time, *end_time;  //tm结构指针
    
	time (&t);//获取时间戳。  
    start_time = localtime (&t);//转为时间结构。  
    printf ( "%d\n", start_time);
//    printf ( "%d/%d/%d %d:%d:%d\n",lt->tm_year+1900, lt->tm_mon, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec);//输出结果  	

	int length = 100000;
	int evens[length/2];
	int j = 0, i;

	for(i=0;i<=length;i++){
     
		if (i % 2 == 0){
     
			evens[j] = i;
			j += 1;
		}
	}
	
	time (&t);
	end_time = localtime (&t);
	printf ( "%d\n", end_time);
	
	// for(i=0;i<=length/2;i++){
     
	// 	printf("%d ", evens[i]);
	// 	if(i % 10 == 0){
     
	// 		printf("\n");
	// 	}	
	// }
	
	printf("%d", end_time - start_time);
		
	return 0;
} 

问题描述
开始调试,终端显示以下警告

=thread-group-added,id="i1"
GNU gdb (GDB) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
.
Find the GDB manual and other documentation resources online at:
.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Warning: Debuggee TargetArchitecture not detected, assuming x86_64.
=cmd-param-changed,param="pagination",value="off"

进一步调试遇到以下错误

无法打开“cygwin.S”: 无法读取文件'c:\mingw810\src\gcc-8.1.0\libgcc\config\i386\cygwin.S' 
(Error: 无法解析不存在的文件"c:\mingw810\src\gcc-8.1.0\libgcc\config\i386\cygwin.S")。

经过查询,得知自己的数据结构有问题,由于有总规模大于10w的数组,程序爆栈(stack)了

解决方法
开全局变量(用堆(heap))

C++ 栈内存与堆内存小探究
VSCODE调试时在cygwin.S中发生段错误
vscode报错:无法打开“cygwin.S”:

表达式必须含有常量值变量 – 变量 “length” (已声明 所在行数:13) 的值不可用作常量

DEV-C++使用的编译器是GCC,它允许使用变量作为数组的长度定义数组。
VC的编译器不是GCC,它不允许你这样做。

方法1:使用动态内存分配,new和delete操作符

int num;
cin >> num;
int* a = new int[num];
…
delete[] a;

方法2:使用vector容器

int num;
cin >> num;
vector a(num);

注意:在为数组分配内存失败的时候,以上两种方法均会抛出异常bad_alloc

c++中使用关键字new来进行动态内存申请,它是基于类型进行的,使用关键字delete进行内存释放

1.变量申请

Type *p=new Type;
...
delete p;
//也可以进行初始化
//例如
int *p=new int(2);//动态分配一个int的空间并初始化为3

2.一维数组申请

Type *p=new Type[n];
...
delete[] p;
//例如
 
int *p=new int[5];
...
delete[] p;

3.二维数组申请

Type **p=new Type*[m];
//数组p[m][n];
for(int i=0;i

之前一直这样创建二维数组,然后使用memset将数组初始化为0,但是总是报错

int **edge = new int*[frame.rows];
for (int k = 0; k < frame.rows; ++k)
{
	edge[k] = new int[frame.cols];
}
memset(edge, 0, sizeof(edge));

做了修改后,这样写就不报错了,暂时还没有搞懂为啥,仅供参考吧,弄清楚之后再更新

int **edge = new int*[frame.rows];
for (int k = 0; k < frame.rows; ++k)
{
	edge[k] = new int[frame.cols];
	memset(edge[k], 0, sizeof(int)*frame.cols);

然而run code后,length会影响程序的运行

int length = 1036225; 时
程序可以执行完毕
int length > 1036225; 时
程序只能显示start_time,然后自动结束

why???

C++ 高级技巧

变量命名

【C++】关于以下划线开头的变量名

写程序千万不要_开头
系统头文件、宏名、变量名、内部函数大多数都是_开头
当变量是私有的时候,用_xxx 来表示变量是很好的习惯
Python_ 开始的成员变量叫做保护变量,意思是只有类对象和自类对象自己能访问到这些变量;而 __ 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据:

  • 以单下划线开头(_foo)的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用“from xxx import *”而导入;
  • 以双下划线开头的(__foo)代表类的私有成员;
  • 以双下划线开头和结尾的(__foo__)代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。

C

  • 以单下划线(_)表明是标准库的变量
  • 双下划线(__) 开头表明是编译器的变量
class InitParamSetting
{
     

	public:
		InitParamSetting();
		~InitParamSetting();
	
	public:	
		void ReadRegInfo();
		void WriteRegInfo();
		
		CString _localRecPath;//本地录像存放路径
		int _maxLocalRecTime;//最大录像时间(以分钟为单位)
		CString _capPicPath;//抓图存放路径
		CString _vedioWndLabel;//视频窗口标签
 
 };

类的深入

函数重载(overload)和函数重写(override)的基本规则

函数重载(overload)和函数重写(override)的基本规则

函数重载

需求点:
因为在一个程序中,会出现很多很多,完成的函数功能完全相同,而仅仅是函数的参数略有不同的情形。这时如果没有函数重载这个概念,那么开发人员恐怕就要为如何为功能完全相同的函数起不同的名而头疼了。

特点:

  • 同名不同参,即不同的参数类型,不同的参数个数,或者不同的参数顺序。
  • 函数返回值可以相同,也可以不相同。

应用场景:
类的构造函数、类的成员函数。

函数重写

需求点:
函数重写,亦称覆盖,是指子类重新定义父类中有相同名称和参数的虚函数,主要在继承关系中出现。

特点:

  • 重写函数和被重写的函数必须为virtual函数,函数必须完全一致。
  • 返回值相同,或者返回指针或引用,并且派生类虚函数返回的指针或引用的类型是基类中被替换的虚函数返回的指针或引用的类型的字类型。

应用场景:
为了水一下这篇博客的字数。

C++程序的性能调优

C++程序的性能调优

windows:Intel’s VTune , xperf(WINDOWS7 VC2008 SDK ), amd code analysis, Compuware’s Devpartner Performance Analysis Community Edition, GlowCode

WINDOWS下免费的性能分析工具:
Very Sleepy : http://www.codersnotes.com/sleepy/sleepy
Luke Stackwalker :http://lukestackwalker.sourceforge.net/
Shiny http://sourceforge.net/projects/shinyprofiler/
VSPTree: http://code.google.com/p/vsptree/
Timing:http://ravenspoint.wordpress.com/2010/06/16/timing/

C++程序的性能调优
c++ 性能分析工具

你可能感兴趣的:(笔记,c++)