C/C++走过的坑

1.有符号int与无符号int比较

#define TOTOL_ELEMENTS (sizeof(a) / sizeof(a[0]) );

int main()
{
	int a[] = {23,24,34};
	int d = -1;
	if(d<=TOTOL_ELEMENTS)
		printf("TRUE\n");
	else
		printf("FLASE\n");

	return 0;
}

//结果是FLASE而不是TRUE

结果分析:sizeof() 返回的是无符号整型,因此上述代码中TOTOL_ELEMENTS 的值是unsigned int类型。与 if  语句中signed int 型的 d 比较,signed int 型会被转化成unsigned int  型变量。

-1会转化成一个非常巨大的数---65535

*************************************************************

原码、反码、补码:

原码:二进制定点表示法,即最高位是符号位。0为正,1为负。

反码:正数的反码与原码相同;负数的反码是对其原码逐位去反,符号位除外。

补码:正数的补码与原码相同;负数的补码是在其反码末位上加1。

在计算机中,数值一律用补码存储,因为其能将符号位与数值统一处理。

********************************************************************

以int型的-1为例:

-1是负数,原码为  10000000 00000001   (int为2字节)

反码为       11111111 11111110

补码为       11111111 11111111

那么有符号怎么转化成无符号的呢?直接取绝对值的补码就行了。算术解决: |a|*2-|a| = 无符号的a

int a = -1;

(unsigned int)a= ?

(1)先取-1 的绝对值1的原码  00000000 00000001

(2)将其转化为反码              01111111 11111110

(3)对所求的数+1得到补码。补码就是无符号char的a值,转换为十进制数为65535

所以(unsigned int)a=65535;

另外,注意:printf函数输出的是无符号的值!!

附:(转)C语言符号扩展知识讲解http://blog.csdn.net/u010069213/article/details/24012649

2.位域变量 的符号问题

#include <stdio.h>

struct data
{
	int flag: 1;//;或者,都是允许的
	int other: 31;
};

int main()
{
	struct data test;
	test.flag = 1;
	if (test.flag == 1)
		printf("test.flag =1,it is true\n");
	else
		printf("test.flag !=1,it is flase\n");

	return 0;
}

  输出:test.flag !=1,it is flase

分析:flat 是 int型的位域变量,用一个bit来表示int时,这一位是用来表示符号位的,带符号的一个bit的位域变量的取值范围是0或者-1(无符号的一个bit的位域变量的取值范围是0或者1)!!

当1赋值给test.flag时候,test.flag溢出,变为 -1......

将结构体改为一下代码即可:

struct data
{
	unsigned int flag: 1;//;或者,都是允许的
	int other: 31;
};

  

3.整除的精度问题

int main()
{
	float result;
	result = 1/6;
	printf("result= %f\n",result);
	return 0;
}

  输出: 0

分析:1和6都是整型变量,两个整型变量结果依然是整型,不会保留整数部分。(毕竟是先运算再等号的)

修改:把 1 或者 6 的至少一个改为浮点类型表示即可!

在C语言中存在隐式类型转换:

(1)赋值时一律是右边值转化为左边,但是右边是表达式时,会先进行运算,然后才对运算的结果进行数据类型转换。

(2)当不同类型的变量进行计算时,遵循由低级向高级转换原则。如:char-->int  ,short-->int , float -->double。。。。

4.浮点数的比较精度问题

int main()
{
	float f = 1.0/3.0;
	float expect_f = 0.333333333;
	double d = 1.0/3.0;
	double expect_d = 0.333333333;
	printf("f = %f, expect_f = %f, d = %lf, expect_d = %lf\n",f,expect_f,d,expect_d );
	if (f==expect_f && d == expect_d)
		printf("equal!!\n");
	else
		printf("not equal!!!\n");
}

  输出:

f = 0.333333, expect_f = 0.333333, d = 0.333333, expect_d = 0.333333
not equal!!!

分析:浮点数表示精度的位数有限,不能准确表示一个小数(IEEE754规定:单精度的float数据类型7位有效数字,double16位有效数字)

=====》浮点数比较时,一般比较他们之间的差值在一定范围内

将 if 的条件部分改为以下:

if (fabs(f-expect_f)<0.000001 && fabs(d == expect_d)<0.000001)
		printf("equal!!\n");

  

5.最小整数取相反数溢出

int main()
{
	int a = 0xffffffff;
	if(a<0)
		a = -a;
	printf("a =%d \n",a);

	return 0;
}

  结果:a = 1

