程序员之---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-11-04 15:25:01
程序员之---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
主要内容:指针和数组细节,"//"的可移植性说明 #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的值
主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static char fruit[] = "apple"; // 不加static的话这个函数还回的指针会悬空,由于在函数退出时fruit组数被销毁 // 加了static后fruit数组分配在数据段里,而不是堆栈中.生命期和程序一样长,函数退出时变量 // 依旧有效 return fruit; }
主要内容:二维数组和指针.&*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] = {{
主要内容:段错误.类型提升.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
/*给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 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#基本功.在05年的时候,Scott Hanselman(微软的一个Principal Program Manager)在他的博客上列出了一张清单, 清单上是关于"一个好的.Net程序员应该知道的东东 What Great .NET Developers Ought To Know (More .NET Interview Questions
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.球体自由落下物理问题
记得以前有个笑话,说一个程序员和他的朋友去吃饭,他拿着本记录菜名,几个人商量之后决定有一个菜不点了.过了一会儿上菜的时候还是上来了,大家都问为什么,服务员拿来菜单一看: //鱼香肉丝.对于不懂程序的服务员,她显然没有明白这两个斜杠是什么意思 ,所以就闹出了这个笑话.在程序开发中,如果一味的写程序可执行的代码,运行起来可能没有问题,但是后续更改或维护就比较吃力,毕竟人直接看程序难度是有点大的,所以为了方便在以后阅读程序或者别人阅读程序时能比较容易读懂,为程序添加注释是必要的.听人说,一个完整