`
songtianbao
  • 浏览: 28376 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
x&(x-1)表达式的意义 http://hi.baidu.com/zengzhaonong/blog/item/7fb884509ee30c61853524c2.html
求下面函数的返回值(微软) -- 统计1的个数
-------------------------------------
int func(int x)
{
    int countx = 0;
    while(x)
    {
        countx++;
        x = x&(x-1);
    }
    return countx;
}

假定x = 9999
10011100001111
答案: 8

思路: 将x转化为2进制,看含有的1的个数。
注: 每执行一次x = x&(x-1),会将x用二进制表示时最右边的一个1变为0,因为x-1将会将该位(x用二进制表示时最右边的一个1)变为0。




判断一个数(x)是否是2的n次方
-------------------------------------
#include <stdio.h>

int func(int x)
{
    if( (x&(x-1)) == 0 )
        return 1;
    else
        return 0;
}

int main()
{
    int x = 8;
    printf("%d\n", func(x));
}


注:
(1) 如果一个数是2的n次方,那么这个数用二进制表示时其最高位为1,其余位为0。

(2) == 优先级高于 &
字符串逆序(串中单个的单词不逆序) http://www.360doc.com/content/11/1024/23/1317564_158833674.shtml

        
汇编语言课程设计——调试并修改一个小的内存驻留程序 http://www.4ngel.net/article/31.htm

        
C语言宏定义使用技巧 http://blog.csdn.net/21aspnet/article/details/6724435

        
问题转载:javascript 的问题,在ie6中不能正常得到option 的值,FF中无问题,请大家帮帮我 javascript 的问题,在ie6中不能正常得到option 的值,FF中无问题,请大家帮帮我

        
【转载】分析一个好玩的c语言程序 【原创】分析一个好玩的c语言程序
前两天看到这么一个程序。代码如下:

#include <stdio.h>
int main()
{
    const short int c1 = 49920;
    const int c2 = 1073742008;

    int (*pf)() = (int (*)())&c2;
 
    printf("%c%c\n", *(char*)pf()-19, *((char*)pf()+1)-49);
    return   0; 
}

运行这个程序,屏幕上会出现一个 :)

很多人不懂其中的道理,在这里我给大家分析下代码。

先看这两句:

    const short int c1 = 49920;
    const int c2 = 1073742008;

定义了两个局部变量,数值转换成16进制为:

    const short int c1 = 0xc300;
    const int c2 = 0x400000b8;

其中变量c1的地址为:0x0012FF7C ,占两个字节,c2的地址为:0x0012FF78,占四个字节。这两个变量占据了连续的空间。变量赋值后,从0x12ff78开始的内存单元存储的字节码为:B8 00 00 40 00 C3 。对应的汇编码是:

    mov         eax,400000h
    ret


接下来的这句:

int (*pf)() = (int (*)())&c2;

分析如下:

 定义了一个函数指针,参数为NULL,返回值为int类型。 这个函数指针,指向上面的汇编码。这样,后面执行pf(),就执行了这段汇编码。

继续分析下面这句代码:

printf("%c%c\n", *(char*)pf()-19, *((char*)pf()+1)-49);

先看*(char*)pf()-19这个表达式, 执行了了pf指向的汇编代码,从汇编代码看,

这个函数调用后的返回值是0x400000,pf()前面的char *是把函数的返回值转换成一个

char*型指针,这个指针指向0x400000,前面再加个*号,表示取0x400000地址的内容,

由于是char *型指针,因此从这个地址取一个字节。

*(char*)pf()-19 表示的是从0x400000取出的字节内容再减去19。

接下来:*((char*)pf()+1)-49代表的意思是从0x400000 + 1的地址取出一个字节内容在减去49。

熟悉PE文件结构的朋友一定知道,对于exe文件0x400000是内存加载的基地址。
也就是说,0x400000 字节的内容对应的是0x4D,0x400001 字节的内容对应的是0x5A.
这是我们常说的pe文件起始的两个字节,"MZ"

这样,表达式*(char*)pf()-19的结果是0x3A ,表达式*((char*)pf()+1)-49的结果是0x29

察看ascii码表,输出就是我们看到的样子。

总结:
  别看一个这么小的程序,但是其中涉及的知识面比较广。
PKU 1014多重背包问题 http://isomer.me/2011/03/pku-1014-dividing-1276-cash-machine-%E5%A4%9A%E9%87%8D%E8%83%8C%E5%8C%85/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define max(a,b) (a>b)?a:b;
#define MAXV 20000*6+1
int dp[MAXV];
int nk[6];
 
int main(){
    int i,k,min,v;
    int cnt,sum;
    int _case=0;
    while(1){
        for(sum=i=0;i<6;i++) { scanf("%d",&nk[i]); sum+=nk[i]*(i+1); }
        if( !nk[0] & !nk[1] & !nk[2] & !nk[3] & !nk[4] & !nk[5] ) break;
        _case++;
        if( _case!=1 ) printf("\n");
        if( sum%2 ) { printf("Collection #%d:\n",_case); printf("Can't be divided.\n"); }
        else{
            sum/=2;
            memset(dp,0,sizeof(int)*(sum+1));
            for(i=0;i<6;i++){
                cnt=1;
                k=(sum/(i+1)>=nk[i])?nk[i]:sum/(i+1);
                while(k){
                    if( cnt>k ) cnt=k;
                    k-=cnt;
                    min=cnt*(i+1);
                    for(v=sum;v>=min;v--)
                       dp[v]=max(dp[v],dp[v-cnt*(i+1)]+cnt*(i+1));
                    cnt<<=1;
                }
            }
            if( dp[sum] == sum ) { printf("Collection #%d:\n",_case); printf("Can be divided.\n");}
            else { printf("Collection #%d:\n",_case); printf("Can't be divided.\n"); }
        }
  }
    return 0;
}
输出自身 c 输出自身 http://hi.baidu.com/atyuwen/blog/item/318ceb9b688ea7b2c8eaf412.html
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";main(){printf(s,34,s,34);}
Global site tag (gtag.js) - Google Analytics