1. volatile 关键字在 C++ 中的性能和 C 的一样?

作用是一样的,但是其内部实现原理可能不同。

2. scanf 格式化输入是怎么赋值的?

由于scanf输入的数据个数是不定的,从键盘输入的数据会进入缓冲流,然后将输入的数据赋值给scanf的参数。

3. 下面代码的作用?

void func(const char* input, char* output, unsigned int outLen)
{
int buf[256] = {0};
while( *input )
{
buf[*input++]++;
}
if( output && outLen )
{
int i = 0;
for(i=0; i<256; i++)
{
if( buf[i] )
{
*output++ = (char)i;
}
}
*output = 0;
}
}
// 输入input为“aaabbbccddddd”,得到output为abcd


1、下面的程序输出什么?为什么?(某 CPU 公司面试题)
int main(int argc, char* argv[])
{
    unsigned char a = 0xA5;
    unsigned char b = ~a >> 4 + 1;
    printf("%d\n", b);
    return 0;

}

(分析:第一个坑:运算符优先级,+的优先级大于>>;第二个坑:当小类型变量和整型做运算的时候,会转化为int类型。

这个题,将得到的int型的结果再截断,最后答案:250)

6. 写程序判断一个数是否是 2 的 N 次方! (某 CPU 公司面试题)

