C++/C 程序员要掌握的问题集锦之三


----------------------------------------------------------------------

Q:请简述一下两个for循环的优缺点
//第一个
for(i = 0; i < N; i++)
{
 if(condition)
  DoSomething();
 else
  DoSomething();
}

优点:

缺点:

//第二个
if(condition)
{
 for(i = 0; i < N; i++)
  DoSomething();
}
else
{
 for(i = 0; i < N; i++)
  DoSomething(); 
}

优点:

缺点:

A:
第一个
优点:程序简洁
缺点:多执行了N-1次逻辑判断,并且打断了循环"流水线"作业,使得编译器不能对循环进行优化处理,降低了效率。

第二个
优点:循环的效率高。
缺点:程序不简洁

----------------------------------------------------------------------

Q:下列程序有什么问题?
char a[] = "hello";
a[0] = 'X';
cout<<a<<endl;
char *p = "world";
p[0] = 'X';
cout<<p<<endl;

A:
char *p = "world"; p是指向常量字符串"world"(位于静态存储区,内容为world/0),常量字符串的内容是不可以被修改的。从语法上,编译器不会发现错误,但是该语句企图修改常量字符串的内容而导致运行错误。

----------------------------------------------------------------------

Q:有了malloc/free为什么还要new/delete?

A:
malloc/free是C++/C语言的标准库函数,new/delete是C++的运算符,它们都可以用于申请动态内存和释放内存。
malloc/free是库函数而不是运算符,不在编译器控制权之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
因此C++语言需要一个能完成动态分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。
 
----------------------------------------------------------------------
                                               
Q:请问允许Test函数会有什么样的结果?
void GetMemory(char *p)
{
 p = (char *)malloc(100);
}

void Test(void)
{
 char * str = NULL;
 GetMemory(str);
 strcpy(str, "hello world");
 printf(str);
}

A:
程序崩溃。
GetMemory并不能传递动态内存,Test函数中的str一直都是NULL。strcpy(str, "hello world");将使程序崩溃。

----------------------------------------------------------------------

Q:请问允许Test函数会有什么样的结果?
void *GetMemory(void)
{
 char p[] = "hello world";
 return p;
}

void Test(void)
{
 char * str = NULL;
 str = GetMemory();
 printf(str);
}

A:
可能会出现乱码。
GetMemory返回的是指向“栈内存”的指针,该指针的地址不是NULL,但其原先的内容已经被消除,新内容不可知。

----------------------------------------------------------------------

Q:请问允许Test函数会有什么样的结果?
void GetMemory(char **p, int num)
{
 *p = (char *)malloc(num);
}

void Test(void)
{
 char * str = NULL;
 GetMemory(&str, 100);
 strcpy(str, "hello world");
 printf(str);
}

A:
1.能够打印出hello world。
2.内存泄漏。

----------------------------------------------------------------------

Q:请问允许Test函数会有什么样的结果?
void Test(void)
{
 char * str = (char *)malloc(num);
 strcpy(str, "hello ");
 free(str);
 if(str != NULL)
 {
  strcpy(str, "world");
  printf(str);
 }
}

A:
篡改动态内存区的内容,后果难以预料,非常危险。
free(str);之后,str成为野指针,if(str != NULL)不起作用,给任意的内存地址赋值。

----------------------------------------------------------------------

Q:已知strcpy函数原型是char *strcpy(char *strDest, const char *strSrc);
其中strDest是目的字符串,strSrc是源字符串。
1.不用调用C++/C的字符串库函数,请编写函数strcpy。
2.strcpy能把strSrc的内容复制到strDest,为什么还要char *类型的返回值?

A:
1.
#include <iostream>
#include <string>

using namespace std;

char *_strcpy(char *strDest, const char *strSrc)
{
 char *address = strDest;
 while( (*strDest++ = *strSrc++) != '/0')
 {
  NULL;
 }
 return address;
}

