本试题仅用于考查c++/c程序员的基本编程技能。内容限于c++/c常用语法,不涉及数据结构、算法以及深奥的语法。考试成绩能反映出
考生的编程质量以及对c++/c的理解程度,但不能反映考生的智力和软件开发能力。
笔试时间90分钟。请考生认真答题,切勿轻视。
一、请填写bool , float, 指针变量 与“零值”比较的 if 语句。(10分)
提示:这里“零值”可以是0, 0.0 , false或者“空指针”。例如 int 变量 n 与“零值”比较的 if 语句为:
if ( n == 0 )
if ( n != 0 )
以此类推。
请写出 bool flag 与“零值”比较的 if 语句:
请写出 float x 与“零值”比较的 if 语句:
请写出 char *p 与“零值”比较的 if 语句:
解答:
bool型变量:if(!var)
int型变量: if(var==0)
float型变量:
const float epsinon = 0.00001;
if ((x >= - epsinon) && (x <= epsinon)
指针变量: if(var==null)
二、以下为windows nt下的32位c++程序,请计算sizeof的值(10分)
char str[] = "hello" ;
char *p = str ;
int n = 10; 请计算 sizeof (str ) = 6
sizeof ( p ) = 4
sizeof ( n ) = 4
void func ( char str[100]) {请计算 sizeof( str ) =4 }
void *p = malloc( 100 ); 请计算 sizeof ( p ) = 4
数组名的本质如下:
(1)数组名指代一种数据结构,这种数据结构就是数组;
例如:
char str[10];
cout << sizeof(str) << endl;
输出结果为10,str指代数据结构char[10]。
(2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;
char str[10];
str++; //编译出错,提示str不是左值
(3)数组名作为函数形参时,沦为普通指针。
windows nt 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。
在vc6.0+win2k下做过试验:
short - 2
int-4
float-4
double-8
指针-4
三、简答题(25分)
1、头文件中的 ifndef/define/endif 干什么用?答:防止该头文件被重复引用。
2、#include 和 #include “filename.h” 有什么区别?
前者是从standard library的路径寻找和引用file.h,而后者是从当前工作路径搜寻并引用file.h
3、const 有什么用途?(请至少说明两种)
(1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
(2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
(3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
4、在c++ 程序中调用被 c编译器编译后的函数,为什么要加 extern “c”声明?
5、请简述以下两个for循环的优缺点
// 第一个
for (i=0; i
{
if (condition)
dosomething();
else
dootherthing();
}
// 第二个
if (condition)
{ for (i=0; i
dosomething();
}
else
{
for (i=0; i dootherthing();
}
优点: 缺点: 优点: 缺点:
四、有关内存的思考题(20分)
void getmemory(char *p)
{
p = (char *)malloc(100);
}
void test(void)
{
char *str = null;
getmemory(str);
strcpy(str, "hello world");
printf(str);
} 请问运行test函数会有什么样的结果? 答:传入中getmemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = null;
getmemory( str );
后的str仍然为null;
char *getmemory(void)
{
char p[] = "hello world"; return p;
}
void test(void)
{
char *str = null;
str = getmemory();
printf(str);
} 请问运行test函数会有什么样的结果? 答: char p[] = "hello world";
return p;
的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。
void getmemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void test(void)
{
char *str = null;
getmemory(&str, 100); strcpy(str, "hello");
printf(str);
} 请问运行test函数会有什么样的结果?答: getmemory避免了试题4的问题,传入getmemory的参数为字符串指针的指针,但是在getmemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
后未判断内存是否申请成功,应加上:
if ( *p == null )
{
...//进行申请内存失败处理
}
test函数中也未对malloc的内存进行释放
void test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != null)
{
strcpy(str, “world”);
printf(str);
}
} 请问运行test函数会有什么样的结果? 答:同样的问题,在执行
char *str = (char *) malloc(100);
后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = null; test函数中也未对malloc的内存进行释放
对内存操作的考查主要集中在:
(1)指针的理解;
(2)变量的生存期及作用范围;
(3)良好的动态内存申请和释放习惯。
五、编写strcpy函数(10分)
已知strcpy函数的原型是
char *strcpy(char *strdest, const char *strsrc);
其中strdest是目的字符串,strsrc是源字符串。
(1)不调用c++/c的字符串库函数,请编写函数 strcpy
(2)strcpy能把strsrc的内容复制到strdest,为什么还要char * 类型的返回值?
(1)char * strcpy( char *strdest, const char *strsrc )
{
assert( (strdest != null) && (strsrc != null) );
char *address = strdest;
while( (*strdest++ = * strsrc++) != ‘\\0’ );
return address;
}
六、编写类string的构造函数、析构函数和赋值函数(25分)
已知类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(const char *str)
{
if(str==null)
{
m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志'\\0'的空
//加分点:对m_data加null 判断
*m_data = '\\0';
}
else
{
int length = strlen(str);
m_data = new char[length+1]; // 若能加 null 判断则更好
strcpy(m_data, str);
}
}
// string的析构函数
string::~string(void)
{
delete [] m_data; // 或delete m_data;
}
//拷贝构造函数
string::string(const string &other) // 得分点:输入参数为const型
{
int length = strlen(other.m_data);
m_data = new char[length+1]; //加分点:对m_data加null 判断
strcpy(m_data, other.m_data);
}
//赋值函数
string & string::operate =(const string &other) // 得分点:输入参数为const型
{
if(this == &other) //得分点:检查自赋值
return *this;
delete [] m_data; //得分点:释放原有的内存资源
int length = strlen( other.m_data );
m_data = new char[length+1]; //加分点:对m_data加null 判断
strcpy( m_data, other.m_data );
return *this; //得分点:返回本对象的引用
}
试题1:请写一个c函数,若处理器是big_endian的,则返回0;若是little_endian的,则返回1
解答:
int checkcpu()
{
{
union w
{
int a;
char b;
} c;
c.a = 1;
return (c.b == 1);
}
}
试编写函数判断计算机的字节存储顺序是开序(little endian)还是降序(bigendian)
答:
bool isbigendian()
{
unsigned short usdata = 0x1122;
unsigned char *pucdata = (unsigned char*)&usdata;
return (*pucdata == 0x22);
}
与上一题比较
数据库:抽出部门,平均工资,要求按部门的字符串顺序排序,不能含有"human resource"部门,
employee结构如下:employee_id, employee_name, depart_id,depart_name,wage
答:
select depart_name, avg(wage)
from employee
where depart_name <> 'human resource'
group by depart_name
order by depart_name
--------------------------------------------------------------------------
29.
给定如下sql数据库:test(num int(4)) 请用一条sql语句返回num的最小值,但不许使用统计功能,如min,max等
答:
select top 1 num
from test
order by num desc
33.一个数据库中有两个表:
一张表为customer,含字段id,name;
一张表为order,含字段id,customerid(连向customer中id的外键),revenue;
写出求每个customer的revenue总和的sql语句。
建表
create table customer
(
id int primary key,name char(10)
)
go
create table [order]
(
id int primary key,customerid int foreign key references customer(id) , revenue float
)
go
--查询
select customer.id, sum( isnull([order].revenue,0) )
from customer full join [order]
on( [order].customerid=customer.id )
group by customer.id
32.简述critical section和mutex的不同点
答:
对几种同步对象的总结
1.critical section
a.速度快
b.不能用于不同进程
c.不能进行资源统计(每次只可以有一个线程对共享资源进行存取)
2.mutex
a.速度慢
b.可用于不同进程
c.不能进行资源统计
3.semaphore
a.速度慢
b.可用于不同进程
c.可进行资源统计(可以让一个或超过一个线程对共享资源进行存取)
4.event
a.速度慢
b.可用于不同进程
c.可进行资源统计
37.static变量和static 函数各有什么特点?
答:
static变量:在程序运行期内一直有效,如果定义在函数外,则在编译单元内可见,如果在函数内,在在定义的block内可见;
static函数:在编译单元内可见;
38.用c 写一个输入的整数,倒着输出整数的函数,要求用递归方法 ;
答:
void fun( int a )
{
printf( "%d", a%10 );
a /= 10;
if( a <=0 )return;
fun( a );
}
--------------------------------------------------------------------------
一个32位的机器,该机器的指针是多少位
答案:指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。
已知一个单向链表的头,请写出删除其某一个结点的算法,要求,先找到此结点,然后删除。
答案:slnodetype *delete(slnodetype *head,int key){}中if(head->number==key)
{
head=pointer->next;
free(pointer);
break;
}
back = pointer;
pointer=pointer->next;
if(pointer->number==key)
{
back->next=pointer->next;
free(pointer);
break;
}
void delete(node* p)
{
if(head = node)
while(p)
}
11,要对绝对地址0x100000赋值,我们可以用
(unsigned int*)0x100000 = 1234;
那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
答案:*((void (*)( ))0x100000 ) ( );
33,已知一个数组table,用一个宏定义,求出数据的元素个数
答案:#define ntbl
#define ntbl (sizeof(table)/sizeof(table[0]))
34。线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈?
答案:进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。
每个线程有自己的堆栈。
dll中有没有独立的堆栈,这个问题不好回答,或者说这个问题本身是否有问题。因为dll中的代码是被某些线程所执行,只有线程拥有堆栈,如果dll中的代码是exe中的线程所调用,那么这个时候是不是说这个dll没有自己独立的堆栈?如果dll中的代码是由dll自己创建的线程所执行,那么是不是说dll有独立的堆栈?
以上讲的是堆栈,如果对于堆来说,每个dll有自己的堆,所以如果是从dll中动态分配的内存,最好是从dll中删除,如果你从dll中分配内存,然后在exe中,或者另外一个dll中删除,很有可能导致程序崩溃
二、编程题(第一小题20,第二小题30分)
1、 不使用库函数,编写函数int strcmp(char *source, char *dest)
相等返回0,不等返回-1;
答案:一、
int strcmp(char *source, char *dest)
{
assert((source!=null)&&(dest!=null));
int i,j;
for(i=0; source[i]==dest[i]; i++)
{
if(source[i]=='\\0' && dest[i]=='\\0')
return 0;
else
return -1;
}
}
答案:二、
int strcmp(char *source, char *dest)
{
while ( (*source != '\\0') && (*source == *dest))
{
source++;
dest++;
}
return ( (*source) - (*dest) ) ? -1 : 0;
}
2、 写一函数int fun(char *p)判断一字符串是否为回文,是返回1,不是返回0,出错返回-1
答案:一、
int fun(char *p)
{
if(p==null)
return -1;
else
{
int length = 0;
int i = 0;
int judge = 1;
length = strlen(p);
for(i=0; i<length/2; i++)
{
if(p[i]!=p[length-1-i])
judge = 0;
break;
}
if(judge == 0)
return 0;
else
return 1;
}
}
答案:二、
int fun(char *p)
{
int len = strlen(p) - 1;
char *q = p + len;
if (!p)
return -1;
while (p < q) {
if ((*p++) != (*q--))
return 0;
}
return 1;
}
5. 用变量a给出下面的定义
a) 一个整型数(an integer)
b) 一个指向整型数的指针(a pointer to an integer)
c) 一个指向指针的的指针,它指向的指针是指向一个整型数(a pointer to a pointer to an integer)
d) 一个有10个整型数的数组(an array of 10 integers)
e) 一个有10个指针的数组,该指针是指向一个整型数的(an array of 10 pointers to integers)
f) 一个指向有10个整型数数组的指针(a pointer to an array of 10 integers)
g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(a pointer to a function that takes an integer as an argument and returns an integer)
h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( an array of ten pointers to functions that take an integer
argument and return an integer )
答案是:
a) int a; // an integer
b) int *a; // a pointer to an integer
c) int **a; // a pointer to a pointer to an integer
d) int a[10]; // an array of 10 integers
e) int *a[10]; // an array of 10 pointers to integers
f) int (*a)[10]; // a pointer to an array of 10 integers
g) int (*a)(int); // a pointer to a function a that takes an integer argument and returns an integer
h) int (*a[10])(int); // an array of 10 pointers to functions that take an integer argument and return an integer
9. 嵌入式系统总是要用户对变量或寄存器进行位操作。给定一个整型变量a,写两段代码,第一个设置a的bit 3,第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变。
最佳的解决方案如下:
#define bit3 (0x1<<3)
static int a;
void set_bit3(void)
{
a |= bit3;
}
void clear_bit3(void)
{
a &= ~bit3;
}
10. 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x
典型的类似代码如下:
int *ptr;
ptr = (int *)0x
*ptr = 0xaa55;
一个较晦涩的方法是:
*(int * const)(0x
1)写一个内存拷贝函数,不用任何库函数.就是前些时候本版讨论的那个问题.
void* memcpy(void* pvto, const void* pvfrom, size_t size)
{
assert((pvto != null) && (pvfrom != null));
byte* pbto = pvto;
byte* pbfrom = pbfrom;
while (size-- > 0)
{
*pbto++ = *pbfrom++;
}
return pvto;
}
5)将一个数字字符串转换为数字."1234" -->1234
int convert(char* str)
{
int k = 0;
while (*str != '\\0')
{
k = k * 10 + *s++ - '0';
}
return k;
}
string 系列
char * strcpy( char *strdest, const char *strsrc )
{
assert( (strdest != null) && (strsrc != null) );
char *address = strdest;
while( (*strdest++ = * strsrc++) != ‘\\0’ );
return address;
}
char* strncpy(char* strdest, const char* strsrc, int n)
{
assert((strdest != null) && (strsrc != null));
char* address = strdest;
while(n-- > 0)
*strdest++ = *strsrc++;
return address;
}
int strcmp(const char* str1, const char* str2)
{
assert((str1 != null) && (str2 != null);
int ret = 0;
while (!(ret = (unsigned char*)*str1 - (unsigned char*)*str2) && (*str2))
{
str1++;
str2++;
}
if (ret > 0)
ret = 1;
else if (ret < 0)
ret = -1;
return ret;
}
int strlen(const char* str)
{
assert(str != null);
int len = 0;
while ('\\0' != *str++)
len++;
return len;
}
*10)将一个数字字符串转换为数字."1234" -->1234
#i nclude<iostream>
using namespace std;
int f(char* s)
{
int k = 0;
while (*s)
{
k = 10 * k + (*s++)- '0';
}
return k;
}
int main()
{
int digit = f("4567");
cout<<digit<<endl;
cin.get();
}
8)将一个单链表逆序
struct test
{
int number;
double score;
test* next;
}
void reverse(test*& head)
{
test* pe = head;
test* ps = head->next;
while(ps != null)
{
pe->next = ps->next;
ps->next = head;
head = ps;
ps = pe->next;
}
}
单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。比如一个链表是这样的:
1->2->3->4->5
通过反转后成为5->4->3->2->1。
最容易想到的方法遍历一遍链表,利用一个辅助指针,存储遍历过程中当前指针指向的下一个元素,然
后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。源代码如下:
struct linka {
int data;
linka* next;
};
void reverse(linka*& head) {
if(head ==null)
return;
linka *pre, *cur, *ne;
pre=head;
cur=head->next;
while(cur)
{
ne = cur->next;
cur->next = pre;
pre = cur;
cur = ne;
}
head->next = null;
head = pre;
}
还有一种利用递归的方法。这种方法的基本思想是在反转当前节点之前先调用递归函数反转后续节点。
源代码如下。不过这个方法有一个缺点,就是在反转后的最后一个结点会形成一个环,所以必须将函数的
返回的节点的next域置为null。因为要改变head指针,所以我用了引用。算法的源代码如下:
linka* reverse(linka* p,linka*& head)
{
if(p == null || p->next == null)
{
head=p;
return p;
}
else
{
linka* tmp = reverse(p->next,head);
tmp->next = p;
return p;
}
}
*7)实现strcmp函数
int mystrcmp(const char* str1, const char* str2)
{
assert((str1 != null) && (str2 != null));
int ret = 0;
while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str2)
{
str1++;
str2++;
}
if (ret > 0)
ret = 1;
else if (ret < 0)
ret = -1;
return ret;
}
*6)实现strcpy函数
char* strcpy(char* dest, const char* src)
{
assert((dest != null) && (src != null));
char* address = dest;
while ('\\0' != (*dest++ = *src++));
return address;
}
2)写出二分查找的代码.
int binary_search(int* arr, int key, int n)
{
int low = 0;
int high = n - 1;
int mid;
while (low <= high)
{
mid = (high + low) / 2;
if (arr[mid] > k)
high = mid - 1;
else if (arr[mid] < k)
low = mid + 1;
else
return mid;
}
return -1;
}
1.说出下面这个程序的运行结果,并简要叙述其理由:
char buf1[10]="hello";
char buf2[10]="hello";
if (buf1==buf2)
printf("equal!");
else printf("not equal!");
因为buf1,buf2分配了不同的内存块,而比较的是数组名,实际上是两个分别指向数组起始元素地址的指针。
2.指出下面这段程序中存在一些什么问题:
int loop,a[5];
int* p=a;
for (loop=0;loop<5;loop++)
{ p++;
*p=loop;
}
数组a[5]在创建时没有初始化, 在for循环里也没有起到完全初始化数组的作用,而且对一块未知内存赋值。在最后一轮循环
结束时p指向了数组a[5]的最后一个元素的下一个地址。
c语言面试题及答案(1)
2007-04-06 17:54
1.
#include "stdio.h"
int main()
{
int a;
int *p;
p = &a;
*p = 0x500;//给a赋值
a = (int )(*(&p));//取p的地址的内容给a
a = (int )(&(*p));//取p指针的内容给a
if(a == (int)p)
printf("equal !\");
else
printf("not equal !\");
}
请问本程序的输出显示是什么?
答案:输出显示为”equal!”
2.
struct {
signed int bit0:1;
signed int bit1:1;
signed int bit2:1;
signed int bit3:1;
signed int bit4:1;
signed int bit5:1;
signed int bit6:1;
signed int bit7:1;
}bits;
请问sizeof(bits)是否是正确的表达式?
请问语句bits mybits; 的定义是否正确?如果不正确,要如何修改上述的结构定义才能使该语句正确?修改后的结构定义是否会影响sizeof(bits)的正确性?如果正确则该表达式的值为多少?如果将上述的结构中int类型改为char类型,此时sizeof(bits)的大小为多少?
答案:1)是正确的表达式,因为sizeof后面的内容可以是类型,也可以是变量。
2)该语句的定义不正确,因为此时的bits为一个变量;应该这样修改结构的定义
typedef struct {
signed int bit0:1;
signed int bit1:1;
signed int bit2:1;
signed int bit3:1;
signed int bit4:1;
signed int bit5:1;
signed int bit6:1;
signed int bit7:1;
}bits;
修改后sizeof(bits)表达式依然正确,其值为4;类型改为char后其值为1,注意该值是在vc环境中的32位程序中得到的值,在不同的编译器其值有可能不同,因此在编程时不能自己假定类似结构的大小。
3.
struct bit{
unsigned int a[0]:1,a[1]:1,a[2]:1….a[7]:1;
}
请问这种写法是否正确?为什么?
答案:不正确,位域中的变量不能是数组。
4.
struct a {
int x;
char y;
struct a z;
struct a *p;
}
请问这种定义结构正确否? 如果有问题,问题在哪里?
答案:结构中不能对定义结构本身的非指针变量,如果编译器支持则会导致无限嵌套,因此一般编译器都会认为struct a是未定义的类型,即使提前声明也不会有任何用处。
5. 什么是可重入函数?c语言中写可重入函数,应注意的事项?
答案:可重入函数是指能够被多个线程“同时”调用的函数,并且能保证函数结果的正确性的函数。在编写可重入函数时通常要注意如下的一些问题:
尽量不要使用全局变量,静态变量,如果使用了应该注意对变量访问的互斥。通常可以根据具体的情况采用:信号量机制,关调度机制,关中断机制等方式来保证函数的可重入性。
不要调用不可重入的函数,调用了不可重入的函数会使该函数也变为不可重入的函数。
注意对系统中的临界资源,互斥资源的访问方式,防止使函数成为不可重入的函数。
一般驱动程序都是不可重入的函数,因此在编写驱动程序时一定要注意重入的问题。
6. 简述stack frame 的含义。
答案:stack frame的中文译名为:栈框架,表示函数在栈空间的调用层次,以x86平台的函数调用为例,通常一个函数编译成汇编程序,都有如下的结构:
其中的leave指令相当于:mov ebp,esp ;pop ebp
各个函数在栈空间的映象为:
test1函数 test2函数 test3函数
因此在函数test3中,就可以根据这种栈框架的形式得到函数调用层次上的每个函数的基址指针,当前栈指针,以及函数调用点等信息。
7. printf (“%d%d\”,++n, power(2,n)); 其中power(2,n)为实现一定功能的函数 如 2^n 。
请问这种表示方法有什么潜在的问题?
答案:编译器的不同,对++n 和power(2,n)处理的先后顺序不一样,形成二义性,造成程
序的移植性差,因此最好把++n 写在printf函数外面,以消除二义性。
printf (s);
请问这样的语句有没有问题?(s为一指向有效字符串的指针)
答案:没有%的话,可以这样表达,如果有%在s中的话,有意想不到的输出结果。
9. 两段代码共存于一个文件,编译时有选择的编译其中的一部分,请问如何实现?
答案:有两种简单的办法可以实现:
在源码中使用条件编译语句,然后在程序文件中定义宏的形式来选择需
要的编译代码。
在源码中使用条件编译语句,然后在编译命令的命令中加入宏定义命令
来实现选择编译。
10.数据结构指针传给函数,函数能访问数据单元,但不能修改实际的内容,如何实现?
答案:定义为指向常量的指针,这样指针所指的数据结构中的内容就不会被改变。如:
const 类型 *p 或 类型 const *p
11. 在头文件中定义静态变量,可能产生什么问题?
答案:在使用了该头文件的每个c程序文件中都单独存在一个该静态变量,这样造成空间的浪费并且很容易引起错误。因此建议不要在头文件中定义任何变量。
12.malloc()与 calloc()的区别?
答案:
1)参数上的区别
malloc (size_t size);
calloc (size_t n , size_t size);
malloc分配一块size大小的内存块,而calloc分配一个n*size大小的内存块
2)返回内存块的状态不同
malloc分配的内存块没有被清零,而calloc分配的内存块是清了零的。但是建议在使用内存时,如果需要初始化,则最好自己按照需要来进行初试化,不要依赖函数的实现说明。
13.寄存器变量可不可以访问其地址?可否是全局变量?在什么场合使用寄存器变量?
答案:这些问题都与编译器的实现有关,建议不要声明全局变量为寄存器变量,即使是局部变量都最好不要声明其为寄存器变量,现在的编译器在优化时都会较为合理的安排寄存器变量的使用,而人为的安排有时会造成优化的低效。
14."\" '\' 的区别?
答案:前者是一个字符串并且以’/
15.包含预定义头文件< > 和" "的区别?
答案:< >只在指定的目录里寻找被包含文件;" "先在当前目录下查找 ,再在指定目录下查找;通常<>方式用于系统的头文件,而一般用户的头文件用" "的方式。
16.strunt s_a{
int a[10];
};
void f()
{
int i;
strunt s_a *s_ptr;
for (i=0,i<10,i++)
s_ptr -> a[i] = i;
}
请问这段代码正确否?
答案:这段代码不正确,没有对s_ptr指针进行初始化,在编程中要注意此类低级错误的发生。
10. 下面关于“联合”的题目的输出?
a)
#i nclude <stdio.h>
union
{
int i;
char x[2];
}a;
void main()
{
a.x[0] = 10;
a.x[1] = 1;
printf("%d",a.i);
}
答案:266 (低位低地址,高位高地址,内存占用情况是ox
b)
main()
{
union{ /*定义一个联合*/
int i;
struct{ /*在联合中定义一个结构*/
char first;
char second;
}half;
}number;
number.i=0x4241; /*联合成员赋值*/
printf("%c%c\", number.half.first, mumber.half.second);
number.half.first='a'; /*联合中结构成员赋值*/
number.half.second='b';
printf("%x\", number.i);
getch();
}
答案: ab (0x41对应'a',是低位;ox42对应'b',是高位)
6261 (number.i和number.half共用一块地址空间)
1.给两个数组和他们的大小,还有一动态开辟的内存,求交集,把交集放到动态内存dongtai,并且返回交集个数
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])
2.单连表的建立,把'a'--'z'26个字母插入到连表中,并且倒叙,还要打印!
方法1:
typedef struct val
{ int date_1;
struct val *next;
}*p;
void main(void)
{ char c;
for(c=122;c>=97;c--)
{ p.date=c;
p=p->next;
}
p.next=null;
}
}
方法2:
node *p = null;
node *q = null;
node *head = (node*)malloc(sizeof(node));
head->data = ' ';head->next=null;
node *first = (node*)malloc(sizeof(node));
first->data = 'a';first->next=null;head->next = first;
p = first;
int longth = 'z' - 'b';
int i=0;
while ( i<=longth )
{
node *temp = (node*)malloc(sizeof(node));
temp->data = 'b'+i;temp->next=null;q=temp;
head->next = temp; temp->next=p;p=q;
i++;
}
print(head);
3、用递归算法判断数组a[n]是否为一个递增数组。
递归的方法,记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束:
bool fun( int a[], int n )
{
if( n= =1 )
return true;
if( n= =2 )
return a[n-1] >= a[n-2];
return fun( a,n-1) && ( a[n-1] >= a[n-2] );
1、线形表a、b为两个有序升序的线形表,编写一程序,使两个有序线形表合并成一个有序升序线形表h;
答案在 请化大学 严锐敏《数据结构第二版》第二章例题,数据结构当中,这个叫做:两路归并排序
linklist *unio(linklist *p,linklist *q){
linklist *r,*pa,*qa,*ra;
pa=p;
qa=q;
r=ra=p;
while(pa->next!=null&&qa->next!=null){
if(pa->data>qa->data){
ra->next=qa;
qa=qa->next;
}
else{
ra->next=pa;
pa=pa->next;
}
}
if(pa->next!=null)
ra->next=pa;
if(qa->next!=null)
ra->next==qa;
return r;
}
试题5:编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”
函数头是这样的:
//pstr是指向以'\\0'结尾的字符串的指针
//steps是要求移动的n
void loopmove ( char * pstr, int steps )
{
//请填充...
}
解答:
正确解答1:
void loopmove ( char *pstr, int steps )
{
int n = strlen( pstr ) - steps;
char tmp[max_len];
strcpy ( tmp, pstr + n );
strcpy ( tmp + steps, pstr);
*( tmp + strlen ( pstr ) ) = '\\0';
strcpy( pstr, tmp );
}
正确解答2:
void loopmove ( char *pstr, int steps )
{
int n = strlen( pstr ) - steps;
char tmp[max_len];
memcpy( tmp, pstr + n, steps );
memcpy(pstr + steps, pstr, n );
memcpy(pstr, tmp, steps );
}


意见与建议
沪ICP证:沪B2-20070217 版权所有:东方财富网



