博文

探讨全局变量的析构顺序(2007-09-29 23:48:00)

摘要:                朱金灿   前言:最近回答了网友一个问题,当然我不是C++高手,我仅是提出我的猜想和大家交流。      经典的C++的教科书都这样写着:全局对象在调用 main之前初始化, 在退出main之后析构。但是大家请看下面这样一个程序:   #include <cstdlib> #include <iostream> #include <conio.h> using namespace std;   class gb { public: gb::gb() { std::cout<<"start"<<std::endl; };   gb::~gb() { std::cout<<"end"<<std::endl; getch(); }; };   gb a;   int main() { std::cout<<"This is in main"<<std::endl; return 0; }        大家认为输出是什么呢?大家可能会说:这不是很简单吗? Start
This is in main
End         实际上事情并没有这么简单。在dev-c++-4.9.9.2的工程上,输出结果是顺理成章的: Start
This is in main
End 在VC6.0上建一个控制台工程,把代码拷贝进去,发现运行结果却是: Start
This is in main

  &n......

阅读全文(3238) | 评论:0

求一个数的质因数分解式(2007-08-22 23:14:00)

摘要:                        朱金灿                一个数的质因数分解式就是把一个数分为一个个质数因子,比如60,它的质因数分解式就是2 2 3 5 ,首先这几个数都是质数,其次它们相乘为60。看《算法设计与分析基础》,见到书上提到数的质因数分解式,便编了一个小程序实现求一个数的质因数分解式。算法思路是这样的: 1.       首先判断该数是否为质数,如果不是就进行分解,如果是就输出; 2.       分解步骤是这样的:使用循环从被分解数的平方根中开始相除,一旦相除余数为0,就分别对余数和商进行类似分解,退出循环。   很显然,这个算法要使用递归。   代码如下:   #include <iostream> using namespace std; #include <math.h> #include <conio.h>   // 判断一个数是否是素数 bool IsPrimeNum(int number) {     bool bIsPrimeNum = true;        for (int i = int(sqrt((double)number));i>1;i--)        {         if((number%i)==0)       ......

阅读全文(9529) | 评论:2

(转载)ASCII 表(2007-03-06 22:04:00)

摘要:转载地址:http://www.mcu123.com/new/Article_Show.asp?ArticleID=154 ASCII ( A merican S tandard C ode for I nformation I nterchange , 美国信息互换标准代码 )是基于罗马字母表的一套电脑编码系统。它主要用于显示现代英语 和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准 ISO 646 。 控制字符 Binary Decimal Hex 缩写 可以显示的表示法 名称/意义zgyh 0000 0000 0 00 NUL ? 空字符(Null) 0000 0001 1 01 SOH ? 标题开始 0000 0010 2 02 STX ? 正文开始 0000 0011 3 03 ETX ? 正文结束 0000 0100 4 04 EOT ? 传输结束 0000 0101 5 05 ENQ ? 请求 0000 0110 6 06 ACK ? 收到通知 0000 0111 7 07 BEL ? 响铃 0000 1000 8 08 BS ? 退格 0000 1001 9 09 HT ? 水平 制表符 0000 1010 10 0A LF ? 换行键 0000 1011 11 0B VT ? 垂直制表符 0000 1100 12 0C FF ? 换页键 0000 1101 13 0D CR ? 回车键 0000 1110 14 0E SO ? 不用切换(Shift键) 0000 1111 15 0F SI ? 启用切换(Shift键) 0001 0000 16 10 DLE ? 数据通讯换码 0001 0001 17 11 DC1......

阅读全文(2411) | 评论:0

应用全排序算法解决一道逻辑推理题(2007-03-03 16:14:00)

摘要:                      朱金灿          全排序算法就是列举一些字符的所有排列顺序的一种算法,比较典型的采用递归法。下面是一种简单的全排序算法。   void Swap(char* a, char* b)
{// 交换a和b
  char temp;
  temp = *a;
  *a = *b;
  *b = temp;
}

void Perm(char list[], int k, int m)
{ //生成list [k:m ]的所有排列方式
  int i;
  if (k == m) {//输出一个排列方式
    for (i = 0; i <= m; i++)
      putchar(list[i]);
    putchar('\n');
  }
  else // list[k:m ]有多个排列方式
    // 递归地产生这些排列方式
    for (i=k; i <= m; i++) {
      Swap (&list[k], &list[i]);
      Perm (list, k+1, m);
      Swap (&list [k], &list [i]);
    }
}
int main(int argc, char *argv[])
{
 char s[6]="01234";
 Perm(s,0,4);
 return 0;
}   算法作者:拉格浪日,来源:燕赵草叶风 2006-7-1   下面我简单地应用这个算法解决一道推理问题。该推理是这样的: 一天晚上,一对已婚夫妇,和他们的儿子女儿在家里发生了一起......

阅读全文(3652) | 评论:0

《深入浅出MFC》的一个例子的一点问题(2007-01-14 15:33:00)