int main()
{
 char a[] = "hello world!";
 char *p = a;
 char *q = new char[50];
 
 q = _strcpy(q, p);

 cout<<p<<endl;
 cout<<q<<endl;
 return 0;
}

以上代码可以编译通过~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2.为了实现链式表达。
例如 int length = strlen(strcpy(strDest,"hello world"));

----------------------------------------------------------------------

Q:编写类String的构造函数、析构函数和复制函数
已知类String的原型为:
class String
{
public:
 String(const char * str = NULL);
 String(const String &other);
 ~String(void);
 String & operate = (const String &other);
private:
 char *m_data;
};
请编写String的上述4个函数。

A:
//析构函数
String::~String(void)
{
 delete [] m_data;
}

//构造函数
String::String(const char * str)
{
 if( str == NULL )
 {
  m_data = new char[1];
  m_data = '/0';
 }
 else
 {
  int length = strlen(str);
  m_data = new char[length+1];
  strcpy(m_data, str);
 }
}

//拷贝构造函数
String::String(const String &other)
{
 int length = strlen(other.m_data);
 m_data = new char[length+1];
 strcpy(m_data, other.m_data);
}

//赋值函数
String & String::operate = (const String &other)
{
 //1.检查自赋值
 if( this == other ) 
  return *this;

 //2.释放原有的内存资源
 delete [] m_data;

 //3.分配新的内存资源,并且复制内容
 int length = strlen(other.m_data);
 m_data = new char[length+1];
 strcpy(m_data, other.m_data);
  
 //返回本对象的引用
 return *this;
}

----------------------------------------------------------------------

Q:用C++写个程序,如何判断一个操作系统是16位还是32位的?(不能用sizeof()函数)

A:
16位的系统下:
int i = 65536;
cout << i; // 输出0;
int i = 65535;
cout << i; // 输出-1;

32位的系统下:
int i = 65536;
cout << i; // 输出65536;
int i = 65535;
cout << i; // 输出65535;

----------------------------------------------------------------------

Q:在不用第三方参数的情况下,交换两个参数的值

A:
方法一:
void swap(int *a, int *b)
{
        *a = *a + *b;
        *b = *a - *b;
        *a = *a - *b;
}

方法二:
void swap(int *a, int *b)
{
 *a = *a ^ *b;
        *b = *a ^ *b;
        *a = *a ^ *b;
}

----------------------------------------------------------------------

Q:
union a
{
 int a_int1;      
 double a_double; 
 int a_int2;      
};

typedef struct
{
 a a1;
 char y;
}b;

class c
{
 double c_double;
 b b1;
 a a2;
};
输出cout<<sizeof(c)<<endl;的结果?

A: 32
union a
{
 int a_int1;       //4
 double a_double;  //8
 int a_int2;       //4
};                        //sizeof(a) = 8  以最长的为主

typedef struct
{
 a a1;             //8
 char y;           //8
}b;                       //sizeof(b) = 16 等宽

class c
{
 double c_double;  //8
 b b1;             //16
 a a2;             //8
};                        //sizeof(c) = 32;

----------------------------------------------------------------------

Q:i最后等于多少?
int i = 1;
int j = i++;
if((i>j++) && (i++ == j)) i+=j;

A:5
int i = 1;
int j = i++;  //j = 1, i = 2
if((i>j++) && (i++ == j)) i+=j;
//(i > j++) 2 > 1  (i++ == j)  2 == 2   i += j  i = 3 + 2 = 5;

----------------------------------------------------------------------

Q:
unsigned short array[]={1,2,3,4,5,6,7};
int i = 3;
*(array + i) = ?

A:4

----------------------------------------------------------------------

Q:重载和覆盖有何区别?

A:当你重载一个方法时,你用同样的名字但不同的签名创建了多个方法。当你覆盖一个方法时,你在派生类中用和基类中的方法相同的名字和相同的签名创建一个方法。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值