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 的 值无法输入

解决:将注释那句激活

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

C/C++走过的坑(基础问题篇)的更多相关文章

  1. php支付走过的坑(微信篇 包含h5支付和app支付 注册 秘钥 环境等等配置)

    支付这东西,说容易也容易,说难也难 代码这玩意还比较好说 但是 如果没有demo 直接去看官方文档 十有八九一脸懵逼 今天就整理一下 支付这块走过的坑 涉及 微信h5支付 支付宝h5支付 (api文档 ...

  2. php支付走过的坑(支付宝篇 注册 秘钥 环境等等配置)

    支付这东西,说容易也容易,说难也难 代码这玩意还比较好说 但是 如果没有demo 直接去看官方文档 十有八九一脸懵逼 今天就整理一下 支付这块走过的坑 涉及 微信h5支付 支付宝h5支付 (api文档 ...

  3. 【转】8年!我在OpenStack路上走过的坑。。。

    8年!我在OpenStack路上走过的坑... 摘要: 2010年10月,OpenStack发布了第一个版本:上个月,发布了它的第18个版本Rocky.几年前气氛火爆,如今却冷冷清清.Rocky版本宣 ...

  4. web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史

    秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...

  5. 记一次ftp服务器搭建走过的坑

    记一次ftp服务器搭建走过的坑 1.安装 ①下载 wget https://security.appspot.com/downloads/vsftpd-3.0.3.tar.gz #要FQ ②解压 ta ...

  6. javamail模拟邮箱功能发送电子邮件-基础实战篇(javamail API电子邮件实例)

    引言: JavaMail 是一种可选的.能用于读取.编写和发送电子消息的包 JavaMail jar包下载地址:http://java.sun.com/products/javamail/downlo ...

  7. 【Java面试】基础知识篇

    [Java面试]基础知识篇 Java基础知识总结,主要包括数据类型,string类,集合,线程,时间,正则,流,jdk5--8各个版本的新特性,等等.不足的地方,欢迎大家补充.源码分享见个人公告.Ja ...

  8. 安卓布局修改基础常识篇之TextView属性

    [天使]安卓布局修改基础常识篇之TextView属性 在修改布局xml文件时需要熟练掌握一些属性,以下是TextView也就是文本的属性:android:autoLink 是否自动链接网址或邮箱地址: ...

  9. SQLAlchemy 教程 —— 基础入门篇

    SQLAlchemy 教程 -- 基础入门篇 一.课程简介 1.1 实验内容 本课程带领大家使用 SQLAlchemy 连接 MySQL 数据库,创建一个博客应用所需要的数据表,并介绍了使用 SQLA ...

随机推荐

  1. 【转】appium_python_API文档

    1.contextscontexts(self): Returns the contexts within the current session. 返回当前会话中的上下文,使用后可以识别H5页面的控 ...

  2. 计数排序(Count Sort )与插入排序(Insert Sort)

    计数排序法:计数数组适用于当前数组密集的情况.例如(2,3,5,4,2,3,3,2,5,4) 方法:先找出最大值最小值,之后统计每个数出现的次数,根据次数从小到大往数组里添加 计数排序法是一种不需要比 ...

  3. Datable 排序

    if(dt.Columns.IndexOf("name") != -1) //存在这个字段 { dt.DefaultView.Sort = "name asc" ...

  4. Entity Framework Lambda 实现多列Group by,并汇总求和

    var result = DataSummaryRepository.FindBy(x => x.UserID == argMemberNo && x.SummaryDate & ...

  5. 洛谷P1518 两只塔姆沃斯牛 The Tamworth Two

    P1518 两只塔姆沃斯牛 The Tamworth Two 109通过 184提交 题目提供者该用户不存在 标签USACO 难度普及+/提高 提交  讨论  题解 最新讨论 求数据 题目背景 题目描 ...

  6. bzoj1216 [HNOI2003]操作系统

    1216: [HNOI2003]操作系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 751  Solved: 419[Submit][Status ...

  7. 在 JNI 编程中避免内存泄漏

    JAVA 中的内存泄漏 JAVA 编程中的内存泄漏,从泄漏的内存位置角度可以分为两种:JVM 中 Java Heap 的内存泄漏:JVM 内存中 native memory 的内存泄漏. Java H ...

  8. Chrome 和 Webkit 的渊源

    互联网的浪潮从未停息,而用以网上冲浪的冲浪板也一直在变得愈加精良.自人们进入互联网时代以来,即已经发生了三次浏览器大战.第一次浏览器大战的主角是IE和Netscape,最终IE凭借着Windows的庞 ...

  9. myecplise 添加svn插件

    myecplise svn插件下载地址 http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240 1.SVN下载地址 ...

  10. play framework 框架安装及myeclipse 导入项目

    下载 play framework 框架. 解压你你要解压的目录 E:\play-1.2.7 相对其他的WEB框架.play的配置是相当简单的.没有那么多配置文件的搞法.上手比较快,就是相关的资料比较 ...