程序员之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)

主要内容:无符号和有符号之间转换、两数相加溢出后数值计算

#include <stdio.h> 

/* 这个函数存在潜在漏洞 */
float sum_elements(float a[], unsigned length)
{
	int i;
	float result = 0;

	for(i = 0; i <= length - 1; i++)
	{
		result += a[i];
		printf("a[%d] = %f  \n",i,a[i]);
	}
	return result;
}
int main()
{
	int i = 200 * 300 * 400 * 500;  // int表示20亿左右,无符号就40亿左右
	float j = (3.14 + 1e20) -1e20; // 因为表示精度有限输出结果为0 ,而这条语句输出3.14:float j = 3.14 + (1e20 -1e20);
		                       //  e表示10为低的指数
   	long int a = 1;
    	long long int b =10;

        printf("i = %d\n",i);
	printf("j = %f\n",j);
	printf("a = %ld\n",a);
	printf("b = %ld\n",b);
	printf("\n");

	/* 測试补码*/
	unsigned int u = 4294967295u;
	int tu = (int)u;
	printf("u = %u, tu = %d\n", u, tu);  // 无符号int的最大值和-1的补码是一样的(即无符号Umax和-1的补码同样位表示)
	printf("\n");// 一个有符号数映射为它对应的无符号数时,负数转换成大的正数,非负数保持不变 

	/* 測试转换*/
	short int v = -12345;
	unsigned short uv = (unsigned short) v;  // 强制转换改变数值。但不改变位表示(即 -12345和无符号53191位一样)
	printf("v = %d, uv = %u\n", v, uv);
	printf("\n");

	float c[3];
	sum_elements(c,3);  // 传递0时出错 ,出现无符号和有符号转换问题
	/*小结:表达式中一个数是有符号还有一个是无符号,C语言默认转换为无符号。在比較-1<0U时会有问题 */

	/*
		溢出计算,公式见下图
	*/
	short a1 = -65536;
	short b1 = -1;
	printf("\n");
	printf("%d\n",a1+b1);

	return 0;
}

溢出公式:

输出:

原文地址:https://www.cnblogs.com/zhchoutai/p/8504008.html

时间: 2024-08-28 10:28:03

程序员之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)的相关文章

程序猿之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)

主要内容:无符号和有符号之间转换.两数相加溢出后数值计算 #include <stdio.h> /* 这个函数存在潜在漏洞 */ float sum_elements(float a[], unsigned length) { int i; float result = 0; for(i = 0; i <= length - 1; i++) { result += a[i]; printf("a[%d] = %f \n",i,a[i]); } return resul

程序员之---C语言细节12(指针和数组细节,&amp;quot;//&amp;quot;的可移植性说明)

主要内容:指针和数组细节,"//"的可移植性说明 #include <stdio.h> int main(int argc, char **argv) { int a[10]={1,2,3,4,5,6,7,8,9,0},*p; #if 0 /* 按移植性来说.在<c语言程序设计--现代方法>指出要用当前凝视方法.而不是// 由于一些编译可能不支持 */ // 错误举例 while(*a != 0) { a++; // a++ 相当于a = a+1,不能改变a的值

程序员之---C语言细节22(函数返回指针注意事项&amp;lt;悬空指针&amp;gt;、查看进程能够分配的内存大小)

主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static char fruit[] = "apple"; // 不加static的话这个函数还回的指针会悬空,由于在函数退出时fruit组数被销毁 // 加了static后fruit数组分配在数据段里,而不是堆栈中.生命期和程序一样长,函数退出时变量 // 依旧有效 return fruit; }

程序员之--C语言细节13(二维数组和指针,&amp;amp;*a[i][0]的理解,数组1[e]和e[1]非常可能你没见过)

主要内容:二维数组和指针.&*a[i][0]的理解.数组1[e]和e[1] #include <stdio.h> #define NUM_ROWS 10 #define NUM_COLS 10 int main(int argc, char **argv) {     int a[NUM_ROWS][NUM_COLS], *p, i = 0; // a理解为指向整数指针的指针 即int **     int c, d=2,*test, e[2] = {4,5},f[2][2] = {{

程序猿之---C语言细节24(段错误、类型提升、sizeof &#39;A&#39;)

主要内容:段错误.类型提升.sizeof  'A' #include <stdio.h> int main() { union test{ char a[10]; int b; }u; int *p = (int *)&(u.a[1]); // 没有引起总线错误 *p = 17; printf("%d\n",*p); #if 0 int *q = 0; // 引起段错误,在linux中运行可看到段错误,在windows下运行时直接出错 *q = 1; #endif

C语言实现两数相加2018-09-23

/*给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)输出:7 -> 0 -> 8原因:342 + 465 = 807*//** * Definition for singly-linked list. * struct ListNode { * int val; * str

.Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)

过去几年都在忙着找项目,赶项目,没有时间好好整理深究自己在工作中学到的东西.现在好了,趁着找工作的这段空余时间,正好可以总结和再继续夯实自己的.Net, C#基本功.在05年的时候,Scott Hanselman(微软的一个Principal Program Manager)在他的博客上列出了一张清单, 清单上是关于"一个好的.Net程序员应该知道的东东 What Great .NET Developers Ought To Know (More .NET Interview Questions

黑马程序员——经典C语言程序设计100例

1.数字排列 2.奖金分配问题 3.已知条件求解整数 4.输入日期判断第几天 5.输入整数进行排序 6.用*号显示字母C的图案 7.显示特殊图案 8.打印九九口诀 9.输出国际象棋棋盘 10.打印楼梯并按条件打印笑脸 11.经典兔子问题 12.判断素数 13.水仙花数问题 14.正整数分解质因数 15.学习成绩划分 16.正整数求其最大公约数和最小公倍数 17.统计英文字母/空格/数字个数 18.求s=a+aa+aaa+aa...a的值 19.求解"完数" 20.球体自由落下物理问题

程序员的专属语言-----注释(04)

记得以前有个笑话,说一个程序员和他的朋友去吃饭,他拿着本记录菜名,几个人商量之后决定有一个菜不点了.过了一会儿上菜的时候还是上来了,大家都问为什么,服务员拿来菜单一看:    //鱼香肉丝.对于不懂程序的服务员,她显然没有明白这两个斜杠是什么意思 ,所以就闹出了这个笑话.在程序开发中,如果一味的写程序可执行的代码,运行起来可能没有问题,但是后续更改或维护就比较吃力,毕竟人直接看程序难度是有点大的,所以为了方便在以后阅读程序或者别人阅读程序时能比较容易读懂,为程序添加注释是必要的.听人说,一个完整