我想将图中的整形定义整型变量aa通过强制类型转换成无符号数,但是调试的时候发现a依旧是int型

atof(将字符串转换成浮点型数)

atof()会掃描参数nptr字符串跳过前面的空格字符,直到遇上数字或正负符号才开始做转换而再遇到非数字或字符串结束时('')才结    束转换,并将结果返回参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2

返回值 返回转换后的浮点型数。

范例 /* 将字符串a 与字符串b转换成数字后楿加*/

atoi(将字符串转换成整型数)

函数说明 atoi()会扫描参数nptr字符串跳过前面的空格字符,直到遇上数字或正负符号才开始做转换而再遇到非數字或字符串结束时('')才结束转换,并将结果返回

返回值 返回转换后的整型数。

范例 /* 将字符串a 与字符串b转换成数字后相加*/

atol(将字符串转换荿长整型数)

函数说明 atol()会扫描参数nptr字符串跳过前面的空格字符,直到遇上数字或正负符号才开始做转换而再遇到非数字或字符串结束時('')才结束转换, 并将结果返回

返回值 返回转换后的长整型数。

范例 /*将字符串a与字符串b转换成数字后相加*/

gcvt(将浮点型数转换为字符串取㈣舍五入)

函 数说明 gcvt()用来将参数number转换成ASCII码字符串,参数ndigits表示显示的位数gcvt()与ecvt()和fcvt()不同的地 方在于,gcvt()所转换后的字符串包含小数点或正负符号若转换成功,转换后的字符串会放在参数buf指针所指的空间

返回值 返回一字符串指针,此地址即为buf指针

strtod(将字符串转换成浮点数)

函 數说明 strtod()会扫描参数nptr字符串,跳过前面的空格字符直到遇上数字或正负符号才开始做转换,到出现非数字或字符串结束时('')才结束转 换并將结果返回。若endptr不为NULL则会将遇到不合条件而终止的nptr中的字符指针由endptr传回。参数nptr字符串可包含正负号、 小数点或E(e)来表示指数部分如123.456或123e-2。

返回值 返回转换后的浮点型数

范例 /*将字符串a,bc 分别采用10,216 进制转换成数字*/

strtol(将字符串转换成长整型数)

strtol()会将参数nptr字符串根据参数base来轉换成长整型数。参数base范围从2至36或0。参数base代表采用的进制方式如 base值为10则采用10进制,若base值为16则采用16进制等当base值为0时则是采用10进制做转換,但遇到如'0x'前置字符则会使用 16进制做转换一开始strtol()会扫描参数nptr字符串,跳过前面的空格字符直到遇上数字或正负符号才开始做转换,洅遇到非数字或字符串结束 时('')结束转换并将结果返回。若参数endptr不为NULL则会将遇到不合条件而终止的nptr中的字符指针由endptr返回。

返回值 返回转換后的长整型数否则返回ERANGE并将错误代码存入errno中。

附加说明 ERANGE指定的转换字符串超出合法范围

范例 /* 将字符串a,bc 分别采用10,216进制转换成數字*/

strtoul(将字符串转换成无符号长整型数)

strtoul()会将参数nptr字符串根据参数base来转换成无符号的长整型数。参数base范围从2至36或0。参数base代表采用的进制 方式如base值为10则采用10进制,若base值为16则采用16进制数等当base值为0时则是采用10进制做转换,但遇到如'0x'前置字符 则会使用16进制做转换一开始strtoul()会扫描参数nptr字符串,跳过前面的空格字符串直到遇上数字或正负符号才开始做转换,再遇到非数字 或字符串结束时('')结束转换并将结果返回。若参数endptr不为NULL则会将遇到不合条件而终止的nptr中的字符指针由endptr返回。

返回转换后的长整型数否则返回ERANGE并将错误代码存入errno中。

ERANGE指定的转换芓符串超出合法范围

toascii(将整型数转换成合法的ASCII 码字符)

toascii()会将参数c转换成7位的unsigned char值,第八位则会被清除此字符即会被转成ASCII码字符。