分析:有符号的数据类型,有正负之分,如int,double,float...溢出后去反,得到a = 1

解决:对int数据类型进行去反处理时候,需要额外处理这种情况,添加以下代码:

else if (a == 0xffffffff)
	printf("a = %d\n",a );

  

6.临时变量溢出问题

long multiply(int m,int n)
{
	long score;
	score = m*n;
	return score
}

  分析:m,n的相乘结果会先存储在一个临时的int变量中,然后再赋值给long变量score,这个临时变量容易溢出。所以在表达式运算前需要对m和n进行数据转换。

(64位平台,int 4bit, long 8bit--------------也不排除一些装了一些32位的软件,比如Dev-C++

32位平台,int 4bit,long 4bit)

无论怎样:一定要注意数据溢出问题!!

7.区分continue与return

return 用来返回某个值并退出程序;

continue  用于循环中,结束本次循环

8.指针常量与常量指针

指针常量:指针在常量前面。int *const 指针名 -------------指针本身是常量,它指向的地址不可以改变,但是地址内的数据可以根据指针的解引用改变!!

常量指针:常量在指针前面, const  int *指针名 -----------指向常量的指针,顾名思义,指针指向常量,不可以指向变量!所以不能通过改变指向地址的内容!!,但是指针自身不是常量,自身的值可以改变,即指向哪个常量是可以改变的! 