(分析:

2的1次方:0000 0001

2的2次方:0000 0010

2的3次方:0000 0100

那么,如果一个数是2的N次方,那么这个数的二进制就只有一个1.

假设X这个数是2的N次方,(X-1 & X)必然等于0!!!


7. 有 2 个数组保存着 100 以内的自然数,编程求出两个数组的交集(两个数组中同时出现的自然数)。

#include <iostream>
using namespace std; int main()
{
int a[] = {1, 2, 3, 4, 5, 6};
int b[] = {3, 5, 7, 9};
int buf[100] = {0}; for(int i=0; i<sizeof(a)/sizeof(*a); i++)
{
buf[a[i]]++;
}
for(int i=0; i<sizeof(b)/sizeof(*b); i++)
{
if( buf[b[i]] )
cout << b[i] << endl;
} return 0;
}

8. 面试时如何被问及期望的薪水,该如何回答?

(打听公司底薪+500)

9. 职场新人应该注意些什么问题?

(如果有的师傅不屌你,那么你就需要主动问师傅有什么杂活可以帮你做的,给师傅节省了时间,打好了关系,他才会也才有时间教你。不要坐着耗下去,因为即便跳槽也一样。)


1.有一个问题: C++定义一个空类,编译器都会做些什么??

(例如:定义Test空类

class Test
{
};

1:如果类中没有数据成员,那么编译器会给这个类分配固定的大小,VS是1,不可能是0

2:编译器会在类中放入构造函数、拷贝构造函数、赋值运算符、析构函数。

Test() {};

Test(const Test& obj) {};

Test& operator= (const Test& obj) {};

~Test() {};

2.二阶构造法【为解决半成品的构造对象】

(使用场所:当在构造函数里面申请资源,并且这个资源可能申请失败的时候

分析:相当于将申请资源的步骤分为两个阶段:

1:第一阶段申请不会出错的资源(类对象资源)

2:第二阶段申请可能出错的资源,并进行判断,出错返回NULL,否则返回完整对象

这样就有效地避免了半成品对象的产生!!!

4.对于一个给定的字符串,我们需要在线性(也就是O(n))的时间里对它做一些变形。
首先这个字符串中包含着一些空格,就像"Hello World"一样,然后我们要做的是把这个字符串中
由空格隔开的单词反序,同时反转每个字符的大小写。

比如"Hello World"变形后就变成了"wORLD hELLO"。

(分析:

步骤1:先将大小写字母反转;

步骤2:再将整个字符串反转;

步骤3:最后以空格为分界,每段的字符串再反转一次。

代码如下:

#include <iostream>
using namespace std; // 字符大小写反转
char change_char(char ch)
{
char ret = ch; if (('a' < ch) && (ch < 'z'))
{
ret = 'A' + ch - 'a';
}
else if (('A' < ch) && (ch < 'Z'))
{
ret = 'a' + ch - 'A';
} return ret;
} // 字符串反转
void reverse(char s[], int index, int len)
{
int i = index; // 第一个位置下标
int j = index + len - 1; // 最后一个位置下标 while ( i < j )
{
char t = s[i];
s[i] = s[j];
s[j] = t; i++; j--;
}
} void solution(char s[])
{
int len = strlen(s);
int i = 0; // 空间换时间
int* space = (int*)malloc(len * sizeof(int)); // 用来记录空格的位置
int* index = (int*)malloc(len * sizeof(int)); // 用来记录空格之后第一个字符的位置
int j = 0;
int k = 0; for (i = 0; i<len; i++)
{
s[i] = change_char(s[i]);
} cout << "1th: " << s << endl; reverse(s, 0, len); cout << "2th: " << s << endl; for (i = 0; i<len; i++)
{
if (s[i] == ' ')
{
space[j] = i; // 记录第一个空格下标位置
index[j] = k; // 记录第一个字符下标位置,就是起始的字符位置0 j = j + 1;
k = i + 1;
}
}
// 最后字符串的结束符当做空格处理,所以需要再写一次
space[j] = i;
index[j] = k; for (i = 0; i <= j; i++)
{
reverse(s, index[i], space[i] - index[i]);
} free(space);
free(index);
} int main()
{
char str[] = "Hello World!"; cout << "before: " << str << endl; solution(str); cout << "after: " << str << endl; return 0;
}

1、GetMemory函数用于申请一片内存空间,要使用二重指针。

void GetMemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
void main(void)
{
char *str=NULL;
GetMemory=(&str);
strcpy(str,"hello world");
printf(str);
}

2、列举几种进程的同步机制,并比较其优缺点。

答案:   原子操作  信号量机制     自旋锁    管程,会合,分布式系统  
 
3、进程之间通信的途径 
答案:共享存储系统消息传递系统管道:以文件系统为基础  
 
4、进程死锁的原因 
答案:资源竞争及进程推进顺序非法  
 
5、死锁的 4个必要条件 
答案:互斥、请求保持、不可剥夺、环路  
 
6、死锁的处理 
答案:鸵鸟策略、预防策略、避免策略、检测与解除死锁  
 
7、操作系统中进程调度策略有哪几种? 
答案:FCFS(先来先服务),优先级,时间片轮转,多级反馈

8、(void *)ptr  和 (*(void**))ptr 的结果是否相同?(其中 ptr为同一个指针)

答案:(void *)ptr  和 (*(void**))ptr值是相同的

9、要对绝对地址 0x100000 赋值,我们可以用  (unsigned int*)0x100000 = 1234;  那么要是
想让程序跳转到绝对地址是 0x100000 去执行,应该怎么做? 
答案:*((void (*)( ))0x100000 ) ( );

首先要将 0x100000 强制转换成函数指针,即: (void (*)())0x100000

然后再调用它: *((void (*)())0x100000)();

用 typedef 可以看得更直观些: 
typedef void(*)() voidFuncPtr;

*((voidFuncPtr)0x100000)();

(但是在gcc里面编译会出错,但是写成:
typedef void(*FuncType)();
FuncType pf = (FuncType)0x10000;
pf();
可以编译通过,只不过段错误。)

10、

11、


微软亚洲技术中心的面试题!!!
1.进程和线程的差别。
线程是指进程内的一个执行单元,也是进程内的可调度实体.
与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

2.测试方法

人工测试:个人复查、抽查和会审

机器测试:黑盒测试和白盒测试

unsigned short A = 10;
printf("~A = %u\n", ~A);

char c=128;
printf("c=%d\n",c);
输出多少?并分析过程

第一题,~A =0xfffffff5,int值 为-11,但输出的是uint。所以输出4294967285
第二题,c=0x80,以char的8位字节来看,最高位为1,是负数。所以在内存的存储方式为补码(补码 = 反码 + 1)所以~(10000000-1)=-128
这两道题都是在考察二进制向int或uint转换时的最高位处理。

#include<iostream.h>
#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef struct AA
{
        int b1:5;
        int b2:2;
}AA;
void main()
{
        AA aa;
        char cc[100];
         strcpy(cc,"0123456789abcdefghijklmnopqrstuvwxyz");
       memcpy(&aa,cc,sizeof(AA));
        cout << aa.b1 <<endl;
        cout << aa.b2 <<endl;
}
答案是 -16和1
首先sizeof(AA)的大小为4,b1和b2分别占5bit和2bit.
经过strcpy和memcpy后,aa的4个字节所存放的值是:
0,1,2,3的ASC码,即00110000,00110001,00110010,00110011
所以,最后一步:显示的是这4个字节的前5位,和之后的2位
分别为:10000,和01
因为int是有正负之分  所以:答案是-16和1

求函数返回值,输入x=9999;
int func ( x )
{
    int countx = 0;
    while ( x )
    {
        countx ++;
        x = x&(x-1);
    }
    return countx;
}
结果呢?
知道了这是统计9999的二进制数值中有多少个1的函数,且有
9999=9×1024+512+256+15
9×1024中含有1的个数为2;
512中含有1的个数为1;
256中含有1的个数为1;
15中含有1的个数为4;
故共有1的个数为8,结果为8。
1000 - 1 = 0111,正好是原数取反。这就是原理。
用这种方法来求1的个数是很效率很高的。
不必去一个一个地移位。循环次数最少。

struct bit
{   int a:3;
    int b:2;
    int c:3;
};
int main()
{
bit s;
char *c=(char*)&s;
   cout<<sizeof(bit)<<endl;
*c=0x99;
   cout << s.a <<endl <<s.b<<endl<<s.c<<endl;
     int a=-1;
   printf("%x",a);
return 0;
}
输出为什么是
4
1
-1
-4
ffffffff
因为0x99在内存中表示为 100 11 001 , a = 001, b = 11, c = 100
当c为有符合数时, c = 100, 最高1为表示c为负数,负数在计算机用补码表示,所以c = -4;同理
b = -1;

位域 :  
有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:    
struct 位域结构名    
{ 位域列表 };   
其中位域列表的形式为: 类型说明符 位域名:位域长度    
例如:    
struct bs   
{   
int a:8;   
int b:2;   
int c:6;   
};   
位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:    
struct bs   
{   
int a:8;   
int b:2;   
int c:6;   
}data;   
说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明:   
1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:    
struct bs   
{   
unsigned a:4   
unsigned :0 /*空域*/   
unsigned b:4 /*从下一单元开始存放*/   
unsigned c:4   
}   
在这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。
2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。   
3. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:    
struct k   
{   
int a:1   
int :2 /*该2位不能使用*/   
int b:3   
int c:2   
};   
从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。

(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?
答:为了实现链式表达式。 // 2分
例如 int length = strlen( strcpy( strDest, “hello world”) );

编写类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个函数。

标准答案:
// String的析构函数
String::~String(void)               // 3分
{
delete [] m_data;                    
// 由于m_data是内部数据类型,也可以写成 delete m_data;
}
// String的普通构造函数             
String::String(const char *str)      // 6分
{
if(str==NULL)                          
{
m_data = new char[1];    // 若能加 NULL 判断则更好
*m_data = ‘\0’;                      
}                                       
else
{
int length = strlen(str);           
m_data = new char[length+1];  // 若能加 NULL 判断则更好      
strcpy(m_data, str);                
}
}
// 拷贝构造函数
String::String(const String &other)   // 3分
{
int length = strlen(other.m_data);
m_data = new char[length+1];      // 若能加 NULL 判断则更好    
strcpy(m_data, other.m_data);         
}
// 赋值函数
String & String::operate =(const String &other)    // 13分
{
// (1) 检查自赋值                     // 4分
if(this == &other)
return *this;

// (2) 释放原有的内存资源            // 3分
delete [] m_data;

// (3)分配新的内存资源,并复制内容 // 3分
int length = strlen(other.m_data);
m_data = new char[length+1];         // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);

// (4)返回本对象的引用            // 3分
return *this;
}


请问下面程序有没有错误为什么?

(段错误: char *strcpy(char *dest, const char *src);是拷贝字符串的函数,s只是字符数组,在结尾没有’\0’字符。)

(strlen(a) = 255;因为char类型的范围为-256~255,当i=256时,a[256] = 1 0000 0000b, 产生截断,a[256]= 0,对于strlen来看相当于结束符。)




C/C++练习题(一)的更多相关文章

  1. Linux基础练习题(二)

    Linux基础练习题(二) 1.复制/etc/skel目录为/home/tuer1,要求/home/tuser1及其内部文件的属组和其它用户均没有任何访问权限. [root@www ~]# cp -r ...

  2. shell 脚本之 shell 练习题汇总

    整理了一些 shell 相关的练习题,记录到这里. 1. 请按照这样的日期格式 xxxx-xx-xx 每日生成一个文件,例如:今天生成的文件为 2013-09-23.log, 并且把磁盘的使用情况写到 ...

  3. MySQL练习题

    MySQL练习题 一.表关系 请创建如下表,并创建相关约束 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成 ...

  4. MySQL练习题参考答案

    MySQL练习题参考答案 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 思路: 获取所有有生物课程的人(学号,成绩) - 临时表 获取所有有物理课程的人(学号,成绩) - 临时表 根据[ ...

  5. mysql练习题-查询同时参加计算机和英语考试的学生的信息-遁地龙卷风

    (-1)写在前面 文章参考http://blog.sina.com.cn/willcaty. 针对其中的一道练习题想出两种其他的答案,希望网友给出更多回答. (0) 基础数据 student表 +-- ...

  6. 【UOJ#228】基础数据结构练习题 线段树

    #228. 基础数据结构练习题 题目链接:http://uoj.ac/problem/228 Solution 这题由于有区间+操作,所以和花神还是不一样的. 花神那道题,我们可以考虑每个数最多开根几 ...

  7. 【Java EE 学习 28 下】【Oracle面试题2道】【Oracle练习题3道】

    一.已知程序和数据 create table test1 (id int primary key, name ), money int); ,); ,); ,); ,); 要求根据下图写出相应的sql ...

  8. 从一道NOI练习题说递推和递归

    一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...

  9. 《java编程思想》读书笔记 暂停一段时间,改为上面的练习题

    发现个很尴尬的现象.我一天实在看得太快了...全写下 写博客都得一晚上.. 之前因为是第一次看这么厚的书,别人都说很难,以为会看很慢的.然而,已经完全学过Java的 我感觉没啥压力,越看越快....第 ...

  10. 很不错的sql练习题(select)

      创建表和输入数据 CREATE TABLE STUDENT (SNO VARCHAR(3) NOT NULL,    SNAME VARCHAR(4) NOT NULL,    SSEX VARC ...

随机推荐

  1. office2010安装不成功提示缺少MSXML 6.10.1129.0?

    office2010安装 1. office重装 由于之前重装系统后安装office2010很顺利,这次删除office2010,由于没有删除干净,在程序删除面板中误点删除了其他文件所致,所以在此安装 ...

  2. delphi 6数据库连接之长短模式(sqlserver)

    delphi 6数据库连接之长短模式(sqlserver) 标签: delphi数据库 2015-08-12 20:59 351人阅读 评论(0) 收藏 举报  分类: delphi(3)  版权声明 ...

  3. 如何获得 Microsoft Push Notification Service(MPNS)的最佳体验

    有很多同学抱怨MPNS的各种问题,其中包括服务超时.返回各种错误代码不知如何处理等等..今天我用一点时间来为大家介绍下如何处理和操作咱们的MPNS. 首先为大家明确一个问题,Microsoft Pus ...

  4. go 编译问题

    golang的编译使用命令 go build , go install;除非仅写一个main函数,否则还是准备好目录结构:GOPATH=工程根目录:其下应创建src,pkg,bin目录,bin目录中用 ...

  5. express session

    一.什么是session? 最近在学习node.js 的express框架,接触到了关于session方面的内容.翻阅了一些的博客,学到了不少东西,发现一篇博文讲的很好,概念内容摘抄如下: Sessi ...

  6. 【C#进阶】委托那些事儿(二)

    二.传统的委托 接下来讲一讲方法参数.下面以“餐馆服务员为客户下单”[2]的事件作为描述.一般对事件的做法分3个部分: 1. 方法参数 EventArgs,一般用于传送数据.在本例场景中 public ...

  7. 【C#进阶】委托那些事儿(一)

    一.简单的委托 1.1 委托的声明: C#当中,委托(delegate)是一种方法封装,也即委托对象可以作为一种传递方法的变量来使用. 委托也算是一种类,与类是平级的存在.在类中写delegate对象 ...

  8. 逆变(contravariant)与协变(covariant)

    逆变(contravariant)与协变(covariant)是C#4新增的概念,许多书籍和博客都有讲解,我觉得都没有把它们讲清楚,搞明白了它们,可以更准确地去定义泛型委托和接口,这里我尝试画图详细解 ...

  9. 网络请求 get 请求时, 如果参数中的字符带有+号

    网络请求 get 请求时, 如果参数中的字符带有+号, 今天前端在调用我的API时, 发现有个参数一直没法通过我后台的验证, 但是在前端查看时, 该参数结构又没有什么异常, 又是一番查找, 直到在后端 ...

  10. 三,mysql优化--sql语句优化之索引一

    1,需求:如何在一个项目中,找到慢查询的select,mysql数据库支持把慢查询语句,记录到日志中.供程序员分析.(默认不启用此功能,需要手动启用) 修改my.cnf文件(有些地方是my.ini) ...