3-13面试

上午到衡态面试,感觉还行就是还是等通知,下午到浙江大华面试,做了面试题,然后等了一个小时才面试我,然后问了我一些问题,我答的不好,然后他就说现在这个岗位不适合我,意思就是我的基础太差了,也是他问我的问题有好多没有答上来,我看见有个女的也是面试c++,真是少见呢,女的不知为什么要搞软件开发呢。到晚上7点多到寝室。

现在把面试中遇到的问题总结一下:

1.下面这段代码输出什么

#include 
using namespace std ;
int main()
{
	char a[] = "123" ;
	char b[] = "123456789" ;
	strcpy(a, b) ;
	printf("%s, %s", a, b) ;
	system("pause") ;
	return 0 ;

}

具体来说这个代码会发生内存溢出的,a只分配了4个字节,而你要复制10个字节给他,是有问题,但我试验一下,输出是123456789, 123456789?

如果定义成char * a = "123" ; char *b = "123456789" ;然后strcpy(a, b) ;这样是不行的,因为a和b是指向常量的,而且自己没有分配内存,定义成数组自己就分配了内存,是可以的。

ps:返回局部变量:返回局部变量的值是正确的,但返回局部变量的地址就有问题了,因为是在栈上分配的,如果给内存被其他的值覆盖了,就不是你想要的值了。

ps: 栈是从高地址向低地址方向扩展的
1.普通变量按声明的变量顺序入栈,即高地址向低地址依次存放各个声音的变量
2.函数调用时,形参从右向左依次入栈
3.数组内部地址排列可能与平台有关,但是一般从低地址向高地址依次存放各个成员
4.类和结构体内部的数据成员先声明的会被放在高地址还是低地址处,完全由编译器实现来决定的
,而且一般都会采用"按照声明的先后顺序从低地址向高地址依次存放各个成员".
*/

2.静态链接库和动态链接库的区别

动态链接是指在生成可执行文件时不将所有程序用到的函数链接到一个文件,因为有许多函数在操作系统带的dll文件中,当程序运行时直接从操作系统中找。   
  而静态链接就是把所有用到的函数全部链接到exe文件中。
 动态链接是只建立一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入;   
          而静态链接是把所有的代码和数据都复制到本模块中,运行时就不再需要库了。
http://blog.sina.com.cn/s/blog_61ba4898010153zu.html

3.ifndef /define/endif的作用

一般用在头文件中,为了防止头文件重复包含而导致的重复定义。
头件的中的#ifndef,这是一个很关键的东西。比如你有两个C文件,这两个C文件都include了同一个头文件。而编译时,这两个C文件要一同编译成一个可运行文件,于是问题来了,大量的声明冲突。 
还是把头文件的内容都放在#ifndef和#endif中吧。不管你的头文件会不会被多个文件引用,你都要加上这个。一般格式是这样的: 
#ifndef <标识> 
#define <标识> 
...... 
...... 
#endif 
<标识> 在理论上来说可以是自由命名的,但每个头文件的这个“标识”都应该是唯一的。标识的命名规则一般是头文件名全大写,前后加下划线,并把文件名中的“.”也变成下划线,如:stdio.h 
#ifndef _STDIO_H_ 
#define _STDIO_H_ 
......

4.链表的创建

#include  /*这个头文件在动态的建立结点时要用到*/
/*
 * 这就是表示单链表的一个结点的结构体了,
 * 简单起见没有使用模板之类的复杂东西。
 */
struct Node
{
 /*这个表示结点的值,这里为了简单,就用int型的吧*/
 int data;
 /*
  * 这是指向结点结构体的一个指针,
  * 这里用它指向该结点的下一个结点,
  * 以此使单个的结点形成链表
  */
 struct Node* next;
};/*至此链表的结点就定义完了*/
 
 
int main()
{
    /*下面展示如何建立成为一个带头结点的单链表:L={12,13,21,24}*/
 struct Node* head= NULL; /*这是链表的头结点*/
 struct Node* p =NULL, *q = NULL; /*临时指针,建立链表时会用到*/
 
 /*链表很短,我不用循环,直接建立,可以让你看的更清楚*/
 
 /*建立头结点*/
 head = (structNode*)malloc(sizeof(struct Node));
 /*指定结点的值*/
 head->data =12;
 /*指定下一个结点,现在还没有先给NULL*/
 head->next =NULL;
 /*用q保存刚生成的结点*/
 q = head;
 
 /*第二个结点,建立的方法和第一个一样*/
 p = (structNode*)malloc(sizeof(struct Node));
 p->data = 13;
 p->next = NULL;
 /*注意,此时需要调整一下上一个结点的next指针,使各结点可以连接起来*/
 q->next = p;
 q = p;
 
 /*第三个结点*/
 p = (structNode*)malloc(sizeof(struct Node));
 p->data = 21;
 p->next = NULL;
 q->next = p;
 q = p;
 
 /*第四个结点,差不多应该发现可以写成个循环了吧!*/
 p = (structNode*)malloc(sizeof(struct Node));
 p->data = 24;
 p->next = NULL;
 q->next = p;
 q = p;
 
 /*到此链表建立完成!*/
 
 /* 用循环来写的话就是:
  * int i = 0;
  * int data[] ={12, 13, 21, 24};
  * for(i = 0; i< 4; i++)
  * {
  *  p = (struct Node*)malloc(sizeof(structNode));
  *  p->data = data[i];
  *  p->next = NULL;
  *  if(i == 0)
  *  {
  *   head = p;
  *  }
  *  else
  *  {
  *   q->next = p;
  *  } 
  *  q = p;
  * }
  */
 
    return 0;
}
5.memset的用法

void *memset(void *s,int ch,size_t n);函数解释:将 s 中前 n 个字节用 ch 替换并返回 s 。

memset:作用是在一段内存块中填充某个给定的值,它是对较大的结构体数组进行清零操作的一种最快方法[1]

如定义一个数组int a[20] ;

那可以memset(a, 0, 20) ;这个参数的顺序容易弄错。

你可能感兴趣的:(面试)