Chinaunix首页 | 论坛 | 博客
  • 博客访问: 428552
  • 博文数量: 83
  • 博客积分: 2622
  • 博客等级: 少校
  • 技术积分: 1345
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-17 08:59
个人简介

一直在努力

文章分类

全部博文(83)

文章存档

2014年(3)

2013年(9)

2012年(46)

2010年(25)

分类: C/C++

2010-06-05 10:41:31

想说一说关于集中数据类型的sizeof问题,这题出现率40%

sizeof就是求在内存总占多少字节的问题,最基本的char 1字节 short 2字节 int 4字节

任何的指针都是4字节    sizeof(数组名)=数组占的大小(这里必须注意虽然数组名可作为只想数组首地址的指针,但是sizeof(数组名)求得的不是指针的大小,而是数组大小)

还有就是sizeof(结构体)    sizeof(联合体)

举两个例子    struct stu {

                                                  Char a;

                                                        Int b;

                                                        Char c; 

}

struct teacher {

                                                  Char a;

Char c; 

                                                        Int b;

}

Sizeof (stu) =12   ;内存中这样存储  char 空空空   int  char  空空空

内存4字节对其问题

Sizeof (teacher) =8   ;内存中这样存储  char char空空   int

关于联合体

Union std{

                                                  Char a[10]

                                                        Int b[3];

}

Sizeof(std)=12;    联合体公用内存,取其中所占内存最大的元素为联合体所占内存

以下为Windows NT下的32C++程序,请计算sizeof的值
       char  str[] = “Hello” ;
       char   *p = str ;
       int     n = 10;
1.
请计算
sizeof (str ) =  6  
sizeof ( p ) =   4  
sizeof ( n ) =   4 
void Func ( char str[100])
{
请计算
sizeof( str ) =   4  
}
void *p = malloc( 100 );
请计算
sizeof ( p ) =  4   

还有位段的问题如下

分析:

struct bit

{   int a:3;

    int  b:2;

    int c:3;

};

int main()

{

  bit s;

  char *c=(char*)&s;

   cout<

  *c=0x99;

   cout << s.a <

     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;

c为有符合数时, c = 100, c = 4,同理 b = 3

位域   

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有01 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,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;   

说明databs变量,共占两个字节。其中位域a8位,位域b2位,位域c6位。对于位域的定义尚有以下几点说明:  

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   

};   

从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。  

位域的使用位域的使用和结构成员的使用相同,其一般形式为: 位域变量名位域名 位域允许用各种格式输出。   

main(){   

struct bs   

{   

unsigned a:1;   

unsigned b:3;   

unsigned c:4;   

} bit,*pbit;   

bit.a=1;   

bit.b=7;   

bit.c=15;   

pri

 

二、 关于动态申请内存的问题    这题出现率极高,60%不为过

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 GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}

void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");  
printf(str);    
}
请问运行Test函数会有什么样的结果?
答:
1)能够输出hello
2 Test函数中也未对malloc的内存进行释放。
3GetMemory避免了试题1的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );
后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
   ...//
进行申请内存失败处理
}


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;
三、基本关键字的提问

常考的

Static   extern   volatile   const  register

register是把一个变量声明为寄存器变量,和auto相对,auto是让编译器自动决定那些变量放在寄存器里,显然让编译器去决定更合理,所以这个关键字不常用,而声明变量时不写auto的话则自动会成为auto变量, int a; 和auto int a;效果是一样的,这两个只需要了解。

const是什么含意?

我只要一听到被面试者说:“const意味着常数”,我就知道我正在和一个业余者打交道。去年Dan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:Embedded Systems Programming)的每一位读者应该非常熟悉const能做什么和不能做什么.如果你从没有读到那篇文章,只要能说出const意味着“只读”就可以了。尽管这个答案不是完全的答案,但我接受它作为一个正确的答案。(如果你想知道更详细的答案,仔细读一下Saks的文章吧。)如果应试者能正确回答这个问题,我将问他一个附加的问题:下面的声明都是什么意思?

const int a;

int const a;

const int *a;

int * const a;

int const * a const;

前两个的作用是一样,a是一个常整型数。第三个意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。第四个意思a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。最后一个意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答这些问题,那么他就给我留下了一个好印象。顺带提一句,也许你可能会问,即使不用关键字const,也还是能很容易写出功能正确的程序,那么我为什么还要如此看重关键字const呢?我也如下的几下理由:

1). 关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的。)

2). 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。

3).

阅读(785) | 评论(0) | 转发(0) |
0

上一篇:c面试问题

下一篇:新的开始

给主人留下些什么吧!~~