C++相关问题笔记(一)

目录

1. fstream中读取文件结束标志问题:

2. 关于数组定义时大小用变量的问题:

3. 读取文件时文件格式问题

4. 全局变量及命名空间中的全局变量

5. acos输入要求及输入精度问题

6. Win32中内存复制错误

7. C++贝塞尔函数

8. C++多线程中使用随机数需注意


1. fstream中读取文件结束标志问题:

 eofbit:当文件中所有数据均被读取完毕且再次读取一次发现无数据时才为TRUE,即eofbit标志
上一次读取文件的操作是否失败
。当读取完最后一个数据时,此时eof()仍返回TRUE,只有再进行
一次读取操作,eofbit才置位,eof()才返回TRUE

EOF:文件最后一个数据的下一个位置为EOF数据,可通过peek()来判断下一个数据是否为EOF来判断文件是否读取结束,此方法更好

peek():预读文件下个位置的数据,但不影响文件内容,用此判断文件读取结束更好

正常读取结束

判断的文件数据数量比实际数量多1,用eof()进行判断应在读取之后,判断数据个数应在eof()之后

2. 关于数组定义时大小用变量的问题:

在项目属性里设置,这会在整个项目里生效,依次选择:属性->配置属性->C/C++ ->预处理器->预处理器定义

最后面直接加上:_CRT_SECURE_NO_WARNINGS

_CRT_SECURE_NO_WARNINGS此类警告非C++官方定义,而是VS内部自行定义的,VS认定某些方法存在安全隐患,故而设置此种不安全警告,通过上述方法可以取消此种警告

VS中在项目配置中修改预处理器限制,可实现

int a=10; int b[a];

此类代码,并且可正常运行相关程序。但此种用法与C++标准相违背,C++标准中在上述情况下数组大小不允许使用变量。此种方法为gcc相关扩展。

C++中数组使用栈内存,堆栈均在运行时分配内存,但栈大小有限,若使用变量,无法提前确定栈大小,变若量大小超出限制则栈空间不足,会导致数据覆盖的问题;常量大小有助于编译时确定栈大小。因此,不建议使用上述方法,动态数组使用动态分配即可,上述情况知道就行。

详细可参照:http://t.csdn.cn/vjfn9

3. 读取文件时文件格式问题

读取文件的方法有很多,但是需注意,在读取时一定要注意文件内容的存放格式,若为通常UTF-8,则无问题,但如果文件的内容是从其他软件复制过来,则可能会出现数据存放类型不同,从而导致使用UTF-8类型读取的代码无法正确读取其他类型的数据。(此时数据在txt中的显示均正常)如:

正常情况输出到文件中的存储类型(编码方式)为UTF-8,此时可正常读取

 

此处举例为matlab中复制过来的数据,编码为UTF-16 L,此时便无法正常读取

若文件中数据为matlab中直接写入文件,则类型相同,此处应该是显示时的格式不同,从而导致复制的结果格式也不同

注:文件路径中有中文时,打开文件可能会失败

4. 全局变量及命名空间中的全局变量

全局变量的定义建议放于cpp中(防止使用时出现重定义问题,放头文件中往往被包含不止一次,若头文件只被包含一次,则无问题),使用时需注意,全局变量的定义只能存在一份,而声明可以由多份

// a.cpp
int a = 1; // 定义

// b.cpp
extern int a; // 声明

// c.cpp
extern int a; // 声明

命名空间中的全局变量声明及定义与正常(全局命名空间下)的全局变量定义及声明使用方式相同,只不过相关代码需写在相关命名空间中

// a.cpp
namespace tjz
{
    int a = 1;
}

// b.cpp
namespace tjz
{
    extern int a;
}

5. acos输入要求及输入精度问题

 acos要求输入数据范围为[-1, 1],但在某些情况下入数据可能非常接近1或-1但精度上不是(例如:1.000000000457,此时输出结果在未显示多位小数情况下是1),从而导致结果计算错误显示nan。

此种问题不一定是中间计算过程有误,可能为精度导致的结果偏差从而使输入与-1和1不匹配。此时若确定输入无误只有精度问题时,可使用fmaxl和fminl或其他方法修改输入数据使数据保持在[-1, 1]之间。

其余函数可能存在类似问题,故在此提供一种思想。 

6. Win32中内存复制错误

VS中若一数组或vector数据过大,则在Win32环境下内存中会出现复制错误,此时应更换为x64环境。(项目中遇见3G大小数据复制出现问题)

7. C++贝塞尔函数

相关贝塞尔函数存在于cmath头文件中,且输入类型不存在复数类型

第一类贝塞尔函数:

double cyl_bessel_j(double nu, double x);

float cyl_bessel_jf(float nu, float x);

long double cyl_bessel_jl(long double nu, long double x);

第一类修正贝塞尔函数:

double cyl_bessel_i(double nu, double x);

float cyl_bessel_if(float nu, float x);

long double cyl_bessel_il(long double nu, long double x);

 第二类贝塞尔函数:

double cyl_neumann(double nu, double x);

float cyl_neumannf(float nu, float x);

long double cyl_neumannl(long double nu, long double x);

第二类修正贝塞尔函数:

double cyl_bessel_k(double nu, double x);

float cyl_bessel_kf(float nu, float x);

long double cyl_bessel_kl(long double nu, long double x);

8. C++多线程中使用随机数需注意

基本随机数使用方式:

#include <ctime>

int main()
{
    srand((unsigned)time(NULL));
    // srand()中设置随机数种子,从而使得rand()中获得的随机数序列不同,种子默认为1
    // 故若不设置随机数种子,rand()函数每次获得的随机数序列相同
    // 一般采用当前系统时间作为种子,从而确保每次种子均不同
    // 采用srand(time(0))写法相同
    
    int ra = rand() % 10;
    return 0;
}
  • srand()在使用时一般只使用一次即可满足后续对随机数的需求,time的单位为1s
  • 若使用多次,则当程序运行速度过快时,在1s内重复执行多次srand函数,重新赋予相同种子,则会导致每次的随机数相同
  • 故一般应确保srand函数只运行一次

 多线程中随机数使用方式:

#include <ctime>
#include <thread>

void xiancheng()
{
    srand(time(0));
    int ra = rand() % 10;
}

int main()
{
    thread th1(xiancheng);
    return 0;
}
  • 多线程中,srand需在每个线程内部重新使用
  • 在主线程中使用srand不会对子线程有影响,此时若子线程直接调用rand则相当于未调用srand,主线程中的srand只对主线程中rand起作用,每个子线程均需重新调用srand

多线程中多子线程随机数种子相同解决方案:

#include <ctime>
#include <thread>
#include <windows.h>

void xiancheng()
{
    LARGE_INTEGER nStartCounter;
	QueryPerformanceCounter(&nStartCounter);
	srand((unsigned)nStartCounter.LowPart);
    int ra = rand() % 10;
}

int main()
{
    thread th1(xiancheng);
    thread th2(xiancheng);
    thread th3(xiancheng);
    return 0;
}
  • 多子线程随机数种子相同的原因是:多个线程在1s内同时产生从而导致time(0)读取到相同的时间 
  • time(0)单位为1s,故而使用毫秒或微秒级的时钟即可解决此类问题,上诉代码只是一种方案,其余能获得更高精度时钟的方法具有相同效果

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tjz_jlu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值