精华内容
下载资源
问答
  • //信息存储到乘客信息类中 for(l=0;l<100;l++) { if(l != s)//同一身份证不能重复选座 if(ck[s].id == ck[l].id) { cout<<"抱歉!该身份证已选座࿰...
  • 今天实现与fpga通信的过程中碰到的一些问题集中罗列一下,做一个总结,自己以后再碰到这些问题不再有疑问。 下面这些问题其实是理解计算机和程序最基本的问题,这些问题在《深入理解计算机系统》中有很深入的...

    今天把实现与fpga通信的过程中碰到的一些问题集中罗列一下,做一个总结,让自己以后再碰到这些问题不再有疑问。

    下面这些问题其实是理解计算机和程序最基本的问题,这些问题在《深入理解计算机系统》中有很深入的讨论,我就是在看完这本书的第三版的相关章节后才算是理解的比较清晰了。

    1.关于64位整形数的问题。

    fpga工程师给我的通信协议中有一个需要计算信号频率的公式是:下发数值=频率/10000000 * 2^32,

    问题的关键是在2^32这,这个数的值大于了uint32类型能表示的最大的值了,uint32能表示的最大的整数值是(1<<32)-1,而2^32这个数等于(1<<32);所以必须用64位整形数来表示,在linux里可以用long long类型表示64位类型,windows vc中可以用unsigned __int64类型来表示,我在vs2015中写测试程序时这样写:

    unsigned __int64 i = (1<<32);
    printf("i=%I64d\n",i);

    但是结果输出的却是0,纳闷了一阵子,后来明白了,输出0的原因出在(1<<32)这个表达式中,而如果我这么写就是正常的:

    unsigned __int64 a = 1;
    unsigned __int64 i = (a<<32);
    printf("i=%I64d",i);
     

    所以问题的原因是,在c/c++中常量的默认类型是什么,在上面的代码中表达式(1<<32)中,1会被编译器识别为一个32位的整形数,所以(1<<32)这个表达式的值会是0,然后这个32位整形值再被转为unsigned __int64的值还是0.所以我们可以强制把1这个常量转为64位整形数也是可以的:

    unsigned __int64 i = ((unsigned __int64)1<<32);

    由这个问题引申出32位有符号和无符号整形数可以表达的最大值和最小值,float和double能表示的最大值和最小值分别是多少?

    2.unsigned int ,signed int,unsigned long int,signed long int,float,double这些类型的数分别能表示的最大值和最小值是多少呢?

    这个问题其实每个现代编译器或sdk的头文件中都会有相关的定义,在windows平台上,我们以windows sdk 的BaseTsd.h头文件中的定义来看,因为这个头文件里面定义的比较容易理解,其他头文件比如c++ stl的头文件limits中也有类似的定义,BaseTsd.h中的相关宏定义如下:

    #define MAXUINT8    ((UINT8)~((UINT8)0))
    #define MAXINT8     ((INT8)(MAXUINT8 >> 1))
    #define MININT8     ((INT8)~MAXINT8)
    
    #define MAXUINT16   ((UINT16)~((UINT16)0))
    #define MAXINT16    ((INT16)(MAXUINT16 >> 1))
    #define MININT16    ((INT16)~MAXINT16)
    
    #define MAXUINT32   ((UINT32)~((UINT32)0))
    #define MAXINT32    ((INT32)(MAXUINT32 >> 1))
    #define MININT32    ((INT32)~MAXINT32)
    
    #define MAXUINT64   ((UINT64)~((UINT64)0))
    #define MAXINT64    ((INT64)(MAXUINT64 >> 1))
    #define MININT64    ((INT64)~MAXINT64)
    
    #define MAXULONG32  ((ULONG32)~((ULONG32)0))
    #define MAXLONG32   ((LONG32)(MAXULONG32 >> 1))
    #define MINLONG32   ((LONG32)~MAXLONG32)
    
    #define MAXULONG64  ((ULONG64)~((ULONG64)0))
    #define MAXLONG64   ((LONG64)(MAXULONG64 >> 1))
    #define MINLONG64   ((LONG64)~MAXLONG64)
    
    #define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
    #define MINLONGLONG ((LONGLONG)~MAXLONGLONG)
    
    #define MAXSIZE_T   ((SIZE_T)~((SIZE_T)0))
    #define MAXSSIZE_T  ((SSIZE_T)(MAXSIZE_T >> 1))
    #define MINSSIZE_T  ((SSIZE_T)~MAXSSIZE_T)
    
    #define MAXUINT     ((UINT)~((UINT)0))
    #define MAXINT      ((INT)(MAXUINT >> 1))
    #define MININT      ((INT)~MAXINT)
    
    #define MAXDWORD32  ((DWORD32)~((DWORD32)0))
    #define MAXDWORD64  ((DWORD64)~((DWORD64)0))

    这种定义让程序员可以在数据的位级(bit)表示或二进制表示角度很好的理解。其中需要特别注意的就是有符号数的表示方法,这个问题在CSAPP这本书中也有很深入和清晰的讲解,从位级表示来说,有符号数的最小值的位级表示为符号位为1,其余为全为0,这个数就是有符号数的最小值,而如果有符号数的位级表示全为1,不管是8位16位32位还是64位,这个数的值就为-1.而有符号数的最大值就是无符号数的最大值再除以2,因为有符号数最高位要用作表示符号,不能贡献数值,所以除以2.

    3.将一个整形数的某一位置零或置一的问题。

    fpga通信协议中有许多命令需要通过位设置来实现不同的命令,比如使用一个字节的数据,不同的位代表不同的命令含义,最后实现都要用到如何设置一个整型数据的某个位bit.

    首先,我们以unsigned int 32位例,写一个函数,置该数的某一位为1,可以这样写这个函数:

    uint32 SetUint32Bit(uint32 v,uint8 bit_index)
    {
        uint32 t;
        assert(bit_index<32);
        t = v |(1<<bit_index);
        return t;
    }
    
    uint32 ClearUint32Bit(uint32 v,uint8 bit_index)
    {
        uint32 t;
        assert(bit_index<32);
        t = v&(~(1<<bit_index));
        return t;
    }

     

    展开全文
  • pcf8563_i2c1_r8_ruoge_ov2640通过RTC驱动增加设备节点读取秒钟成功+直接读取I2C1获取秒钟值20160626_2201.7z http://blog.csdn.net/21cnbao/article/details/7919055 在Android源码树中添加userspace I2C读写...
  • dp变相 [HDU-5456]

    2020-09-11 11:29:08
    题意:你n个火柴 你凑成a-b=c的形式,不包括前导0,问总共有多少个方案数(mod上m)。 思路:真的想不出来,太妙了,先a-b=c变形成a=b+c,然后从低位往高位枚举每填的数,dp状态定义成f[i][f1][f2][flow] ...

    在这里插入图片描述
    题意:给你n个火柴 让你凑成a-b=c的形式,不包括前导0,问总共有多少个方案数(mod上m)。
    思路:真的想不出来,太妙了,先把a-b=c变形成a=b+c,然后从低位往高位枚举每位填的数,dp状态定义成f[i][f1][f2][flow] (只剩下i根火柴,b是否填完,c是否填完,是否有进位的方案数),终止条件就是b和c都填完了,看看是否有进位。很妙,每次火柴数量减去要填的数量,a的数字可以算出来,是(flow+i+j)%10。
    代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=510;
    int stk[10]={6,2,5,5,4,5,6,3,7,6};
    ll f[N][2][2][2]; //将a-b=c 转化为 a=b+c ,状态含义为只剩下i根火柴 b和c是否枚举完,是否有进位
    int n,m;
    ll dfs(int num,bool f1,bool f2,bool flow)
    {
    	if(num<0)	return 0;
    	ll &v = f[num][f1][f2][flow];
    	if(~v)	return f[num][f1][f2][flow];
    	if(f1 && f2)	return flow*2==num;
    	ll ans=0;
    	if(!f1 && f2)
    	{
    		for(int i=0;i<=9;i++)
    		{
    			int cost=stk[i] + stk[(i+flow)%10];
    			ans= (ans+dfs(num-cost,f1,f2,(flow+i)/10))%m;
    			if(i)
    				ans= (ans + dfs(num-cost,1,f2,(flow+i)/10))%m;
    		}
    	}
    	if(f1 && !f2)
    	{
    		for(int i=0;i<=9;i++)
    		{
    			int cost=stk[i] + stk[(i+flow)%10];
    			ans=(ans + dfs(num-cost,f1,f2,(flow+i)/10))%m;
    			if(i)
    				ans= (ans +dfs(num-cost,f1,1,(flow+i)/10))%m;
    		}
    	}
    	if(!f1 && !f2)
    	{
    		for(int i=0;i<=9;i++)
    			for(int j=0;j<=9;j++)
    			{
    				int cost=stk[i]+stk[j]+stk[(i+j+flow)%10];
    				ans = (ans + dfs(num-cost,f1,f2,(flow+i+j)/10))% m ;
    				if(i)
    					ans = ( ans + dfs(num-cost,1,f2,(flow+i+j)/10))%m;
    				if(j)
    					ans = ( ans + dfs(num-cost,f1,1,(flow+i+j)/10))%m;
    				if(i&&j)
    					ans = (ans + dfs(num-cost,1,1,(flow+i+j)/10)) % m;
    			}
    	}
    	return v = ans;
    }
    int main()
    {
    	int cnt=0;
    	int t;
    	cin>>t;
    	while(t--)
    	{
    		memset(f,-1,sizeof f);		
    		cin>>n>>m;
    		cout<<"Case #"<<++cnt<<": "<<dfs(n-3,0,0,0)<<endl;
    	}
    	return 0;
    }
    
    展开全文
  • I2C eeprom调试经验

    千次阅读 2014-04-11 13:35:43
    就这样一个简简单单的I2C,需要无数多的配置,无数多的寄存器,无数多的标志,难道ST的目标就是简单的东西复杂化么?复杂了就难用。另一方面,ST官方的I2C eeprom例程中while死等的语句比比皆是,本来I2C就做...
    在写本文之前我不得不痛批ST的comtex-M3的I2C做得实在是太烂了!就这样一个简简单单的I2C,需要无数多的配置,无数多的寄存器,无数多的标志位,难道ST的目标就是把简单的东西复杂化么?复杂了就难用。另一方面,ST官方给的I2C eeprom例程中while死等的语句比比皆是,本来I2C就做得复杂,还四处布满死等代码,很容易在使用中让系统死机。

    言归正传,前边的抱怨也是我调试I2C的起因。查过很多资料,普遍对于STM32I2C的在产品(不是实验室)中的使用表示需要谨慎,陷阱很多,bug很多。前前后后折磨了我估计有一个月吧,心里始终觉得官方的东西应该还是要好点,所以一直将就官方的代码在用,直到我的系统莫名奇妙的死机,究其原因是I2C操作引起为止,终于下定决心还是用模拟I2C。

    目标平台是STM32C8T6+atmel的eeprom,通信总线为串行I2C总线。

    调试过程遇到的问题:
    1.字节写操作正常,但是字节读函数出错
    原因:一厢情愿的认为写eeprom是在七位器件地址后添加写标志,则读eeprom也应该在七位期间地址后添加读标志,而事实上读eeprom也是在七位地址后添加写标志。

    2.断续单字节读写正常,但是采用连续的单字节读写出错。
    原因:eeprom写过程的结束并不是I2C总线写结束就结束,实际上I2C总线的写入数据先被保存到了eeprom内部的缓冲区,当遇到I2C结束条件后,eeprom才启动内部写过程,这个过程才是保存数据的过程。非常悲哀的是这个过程比较长,官方文档标注为5ms。如果在这5ms以内对eeprom芯片访问将被忽略。

    3.查询eeprom写过程是否结束造成死机
    官方文档说eeprom内部写周期最长为5ms,在很多情况下是远远低于5ms的,为了节约时间,官方给出一个解决办法。当写周期完毕后就开始进行应答查询,来确定eeprom写周期何时结束。所谓应答查询官方解释为:就是向eeprom发送一个I2C起始条件后发送器件地址和一个读写标志位,当eeprom完成内部写周期会回应一个ACK,这时MCU就可以进行正常的其他读写过程了。官方原文如下:
    I2C eeprom调试经验 - kanku - kanku的博客
    杯具就是始于我画红线的那句话,它说可以在器件地址后任意填写读写标志。我就填了读标志,事实证明在eeprom写入过程采用读查询将导致系统死机,I2C总线不能被正常拉高,可能是eeprom内部已经把总线拉到了地!不管怎样,反正就是死机了。经过多次尝试最终发现应答查询只能采用写应答查询可以正常确定eeprom内部写周期的结束。

    原因:运气太背了!

    总结:对于前两个问题归结为自己看资料太不细致,没有认真看先关参数。对于第二个问题,只能说我必须得怪ATMEL! 

    调试过程借鉴了"梅川酷子"的I2C代码,在此表示感谢!原文地址:http://blog.ednchina.com/kuge/1969761/message.aspx
    展开全文
  • Jscex 的一些建议

    2020-11-28 13:18:24
    4. 感觉太多内部细节暴露给了使用者࿰c;感觉不是很妥当。是否可以在现有 API 的基础上࿰c;再包装出一层更傻瓜的高级 API ?比如上面提到了一些: <pre><code> js require('jscex') // ...
  • KMP 算法——C

    2012-09-22 12:18:40
    因为要用C语言来实现,所以书里KMP算法定义的next数组的求值方法需要改动,因为C语言里的字符串数据结构并不是第一存储字符串长度,而是直接保存了第一个字符,就是这样一个小小的变化,可我伤透了脑筋,而且...

    昨天看了一下用于字符子串查找的KMP算法,很巧妙,也很难编,程序不长,理解起来可真是费劲。因为要用C语言来实现,所以书里KMP算法定义的next数组的求值方法需要改动,因为C语言里的字符串数据结构并不是让第一位存储字符串长度,而是直接保存了第一个字符,就是这样一个小小的变化,可让我伤透了脑筋,而且即便如此,对于算法的本质也不算了解得很透彻,几乎是在死命调试的情况下把程序给实现出来,里面是不是有bug也不敢确定,编程可真是件纠结的事,要是早些接触就好了,可以静静的思考,不用背负着找工作的压力来学习。

        寻找字符串的子串,结果返回第一个匹配的子串首字符的位置,从0开始。

    1.先从简单算法开始,简单算法主要是通过循环来实现。

        int Index( char* s, char* t, int pos )        /*s为目标字符串,t为要寻找的字串,pos为s中的开始位置*/

        {

            int slen, tlen;

            int i = pos, j = 0;        /*使用i标记s中的位置,使用j标记t中的位置*/

            if( s == NULL || t == NULL )

                return -1;

            slen = strlen( s );

            tlen = strlen( t );

            if( tlen > slen || pos < 0 || pos > tlen - 1 )

                return -1;

            while( i < slen && j < tlen )

            {

                if( s[i] == t[j] )

                { ++i; ++j }

                else

                { i = i - j + 1; j = 0; }        /*通过回溯i指针并将j重新指向起始位置*/

            }

            if( j >= tlen )

                return i - j;

            else

                return -1;

        }

    2.首位匹配算法

    类似简单算法,只是要先比较模式串t的首尾字符,首尾字符比较完后,再应用简单算法比较中间字符

    int Index_FL( char* s, char* t, int pos )

    {

        int slen, tlen, patStart, patEnd;

        int i = pos, j, k;

        if( s == NULL || t == NULL )

                return -1;

        slen = strlen( s );

        tlen = strlen( t );

        if( tlen > slen || pos < 0 || pos > tlen - 1 )

            return -1;

        patStart = t[0];

        patEnd = t[ tlen - 1 ];

        while( i <= slen - tlen )        /*最后一个匹配位置为i = slen - tlen*/

        {

            if( s[i] != patStart ) ++i;

            else if( s[ i + tlen - 1 ] != patEnd ) ++i;

            else

            {

                k = 1; j = 1;        /*用k来标记s中的位置, 以i + 1为起点*/

                while( j < tlen - 1 && s[ i + k ] == t[j] )        /*对中间字符串应用简单算法进行匹配*/

                { j++; k++; }

                if( j >= tlen - 1 )        /*由于末尾已经检测过相等,所以当 j = tlen - 1时表明匹配*/

                   return i;

                else        /*不匹配则i右移一位*/

                    i++; 

            }

        }

        return -1;

    }

    3.KMP算法,主要差别就在于,之前在遇到不匹配的情况时都是回溯s字符串的i指针,使用该算法则保持i不变,回溯t字符串的j指针,并且通过将t数组的首尾字串的重合位数记录在next数组中,在匹配过程中,通过next数组的值,来确定j指针的回溯位置。(说的比较抽象,具体学习还是参看教材,我这里就是做个记录便于以后复习或改进O(∩_∩)O)

    红色部分是跟原先算法主要的不同之处

    void get_next( char* t, int next[] )        /*若不存在k使得‘p0...pk-1’ = ‘pj-k...pj-1’,则令next[j] = 0(原先算法是令这种情况的next值为1)*/

    {

        int tlen;

        int i = 1, j = 0;

        next[0] = 0;

        next[1] = 0;

        tlen = strlen( t );

        while( i < tlen )

        {

            if( t[i] == t[j] )

            { ++i; ++j; next[i] = j; }

            else

            {

                j = next[j];

                if( j == 0 )        /*j == 0则代表next[i + 1] = 0,即不存在k使得‘p0...pk’ = ‘pi-k...pi’*/

                    next[++i] = 0;

            }

        }

    }

     

    int Index_KMP( char* s, char* t, int pos )

    {

            int slen, tlen, i, j;

            int next[100];

            if( s == NULL || t == NULL )

                return -1;

            slen = strlen( s );

            tlen = strlen( t );

            get_next( t, next );

            if( tlen > slen || pos < 0 || pos > tlen - 1 )

                return -1;

            i = pos; j = 0;

            while( i < slen && j < tlen )

            {

                if( s[i] == t[j] ) { ++i; ++j; }

                else

                {

                    if( j == 0 )        /*当s[i] != t[0]时直接将i移至下一位进行比较*/

                        ++i;

                    else

                        j = next[j];

                }

            }

            if( j >= tlen )

                return i - tlen;

            else

                return 0;

    }

    展开全文
  • 题意:通过他的代码,跑出 n个数a【i】。 然后取任意多个连续的数,他们 异或操作。 计算有多少种取法,使操作后结果为0. 做法:连续就想到了前缀和...再总方案数 c(n,2)减去为0的个数,就是答案了。但是普通
  • 这条限制就是说明了,奇数偶数的相对顺序是不能变的,这道题主要是找不变量,如果这一点相通了就好理解,我们分别奇数和偶数取出来,要使最后得数最小就要是最高的数字尽可能小,所以每次取两个队列小的那一个...
  • codeforces Gym-101246C

    2017-08-09 00:59:02
    题意你一个n*m的矩阵,矩阵有0点,有1点,你放一个雷,就会和雷所在的同一行和同一列的所有1变成0.n和m小于,问最少放几个雷? 思路我一开始想了个二分图,想行是一个集合,列是一个集合,然后每一个点去建一条...
  • 但网友比我还急切,我刚说出了想法,就相我要结果,干脆就周日消灭了。先拿出来共同欣赏一下,以证明这条路子是可以走的,在以后的过程中,将会有漂亮灵巧的例子和大家一起弄。 首先说明一下我的过程,另外介绍...
  • 你一个长度为n的数组,你进行三次操作,选择一个l到r的区间,这段长度为r - l,然后对于这段区间内的每一个数字,你都可以加上或者减去这段长度的倍数,要求三次操作结束之后,数组中每个元素都为0,求出这三次...
  • windows环境下32汇编语言程序设计

    热门讨论 2011-09-20 13:02:19
    用汇编写复杂的运算程序固然会比C更有效率,但同样的事在C中用一个表达式就全部搞定了,从这里开始学汇编,人的感觉就像从复杂的公式开始学算术,要知道,加法还没有学会呢!而对于高级语言封装起来的系统功能,用...
  • C 标准I/O库粗略实现

    2020-12-08 19:40:13
    而C语言为了用户更加方便的编程࿰c;自己封装了一些函数࿰c;组成了C库。而且不同的操作系统对同一个功能提供的系统调用可能不同࿰c;在不同的操作系统上C库对用户屏蔽了这些不同࿰c;所谓一次编译...
  • 但网友比我还急切,我刚说出了想法,就相我要结果,干脆就周日消灭了。先拿出来共同欣赏一下,以证明这条路子是可以走的,在以后的过程中,将会有漂亮灵巧的例子和大家一起弄。 首先说明一下我的过程,另外介绍...
  • “想不出来”是一个贪心的孩子,他天天想着怎么自己变的有钱,有一天他想到去做生意,他想用自己身上唯一的n元钱去买a物品,再用a物品按一定的比例换b物品。。。。。最后再东西卖了。 比如Sample里的数据,想不...
  • 最终还是成功地这道题解了出来࿰c;明明也因此获得了这次校数学竞赛的第一名。明明回家后࿰c;也这道题目你做࿰c;并且增大了题目的难度࿰c;明明不需要你所有的可能的数字组合写出来࿰c;...
  • 为了更好的这个游戏推广到全世界,Lele从Topcoder获得灵感,开发了一套系统量化并记录下每个人在每天的水平(定义为Rating),这样好选手更好的分析自己并促进自己成长。为了更精确,Lele系统里的Rating并不像...
  • 这是怎么回事啊……我大概知道为什么会有这种情况,就是计算机十进制转二进制存储再转十进制的过程出了问题……可是明明是机器告诉我有至少六有效数字,那我输个六有效数字的数不应该会出错的吧? 不知道...
  • s3c6410裸机程序(1)

    2012-03-12 22:51:00
    嘿嘿,今天在博客园注册了新用户,来记录我的嵌入式学习流程,自己的心得体会,教训经验,全部写出来,一来可以加深自己的印象,二来写出来博客园中的高手看到,也可以我批评指正哦 。@_@  以前实际上算的上...
  • 题意 你n个区间,你可以从每个区间中任意挑选一个数字,然后将这n个数字的平方相加问你有多少种方案数。 思路 第一次用bitset,不知道如何去描述,仔细想想就是...我们他放到bitset里面搞搞,bitset的第i表...
  • “想不出来”是一个贪心的孩子,他天天想着怎么自己变的有钱,有一天他想到去做生意,他想用自己身上唯一的n元钱去买a物品,再用a物品按一定的比例换b物品。。。。。最后再东西卖了。 比如Sample里的数据,想不...
  • 上篇文章我们讲到了关于ARM的发展历史,RISC和CISC的区别以及SOC内部各部件是由哪些厂家负责,那么这周我大家讲讲各部件之间是如何配合运转的。...我们可以从不同的角度去理解这个方波信号,首先可以它理解成C
  • P1_0”时,将P1_0 的值给了一个临时变量,然后对这个临时变量取反,而不 是直接对P1_0 取反,因此取反完毕后还要使用赋值符号(“=”)将取反后的值再赋给P1_0, 这样,如果原来P1.0 是低电平(LED 亮),那么取反...
  • C、C++语言是IT行业的主流编程语言,也是很多程序员必备的软件基本功,是软件开发行业招聘考查的重点。本书以流行的面试题讲解为主要内容,介绍了C、C++语言基本概念,包括保留字、字符串、指针和引用、结构体、...
  • 那理所应当下厨好好做些饭菜࿰c;吃饱了饭才好干活嘛! 字幕 0:00:29.558,0:00:30.420 哈喽 大家好 0:00:31.002,0:00:32.688 最近因为我们这里天天下雨 0:00:32.927,0:00:35.627 我在炒菜的时候拍...
  • Linux的工作方式类似于Uinx,它是免费的,源代码也是开放的,符合标准规范的32(在64CPU上是64)操作系统。Linux拥有现代操作系统的所具有的内容,例如:?真正的抢先式多任务处理,支持多用户。?内存保护。?...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 440
精华内容 176
关键字:

把c位让给了