int main()
{
	int a =2;
	int b =4;
	int *const pa = &a;  //指针常量,只能改变地址内的内容
	const int *pb = &b;   //常量指针,只能改变地址

	std::cout<< *pb <<endl;
	std::cout<< *pa <<endl;

	pb=pa;
	std::cout<< *pb <<endl;

	*pa = 343;
	std::cout<< *pa <<endl;

  输出:4 2 2 343

正确!!

9.字符数组和指针不总是相等的

在不同文件用extern引用的时候,字符数组和指针不是相等的!!

************************************************

不可以在a.cpp中:

char a[]="Hello world!";

然后在b.cpp中:

extern char *a; //WRORG

***********************************************

10.cin>>和 getline 混用导致的奇怪问题

cin  是c++标准输出流istream类型的对象,代表标准输出设备,相当于c中的stdin。程序中包含iostream头文件既可以使用 cin对象。istream类重载了抽取操作符">>",能够读取C++中的各种基础数据类型,抽取符“>>”根据后面变量的类型读取数据,从非空白符号开始没遇到Enter,Space,Tab结束

std::getline函数从istream中读取一行数据  遇到“\n”结束

#include <iostream>
using namespace std;

int main()
{
	int a;
	string b;
	cout<< "Please input a:"<<endl;
	std::cin>> a;
//	cin.ignore();   //默认cin::ignore(1,EOF)

	cout<< "Please input b:"<<endl;
	std::getline(cin,b);

	cout<< "a:"<<a <<endl;
	cout<< "b:"<<b<<endl;

	return 0;

}

  输出:b 的 值无法输入

解决:将注释那句激活

提醒:输入/输出 语句用一种就好了,不要混用

时间: 2024-08-04 00:54:58

C/C++走过的坑的相关文章

记录一次升级https走过的坑

记录一次升级https过程中走过的坑 curl: (51) SSL: certificate subject name 'mp3.xxx.com' does not match target host name 'static.xxx.com' 升级 http://mp3.xxx.com http://static.xxx.com 为 https://mp3.xxx.com https://static.xxx.com 因在一台服务器上配置的两个域名都解析到本机,配置完后,发现页面的静态文件都无

阿里云centos7.2 搭建 laravel 框架走过的坑

centos7.2 搭建 laravel框架走过的坑 前言 公司正在处于发展阶段最近开发的伙伴和运维的伙伴一直在忙碌着 开发人员一直在写laravel架构的代码以及新项目的拓展,时间很赶所以作为linux运维的我也不能怠慢. 首先搭建lnmp架构 nginx php 我选择的yum,wget的安装方法 mysql选择编译安装 因为我只认为MySQL我还有编译安装的需要(熟悉熟悉). 准备 : 1.PHP 7版本  2.openssl(yum安装)3.pdo扩展 mysql 4.安装compose

Appium 走过的坑( Mac+java )--Apple 篇

最近随着手机测试盛行,经朋友推荐,selenium的新家庭成员Appium算比较好用的一款自动化手机测试工具.本想,selenium出的东西都是好东西,IDE-->RC-->WebDriver-->PhantomJS,个个都是好东西,当然其中有些不适selenium做的,算半个推荐,但真心不错,那这个Appium也不会差吧...抱着试试的心态,开始了踏坑之旅.下面就让我描述下我走过的坑: 首先先说下环境: Mac pro (OS X 10.10.3) Java (1.6 , 后续会介绍怎

Appium 走过的坑( Mac+java )--Android 篇

Apple的坑走完后,终于打开了界面,想想还是有点小激动的,然后进入了更坑的Android环境搭建. 如果你以为这环境就和Apple这样easy能解决(虽然不少坑 - -),那就大错特错,android环境等于另外一套东西,比Apple难弄多了,机制也很傻... 牢骚话少说,咱们来跨坑,第一个坑随即而来,之前我在说Apple环境时,下载安装完appium工具,Apple环境自动已经完善(前提是你已经安装完xcode).那么android环境应该怎么配置呢? 我就绕过我求寻真理的沼泽了,直接说怎么

最近走过的坑 :slf4j 多个实现 hibernate 类型转换异常 bean依赖问题

最近走过的坑 slf4j 多个实现 主要是maven依赖中存在多个slf4j的实现类,在引入的依赖中排除对应的依赖就可以 <dependency> <groupId>xxxxxx</groupId> <artifactId>xxxxxx</artifactId> <version>1.0.0</version> <exclusions> <exclusion> <groupId>org.

UWP 走过的坑

一切源于项目选择了一个WIN10的PAD. 采用了WPF,WEB制作对应功能的软件,用户交互都不理想. 最后,选择了UWP.最终证明效果是完美的,虽然走过很多伤心的坑... 1.安装UWP的开发环境.是的,他需要WIN10系统.试过虚拟机,系统升级后就挂.后改用实体机,环境搭建OK ,这个过程持续了2周,心累. 2.开发UWP界面,有WPF的基础上手很快. 3.开发功能,项目需要用串口,采用微软提供的串口通讯实例,在打开串口后,通信不正常.单步调试进去查看 SerialPort ( Serial

微信公众平台开发,那些走过的坑

最近接手了一个微信公众平台的项目,历时两个月,基本完工,终于有时间可以总结一下这过程当中遇到的点点滴滴. 1.关于微信的内置浏览器 开始以为,微信内置浏览器是一个浏览器,对于安卓机和苹果机都是一样的,后来发现不是,苹果机和安卓机的内核是不一样的,所以前端设计过程中一定要考虑浏览器的兼容问题.苹果机的微信内置浏览器也并不是纯粹的safri内核,微信有自己的处理,比如,safri并不支持h5的audio,但苹果机的微信内置浏览器是支持的.最坑的一点,是苹果机的语音播放,调了很久,因为苹果机是不允许在

【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studio默认采用的却是gradle方式,与ADT编辑的方式大不相同,那再andorid studio中如何导入so文件呢? 在android studio 中我们可能会用到jar包和so文件的方式,对于jar包可能接触更多,只需要我们把工程转换为project显示方式,打开app下的libs文件夹,导入即

创业那些年,我们一起走过的坑

怎么开头呢,这个问题我想了许久...... 大家都知道,我是个粗人.文人笔下的"落霞与孤鹜齐飞,秋水共长天一色",我只能说:卧槽,好看,这是何等的卧槽! 本人家穷人丑,农村户口,没啥拿得出手的简历.开头跳过了,讲一下我们这些年创业遇到的那些坑,以及个人的见解. 第一:试运营 方向不对,努力白费,这是我花了五十万买出来的教训.在考察一个项目的时候,往往会走到一个死胡同里面.套路如此深的互联网上,预埋着无数的大坑.这个时候满怀激情,太容易冲昏头脑.尤其是第一次创业的时候,很多想法是不成熟的

关于使用echarts走过的坑(同grid多图、多轴系列)

相信大家在工作中,经常会用到echarts,今天我说下我在工作中浪费时间较长的坑 先来看看我的终极需要实现的图吧: 相信以上效果对于常用的小伙伴来说并不困难, 在此我只说option的配置,关于数据,就不在此赘述了,毕竟大家的情况都不太相同,处理就起来也不太一样. option : { grid: [{ left: '20%', right: 50, height: '35%' }, { left: '20%', right: 50, top: '55%', height: '35%' }],