博文
memset用法详解(2008-09-14 00:16:00)
摘要:memset用法详解
memest原型(please type "man memset" in your shell)
void *memset(void *s, int c, size_t n);
memset:作用是在一段内存块中填充某个给定的值,它对较大的结构体或数组进行清零操作的一种最快方法。
常见的三种错误
第一: 搞反了c 和 n的位置.
一定要记住 如果要把一个char a[20]清零, 一定是 memset(a, 0, 20)
而不是 memset(a, 20, 0)
第二: 过度使用memset, 我想这些程序员可能有某种心理阴影, 他们惧怕未经初始化的内存, 所以他们会写出这样的代码:
char buffer[20];
memset(buffer, 0, sizeof((char)*20));
strcpy(buffer, "123");
这里的memset是多余的. 因为这块内存马上就被覆盖了, 清零没有意义.
第三: 其实这个错误严格来讲不能算用错memset, 但是它经常在使用memset的场合出现
int some_func(struct something *a){
…
…
memset(a, 0, sizeof(a));
…
}
问:为何要用memset置零?memset( &Address, 0, sizeof(Address));经常看到这样的用法,其实不用的话,分配数据的时候,剩余的空间也会置零的。
答:1.如果不清空,可能会在测试当中出现野值。 你做下面的试验看看结果()
char buf[......
PKU1019解题报告(2008-09-06 11:39:00)
摘要:PKU1019解题报告
题目大意:
一串数由1写道k.
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011
初始时候k=1.写完一次后k增加1.重新从1写到k,以此循环.
求这串数的第n位
这串数的特征为:一个数比他的前一个数多了(int)log(10)+1位.其他完全相同
第一个while()循环求出k;即k+1写完时,位数超过n.写完k时,位数不足n
第二个while()循环求出i(i为1`k中的数字);要求第i+1个数写完时,位数超过n.第i个数时,位数不足n.从而求出i
不知道这种方法叫什么.应该是逐步求精的思想吧.
题目中使用函数log10()来求出一个数字的位数.
log10在math.h 中声明:
形式为_CRTIMP double __cdecl log10 (double);
如果没有将其参数定义为double类型,将会编译错误.
#include <iostream>
#include <cstdlib>
#include <math.h>
using namespace std;
int main()
{
int t;
cin>>t;//第一行输入
for(;t>0;t--)
{
unsigned long int n;
&nb......
pku3302结题报告(2008-08-24 10:09:00)
摘要:pku3302结题报告
水题一个
题目要求:
给出两个字符串,s和sub
判断s是否包含了sub.包含是指s中含有sub的所有元素,并且在s中按照在sub的顺序或者逆序排列.
类似于串的模式匹配问题
#include <iostream>
using namespace std;
int main()
{
char s[100];
char sub[100];
int t;
int i=0,j=0,k=0;
bool ok=1;
int cur=0;
cin>>t;
for(k=0;k<t;k++)
{
cin>>s>>sub;
int len1=strlen(s);
int len2=strlen(sub);
i=0;j=0;
while(i<len1&&j<len2)
&nbs......
pku3650解题报告(2008-08-23 22:37:00)
摘要:pku3650解题报告
超级水题
将几个字符替换掉
" " (space) 替换成%20
"!" (exclamation point) 替换成%21
"$" (dollar sign) 替换成%24
"%" (percent sign) 替换成%25
"(" (left parenthesis) 替换成%28
")" (right parenthesis) 替换成%29
"*" (asterisk) 替换成%2a
注意输入带空格的字符串时,可以用gets()函数获取一行.
cin和scanf不行.
#include <iostream>
using namespace std;
int main()
{
char str[80];
memset(str,0,strlen(str));
while(gets(str))//获取一行输入
{
if(str[0]=='#')//最后一行只有一个"#"
break;//输入#时结束.
&nb......
PKU 1047解题报告(原创)(2008-08-18 22:29:00)
摘要:PKU 1047解题报告(原创)
题目:Round and Round We Go1047
08-8-17
题目大意:
判断一个数是否为cyclic数.
一个数为cyclic的条件为:设数为n位数.那么原数乘以1~n所得的结果可以通过原来的数移位得到.
由于刚做完一个大数乘法的题,使用了对大数的处理方法.一次AC!
比如 142857 *1 = 142857
142857 *2 = 285714
142857 *3 = 428571
142857 *4 = 571428
142857 *5 = 714285
142857 *6 = 857142
142857就是一个cyclic数.
Description
A cyclic number is an integer n digits in length which, when multiplied by any integer from 1 to n, yields a"cycle"of the digits of the original number. That is, if you consider the number after the last digit to "wrap around"back to the first digit, the sequ......
励志(2008-08-16 11:06:00)
摘要:看我一年前写的东西,发现我确实有一点进步.
看我现在写的东西,发现我还是什么都不会!
中间浪费一年在工作上边,值吗?
工作,考试什么狗屁东西!一般滚着去吧!
我不爱我的工作,却又无法辞职!
我爱编程!
我要成高手!
不断地学习,算法、语法!
用心看别人写的程序,快点提高!
没时间了!老张!
看着一帮年纪小小的人,写出那么好的东西!
我发现我欠缺太多太多了!
用心看每一页书,不再追求多!
走马观花学不到任何东西!
努力!为了我自己和我最爱的人!
努力,为了房子为了将来的孩子!
......
Eratosthenes筛法求1-100之间的素数(2008-08-10 13:03:00)
摘要:/*
写出不超过100的所有的素数。
解 将不超过100的正整数排列如下:
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53 54 55 56 57 58 59 60
61 62 63 64 65 66 67 68&......
【转载】 解读传说中计算π的超牛的C程序(2008-08-09 01:22:00)
摘要:解读传说中计算π的超牛的C程序
在我上大学的时候就流传着这样一个超牛的C程序,只用三行代码就能计算π到小数点后800位,还有的地方开玩笑说是外星人写的,的确是牛的不得了。那个时候大家一起研究都搞不懂,昨天看了一篇文章解释这段代码,今天自己试验了很久,终于弄明白了,所以记下来和大家一起交流。
这段C代码是这样的:
#include "stdio.h"
long a=10000, b, c=2800, d, e, f[2801], g;
void main() {
for( ;b-c; ) f[b++] =a/5;
for( ; d=0, g=c*2; c-=14,printf("%.4d",e+d/a),e=d%a)
for(b=c; d+=f[b]*a,f[b] =d%--g,d/=g--,--b; d*=b) ;
}
我把解释这段代码的文章附在最后面了,作者叫王聪,看他的博客是很高手的样子。我的主要分析都是从他的文章里看到的。谢谢这位高手!这么多年的疑惑终于解开了。
从我的角度来理解,我不习惯把for语句拆开变成while来分析,我觉着现在这个样子就挺好的,当然个别语句还是要调整一下。我觉得说明以下几个问题就能完全搞明白了:算法(两点)、错误(两点)、其他(四点)。
一、算法
1、π的计算公式
π/2=1+1!/3!!+2!/5!!+3!/7!!+...+k!/(2*k+1)!!+...
这个公式不记得了,好像是高数里学过。注:5!=1*2*3*4*5,5!!=1*3*5
2、公式的程序实现(数组存储余数)
把上面的公式做一下展开和调整
π/2 = 1 + 1!/3!! + 2!/5!! + 3!/7!! + ... + k!/(2*k+1)!!
= 1 +&......
标准C++处理for循环作用域规则(2008-08-07 14:20:00)
摘要:C++处理for循环作用域规则
在 C++ 标准制定之前,在 for 循环中声明的变量在循环外也可以访问。例如:
for(intn=0; n〈MAX;++n)
{
//..do something
}
++n;//OK in pre-standard C++; illegal in ISO C++
然而,在 ISO C++ 中,for 循环变量的作用域被限制为循环本身。虽然这一改变不可否认地具有其意义,但是它却影响到了老代码以及新代码。下面我将示范一些迁移技术帮助你处理这一改动。
遗留代码
对于那些使用标准制定之前的作用域规则的遗留代码,如果使用与标准兼容的编译器编译它们,那么就有可能出现错误。解决这一问题的最好方法是修改代码。但是,代码修正需要彻底测试,而且有时候还会招致一连串的缺陷和编译错误。
如果不想处理这一难于解决的问题,同时又希望升级编译器,那么不妨检查一下能否有办法恢复标准制定之前 for 循环变量的行为。如果确实使用了这种变量,那么打开这个选项,然后(使用注释)明确地在代码记下这一事实,以使将来的程序员知道如何正确地编译这一代码。
If you're wary of relying on compilers'favors, there's an alternative patch: move the variable's definition outside thefor-loop:
//如果不愿依赖编译器的帮助,那么还有一种替代方案:将变量的定义移至 for 循环之外:
intn=0;//originally was inside the for&n......
二维数组动态分配内存(2008-08-06 21:28:00)
摘要:如果使用以下方式分配,将无法通过编译
double * x;
x=new double[10][10];
原因是new没有分配多维数组的能力。
可以直接new double[100]分配一个一维数组来代替两维的,用的时候做一下下标转换即可。
或者也可以分配一个指针数组,再为每一个指针分配一个数组来实现两维的堆内存分配。
也可以用如下形式:
A=new int*[10];
for(int i=0;i<10;i++)
A[i]=new int[10];
注意:二维数组的头指针是一个指针的指针,也就是double**,int**...所以必须分配两次.所以例子中A的类型应声明为int**.......