一道好题

  今天在看linux C 语言编程时遇到一道很不错的题目,觉得有必要记录下来并在讲解上作适当延申。

题如下:问最终输出多少?ps:在原题的基础上我增加了        printf("a_sizeof = %d\n",sizeof(a));

#include<stdio.h>

void main()
{
	int i = 0;
	char a[1000];

	for(i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}

	printf("a_strlen = %d\n",strlen(a));
	printf("a_sizeof = %d\n",sizeof(a));

	system("pause");
}

最终打印输出的是:a_strlen = 255

         a_sizeof = 1000

关于这个题,主要涉及到一下几个方面:

1.数据类型与类型转换

  a 是一个char型数组,长度为1000,每个元素的取值范围为 -128~127(-2^7 ~ 2^7 - 1);

  i 是一个int型变量,取值范围为-2^31 ~ 2^31 - 1;

  a[i] = -1 - i;运算过程中,首先 (-1 - i)得到一个int 型数据,最后转换成char型,赋给a[i];

2.数据计算机中的存储及加减运算

  在计算机内存中,任何数据都是以二进制的补码形式存储的,这样做的一个好处就是减法可以当作加法来做,补码相加,舍去进位;

  补码计算:整数的补码与其原码 反码相同,如 十进制 +4,原码 0000 0100,反码 0000 0100,补码 0000 0100;

       负数的补码,反码加1,得到补码,如十进制-1,原码 1000 0001,除符号位外其余位按位取反得到反码 1111 1110,反码加1得到补码 1111 1111,即 0xFF;

       特例:在8位有符号数据类型中,-128 的原码 反码和补码都为1000 0000

  对于有符号数,二进制最高位用作正负数标识,整数最高位为0,负数最高为1,

3.strlen() 和 sizeof()

  strlen() 用于计数字符串中字符的个数(即字符串长度),直到遇到‘\0‘停止,并返回计数值(不包含‘\0‘);

  sizeof() 用于计算变量占用内存空间的大小。

经过上面的简单讲解,现在来看看上面问题结果的由来吧!

  先来看看,经过for循环后,数组a中各元素的值:

  i的值  a[i]的值   a[i]在内存中的存储形式

  0   -1 - 0       1111 1111   即 0xFF  -1

   1   -1 - 1    1111 1110 即 0xFE  -2

   2   -1 - 2    1111 1110 即 0xFD  -3

  ……   ……       ……

  127  -1 - 127   1000 0000  即 0x80    -128

  128  -1 - 128   0111 1111  即 0x7F    127 溢出(下同)

  129     -1 - 129         0111 1110  即 0x1E    126

  ……  ……      ……

  254  -1 - 254   0000 0001 即 0x01  1

  255  -1 - 255   0000 0000 即 0x00    0

  256  -1 - 256   1111 1111即 0xFF  -1

  ……  ……      ……

注意,a[255] = 0,即为ascii中的空格字符,strlen(a)计数到a[255]后停止,并返回计数结果255.

时间: 2024-08-30 14:29:36

一道好题的相关文章

HDU 4507 吉哥系列故事――恨7不成妻(数位dp&amp;好魔性的一道好题)

题目链接:[kuangbin带你飞]专题十五 数位DP J - 吉哥系列故事――恨7不成妻 题意 Time Limit:500MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=7*2 77=7*11 最终,他发现原来这一切归根到底都是

HDU 4944 FSF’s game 一道好题

FSF’s game Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 727    Accepted Submission(s): 377 Problem Description FSF has programmed a game.In this game, players need to divide a rectangle int

【BZOJ-3195】奇怪的道路 状压DP (好题!)

3195: [Jxoi2012]奇怪的道路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 305  Solved: 184[Submit][Status][Discuss] Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n.m条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往.一对城市之间可能存在

「Luogu2765」[网络流24题] 魔术球问题

->戳我进原题 [网络流24题] 魔术球问题 时空限制:1000ms / 128MB 问题描述 假设有n根柱子,现要按下述规则在这n根柱子中依次放入编号为1,2,3,...的球. (1)每次只能在某根柱子的最上面放球. (2)在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法,计算出在n根柱子上最多能放多少个球.例如,在4 根柱子上最多可放11 个球. 编程任务 对于给定的n,计算在n根柱子上最多能放多少个球. 输入格式 第1 行有1个正整数n,表示柱子数. 输出格式 程序运

【10.7校内测试】【队列滑窗】【2-sat】【贪心+栈二分+线段树(noip模拟好题)】【生日祭!】

比较好想的一道题,直接用队列滑窗,因为扫一遍往队列里加东西时,改变的只有一个值,开桶储存好就行了! #include<bits/stdc++.h> using namespace std; int n, k, r; inline int min(int a, int b) { return a > b ? b : a; } inline int max(int a, int b) { return a > b ? a : b; } int sum[200005], q[200005

test20181016 B君的第三题

题意 B 君的第三题(haskell) 题目描述 大学四年,我为什么,为什么不好好读书,没找到和你一样的工作. B 君某天看到了这样一个题,勾起了无穷的回忆. 输入\(n, k\) 和一棵\(n\) 个点的树,有边权,没有点权.两点\(i, j\) 之间的距离\(D(i, j)\) 定义为路径上的边权和.求 \[ \sum_{1 \leq i < j \leq n} \left\lceil \frac{D(i,j)}{k} \right\rceil \] 换句话说,枚举无序的两个点,求出距离除以

「刷题」JZPKIL

这道反演题,真牛逼. 以下用$B$代表伯努利数,$l*g=f$代表狄利克雷卷积,先推式子. 对于给出的$n,x,y$求一百组数据的$ans$ $\begin{array}{rcl} ans & = & \sum\limits_{i=1}^ngcd(i,n)^xlcm(i,n)^y\end{array}$ $\begin{array}{rcl} & = & \sum\limits_{i=1}^ngcd(i,n)^x\frac{(in)^y}{gcd(i,n)^y}\end{a

「刷题」 网络

看了一下网上基本都是线段树二分的题解,然而我想到一种整体二分的思路,正好练习一下. 是道好题. 首先用树上ST表处理,用于求LCA. 考虑整体二分离线求解. 一种方法是用树链剖分的,复杂度是$O(log^2n)$的,在套上个整体二分,复杂度达到了$O(nlog^3n)$所以说不可以直接树剖暴力. 可以用树上差分的方式. 考虑假设对于当前询问二分出的某一个答案,如何$check$? 只需要判断这个点是否阻断了所有的权值大于这个答案的路径,如果是的话,那么放低上界,否则升高下界. 用整体二分来做这个

51Nod1601 完全图的最小生成树计数

传送门 我居然忘写题解啦!(记忆废) 不管怎么说,这题还算是一道好题啊--你觉得敦爷出的题会有水题么 -- 这题比较容易把人误导到Boruvka算法之类的东西上去(我们机房去刚D题的人一开始大多也被误导了),但仔细思考之后是可以发现问题的特殊性质的. 听说很多人是从Kruskal算法想到这道题的做法的?好吧我并不是,那我就写写我的思考过程好了-- 记得算导上有一道思考题,判断一个最小生成树算法的正确性.那个算法是这样的:把当前图的点集随意划分成两半,递归两半后选出连接两个点集的边中权值最小的一条