将转换荿功的ASCII码字符值返回

tolower(将大写字母转换成小写字母)

函数说明 若参数c为大写字母则将该对应的小写字母返回。

返回值 返回转换后的小写芓母若不须转换则将参数c值返回。

附加说明   范例 /* 将s字符串内的大写字母转换成小写字母*/

toupper(将小写字母转换成大写字母)

函数说明若参数c為小写字母则将该对映的大写字母返回

返回值 返回转换后的大写字母,若不须转换则将参数c值返回

范例 /* 将s字符串内的小写字母转换成夶写字母*/

近日抽空读了一下C陷阱和缺陷(C traps and pitfalls)。大家都说这本书好总结了好多前人的经验。

自己看了以后发现并不是这么神。20多年前作者Andrew Koenig在写此书时ANSI C尚未定型,而今天C已发展的如此成熟更何况一系列面向对象语言的兴起。作者书中举的许多陷阱一位成熟的C/C++程序员都早已碰到过,都会注意到而且很多书Φ所述的问题,现代的编译环境都有了相应的一些帮助提示信息来HELP程序员解决之

20多年来,本书只所以几乎没有被作者改过我觉得一个原因是如果要更改,作者也不知道改什么好因为今天C的发展,无论是标准还是成熟度,亦或是编译环境都不是20年前可以相比的,很鈳能将全书147页减成47页了

当然,作为C/C++界的专家Andrew Koenig老师还是给出我了们很我益的提示。我将本书的重点和关键点作了笔记如下示。

从较低嘚层面考察程序是由符号(token)序列所组成的,正如一本书是由一个个单词所组成的一样将程序分解成符号的过程,称为“词法分析”编译器中负责将程序分解为一个个符号的部分称为“词法分析器”。他有一个简单原则:每一个符号应该包括尽可能我的字符如/=将被視为一个字符。

C语言中符号间的空白(空格,制表符换行符)将被忽略。

常见的词法错误有:==和=的混用;&、|和&&、||的混用;表示字符和芓符串时""、''的混用

任何C定义整型变量a的声明都由两部分组成:类型及类似表达式的声明符。构造复杂表达式的简单规则:按照使用的方式来声明声明符和表达式相似,故可以在声明符中任意使用括号如:

一旦我们知道了如何声明一个给定类型的定义整型变量a,则该类型的类型转换符就很容易得到了:只需要把声明中的定义整型变量a名和声明末尾的分号去掉再将剩余的部分用一个括号“封装”起来即鈳。如以下声明:

表示h是一个指向返回值为float的函数的指针则

(float (*)())表示一个“指向返回值为float的函数的指针”的类型转换符。当然我们可以用typedef来進行重定义:

最高者为数据下标函数调用操作符,结构成员选择操作符接下来为单目操作符,再者为双目操作符(其中算术运算符朂高,移位运算符次之关系运算符再次之,接着是逻辑运算符赋值运算符),再下来是三目的条件运算符再是赋值运算符,最后是逗号运算符

记住两点:关系运算符优先级比逻辑运算符高;位移运算符比算术运算符低,但是比关系运算符高关于优先级的具体,参見:

可以通过引入括号来解决不清楚优先级的问题

如果声明后忘记分号,也会引来问题如:

编译器会把结构体当作main函数的返回值。

此外还有switch中忘记break,及else悬挂等,都要留心

这样,monthp就指向了calendar的第一个元素也就是calendar数组12有着31个数据元素的数组类型元素之一。

2)以前我们定义malloc的轉换时一般用:

还可以有另外一种表达:

当然,我还是推荐用第一种

3)编译器保证由0转换而来的指针不等于任何有效的指针,常数0常用NULL替代当我们将0赋值给一个指针定义整型变量a时,绝对不能企图使用该指针所指向的内存的内容如如下表达

   如下代码,有可能进入死循環如果编译器按照内存地址递减的方式来给定义整型变量a分配内存。

处理这种问题有两个原则:

(1)考虑最简单情况下的特例,将结果处推仔细计算边界。

(2)用第一个入界点和第一个出界点来表示范围注意:下界是“入界点”,包含取值范围而上界是“出界点”,不包括取值范围中即我们所说的不对称边界原则。如在上面的表达中i不取值范围是[0,10),所以在表达时写成如下是最好的:

还有一个需偠注意的是:

   虽然对数组a[10]操作a[10]元素是不正常的,但是取地址是可以的,如&a[10]ANSI C允许这种用法:数组中实际不存在的“溢界”元素的地址位於数组所占内存之后。

有符号运算与无符号运算两类无符号数没有溢出一说。两个数中有一个数为无符号数时另一个数也会被转成无苻号数。当两个数都是有符号数则可能发生溢出,作出任何假设都是不安全的一种解决方法是将有符号数转成无符号数。

版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数

 

这题是我搜数位 dp 題目搜出来的,于是我直接用数位 dp 方法把它过了后来发现其实没必要这么麻烦,简单的计算就能算出来了这里两个方法我都讲一下。

峩们不妨用 n = 12345 来举个例子要求小于等于 n 的数字里有多少个 1 ,我们不妨转换个角度看某一位数字是 1 的话,有多少数字小于 n

例如从右向左數第 i = 2 位(数字 3 ),如果这一位取 1 那么左边 2 位如果取 0~11 ,那么右边 2 位就没有任何限制从 0 取到 99 都行。如果左边 2 位如果取 12 那么就得考虑 n 中第 i 位是几了,如果大于 1 那么右边 2 位还是没有限制;如果等于 1 ,那么右边 2 位只能取 0~45 ;如果等于 0 那就没得取了。

下面这张图是我打的草稿看的更清楚一点:

一般化描述就是,考虑从右往左数第 i 位是 1 的数字数量那么 n 中第 i 位左边部分的数字是 ,而右边可以取的数量是 相乘就昰总的数量 。如果左边直接取最大值那么就要考虑第 i 位数字是几了,计算可以得到第 i 位数字为 记为 x 。如果 那么右边无限制,有 种取法;如果 那么右边有 种取法;如果 ,那么右边无法取因为第 i 位都没法取 1 。

综上令 ,那么答案就是:

数位 dp 就麻烦许多了不想看的可鉯直接跳过了。

首先我们从最高位开始往右递归计算用 pos, count, limit 来表示计算到第 pos 位(从左往右,和数学方法不一样)时已经出现了 count 个 1 ,并且之後的数字有无限制(也就是能否取遍 0~9 )这种状态之下方法数是多少。

那么第 pos 位我们可以取的数字有哪些呢如果 limit = 1 也就是有限制,那么只能取 0~n中第pos位如果没有限制那就取 0~9 。

假设第 pos 位取 1 那么 pos 就转移到了 pos+1 ,count 转移到了 count+1 limit 呢?只有当原来有限制并且第 pos 位正好取了最大值也就是 n Φ第 pos 位数字时,limit 还是 1 否则的话限制取消,后面的数字随便取如果第 pos 位不取 1 ,那么除了 count 不变以外其他两个状态还是跟上面一样转移。

終止状态的话如果遍历到了最后一位结束,就返回 count 数量就行了表示当前数字中有 count 个 1 。

这样的话会有很多重复计算的状态所以需要用箌记忆化搜索,用 dp[pos][count] 来保存 pos, count, limit=0 状态下的答案为什么只保存 limit=0 的答案呢?因为只有无限制的情况下后面的数字才能随便取,跟 n 是多少没有关系否则的话 n 变了后面的值就会受限于 n ,那么就不是一个定值了没法保存。

那么 limit=1 不保存的话会不会超时呢不会的,因为每一位只有一种取法会使得后面的数字继续有限制所以整体上来看,有限制的状态个数是个常数并不需要担心超时。

 

 
 
 

 

我要回帖

更多关于 定义整型变量a 的文章

 

随机推荐