摘要:                                   朱金灿     《深入浅出MFC》在第二章中说:虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针。派生类会继承基类的虚函数表(以及其它可以继承的成员),当 我们在派生类中改写虚函数时,虚函数表就受了影响:表中元素所指的函数地址 将不再是基类的函数地址,而是派生类的函数地址。 测试程序: #include <iostream.h>
#include <stdio.h>
class ClassA
{
public:
int m_data1;
int m_data2;
void func1() { }
void func2() { }
virtual void vfunc1() { }
virtual void vfunc2() { }
};
class ClassB : public ClassA
{
public:
int m_data3;
void func2() { }
virtual void vfunc1() { }
};
class ClassC : public ClassB
{
public:
int m_data1;
int m_data4;
void func2() { }
virtual void vfunc1() { }
}; void main()
{
cout << sizeof(ClassA) << endl;
cout << sizeof(ClassB) << endl;
cout << sizeof(ClassC) <......

阅读全文(2687) | 评论:0

使用穷举法解决0—1背包问题(2006-07-09 12:06:00)

摘要:                     朱金灿   问题描述:有不同价值、不同重量的物品n件,求从这n件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。
设n个物品的重量和价值分别存储于数组w[ ]和v[ ]中,限制重量为tw。考虑一个n元组(x0,x1,…,xn-1),其中xi=0 表示第i个物品没有选取,而xi=1则表示第i个物品被选取。用枚举法解决背包问题,需要枚举所有的选取方案,而根据上述方法,我们只要枚举所有的n元组,就可以得到问题的解。
  显然,每个分量取值为0或1的n元组的个数共为2n个。而每个n元组其实对应了一个长度为n的二进制数,且这些二进制数的取值范围为0~2n-1。因此,如果把0~2n-1分别转化为相应的二进制数,则可以得到我们所需要的2n个n元组。 下面是我据此思路编的一个小程序。 #include <stdio.h> #include <math.h>   #define MAX 100                      // 限定最多物品数 /*将n化为二进制形式,结果存放到数组b中*/ void conversion(int n,int b[MAX]) {  int i; for(i=0;i<MAX;i++) { b[i] = n%2; n = n/2; if(n==0)break; }   }   void main() { int i,j,n,b[MAX],temp[MAX]; float tw,maxv,w[MAX],v[MAX],temp_w,temp_v; printf("please input n:\n"); sca......

阅读全文(4618) | 评论:0

C 语言程序设计第6章习题答案(一)(2006-06-14 16:44:00)

摘要: 谭浩强的《C程序设计》第六章的两道习题答案。     6.3求Sn=a+aa+aaa+…+aa…a(n个a位数)的值并显示Sn,其中a、n由键盘输入。例如:a=1,n=3,则Sn=1+11+111=123;     a=2,n=4,Sn=2+222+2222=2468。   #include <stdio.h> #include <math.h>   long Calculate(int a,int n) {    int temp = 0;    int sum =0;    for(int i=0;i<n;i++)    {           temp = temp + a*int(pow(double(10),double(i)));           sum = sum +temp;    }    return sum; }     int main(void) {     printf("%d\n",Calculate(2,4));        return 0; }     改进设想:大数的存诸问题。比如结果超出了长整型的范围。     6.14 打印出下列图案。            *         * * *       * * * * *     * * * * * * *  * * * *......

阅读全文(3817) | 评论:0

用指向指针的指针的方法对n个整数排序并输出(2006-04-14 15:14:00)

摘要:一道编程题目:用指向指针的指针的方法对n个整数排序并输出。要求将排序单独写成一个函数。整数和n在主函数中输入,最后在主函数中输出。
我对该题的理解是:用交换地址的办法来达到交换元素的目的。   #include <stdio.h>
#include <malloc.h>  
void Sort(int **p, int times)
{
    int *temp;
 int i=0;
 int j=0;
    for (i=0; i<times-1; i++)
    {
        for (j=i+1; j<times; j++)
        {
   /*当某元素大于它后面的元素,交换它们的地址*/
            if (**(p+i) > **(p+j))
            {
                temp = *(p+i);
                *(p+i) = *(p+j);
           &nbs......

阅读全文(7237) | 评论:0

结构体的成员变量的对齐问题(2006-04-06 17:08:00)

摘要:结构体的大小是一个令人迷惑不解的问题,不信,我出一题让你算算看:   enum DataType{IntData,CharData,VcharData};   struct Item      {        char ItemNAme[30];          DataType ItemType;          char ItemDecr[50];          int  ItemLength;   };   在你使用sizeof之前你能知道它的大小吗?我想即使你用sizeof得出结果后,结果还是会让你大吃一惊的:怎么是这个?       一.为什么要对齐?   《Windows核心编程》里这样说:当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始,数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。在最好的情况下,是两倍的时间,有时更长。       二.成员变量对齐的原理   我花了一个上午,看了一些资料,总算把这个问题搞明白了。下面我以一些例子说明结构体成员变量的对齐问题。   对于 struct s1 {   char a;   long int d; double c; };   这个结构体的大小是16。编译器默认的一般是8字节对齐。a的大小是1,它就按1字节对齐(因......

阅读全文(5132) | 评论:0

一个字符统计程序(2006-01-16 11:02:00)

摘要:           我编了一个程序,统计一段字符中的字母字符,数字字符、空格字符和其他字符的个数。程序运行环境:Windows2000, VC++6.0。程序如下:
#include <stdio.h>

void StatisticsSymbol2(char *pChar)
{
    int i=0;
    int  NumberCount=0,LetterCount=0,BlankCount=0,OtherCount=0;  // 初始化各个统计变量
    for(i=0;pChar[i]!='\0';i++)
    {
  if(( pChar[i]>47 )&&( pChar[i]<58 ) )   //  假如是数字,数字计数加1
  {
      NumberCount++;
      continue;
  }
  if( ( pChar[i]>64 && pChar[i]<91 ) ||( pChar[i]>96 && pChar[i]<123 ))/*  假如是字母,字母计数加1     */
 {
    LetterCount++;
     continue;
  }
if ( pChar[i]==' ') // 假如是空格,空格计数加1
......

阅读全文(4099) | 评论:0