练习题

来源:互联网 发布:edrawmax mac 注册码 编辑:程序博客网 时间:2024/04/28 00:09

3. 有以下程序段
    char   acArr[]= "ABCDE";
    char   *pcPtr;
    for(pcPtr = acArr; pcPtr < acArr + 5; pcPtr++)
    {
        printf("%s/n", pcPtr);
    }
    return;
    输出结果是(  )
    A) ABCD         B) A              C) E              D) ABCDE
                       B                 D                 BCDE
                       C                 C                 CDE
                       D                 B                 DE
                       E                 A                 E
答案:D

补充一个类似的题:

int main(){long ulCnt1 = 0,ulCnt2 = 0;char *ch = "aha!";while(*ch){switch(*ch){case 'a':case 'h':ulCnt2++;default:ulCnt1++;}ch++;}printf("%u,%u\n",ulCnt1,ulCnt2);return 0;}
结果为:4,3

执行过程,*ch的变化,由aha!变为ha!,再变为a!,直到最后一个字符!

若字符串改为:bhb!,则结果为:4,1

17.在函数内部定义的变量(静态变量、寄存器变量等特殊变量除外)的内存是在栈内存中,所以在定义函数内部的变量的时候,一定要保证

栈不能够溢出。如果临时变量占用空间较大,应该使用内存申请的方式(即使用malloc(sizeof(xxx))的方式),这样该变量指向的内存就是在堆内存中了,这样,程序返回时栈销毁而堆内存中的没有销毁。

20. int *(*ptr)();
    则以下叙述中正确的是(   )
    A) ptr是指向一维组数的指针变量
    B) ptr是指向int型数据的指针变量
    C) ptr是指向函数的指针,该函数返回一个int型数据
    D) ptr是指向函数的指针,该函数的返回值是指向int型数据的指针
答案:D

1. .struct tagAAA                                                                                  

{                                                                                           

    unsigned char ucId:1;

    unsigned char ucPara0:2;

    unsigned char ucState:6;

    unsigned char ucTail:4;

    unsigned char ucAvail;

    unsigned char ucTail2:4;

    unsigned long ulData;

}AAA_S; 

问:AAA_S在字节对齐分别为1、4的情况下,占用的空间大小是多少?

答案:9  12。字节对齐方式为1的情况下,ucId:1和ucPara0:2和用一个字节,ucState:6、unTail:4、ucAvail、ucTail2各占用一个字节,最后

long型占用4个字节,所以共占用9个字节;在4字节对齐时候,前五个变量占用4个字节,第5、6变量又占用4个字节,最后long型仍然是四

个字节,所以共使用12个变量。

2.typedef struct tagTest

  {

      UCHAR  ucFlag;

      ULONG  ulLen;     

  }TEST_S;


  TEST_S test[10];


四字节对齐方式时: sizeof(TEST_S) = ______, sizeof(test)________.

答案:8   80。第一个运算是针对结构体变量类型,第二个是针对具体的变量

4.#pragma pack(4)/*编译选项,表示4字节对齐*/

int main(int argc, char* argv[])

{

    struct tagTest1

    {

        short a;

        char d; 

        long b;    

        long c;    

    };

    struct tagTest2

    {

        long b;    

        short c;

        char d;

        long a;    

    };

    struct tagTest3

    {

        short c;

        long b;

        char d;     

        long a;    

    };

    struct tagTest1 stT1;

    struct tagTest2 stT2;

    struct tagTest3 stT3;

    

    printf("%d %d %d", sizeof(stT1), sizeof(stT2), sizeof(stT3));

    return 0;

}

#pragma pack()(编译选项结束)

请问输出结果是:_________

答案:12   12   16


6.以下程序的输出结果是________.

#include     <stdio.h>

int fun(int   x,int  y)

  static  int   m = 0;

  static  int   i = 2;

  i += m + 1;

  m = i + x + y;

  return  m;

}

void main()

{

  int   j = 4;

  int   m = 1;

  int   k;

  k = fun(j, m);

  printf("%d,", k);

  k=fun(j, m);

  printf("%d/n", k);

  return;

}

答案:8   17


8.在VRP中,实现了strncpy类似的函数,定义如下:
#define CHAR char
#define ULONG unsigned long
#define VOID void

#define MACRO_COPYWORLDLENGTH  4

CHAR *VOS_strncpy(CHAR *pcDest, const CHAR *szSrc, ULONG ulLength)
{
    CHAR *pcPoint = pcDest;
    
    if(( NULL == szSrc ) || ( NULL == pcDest ) )
    {
        return NULL;
    }
    
    while(ulLength && (*pcPoint = *szSrc))/*这里采用了在判断语句中赋值的方式(*pcPoint = *szSrc),建议尽量不使用*/
    {
        pcPoint++;
        szSrc++;
        ulLength--;
    }
    if(!ulLength)
    {
        *pcPoint = '/0';
    }
    return pcDest;
}

VOID main(VOID)
{
    CHAR szStrBuf[ ] = "1234567890";
    CHAR szStrBuf1[ ] = "1234567890";
    CHAR *szHelloWorld = "Hello World!";
    strncpy(szStrBuf, szHelloWorld, MACRO_COPYWORLDLENGTH);
    VOS_strncpy(szStrBuf1, szHelloWorld, MACRO_COPYWORLDLENGTH);
    printf("%s %s", szStrBuf, szStrBuf1);
}
程序的输出结果为________
答案:Hell567890 Hell

10. typedef struct Head 
   {  
       UCHAR  aucSrc[6];  
       ULONG  ulType;  
   } HEAD_S; 

在强制一字节对齐情况下,请指出sizeof(HEAD_S) = ________;
在强制二字节对齐情况下,请指出sizeof(HEAD_S) = ________;
在强制四字节对齐情况下,请指出sizeof(HEAD_S) = ________;
答案:10  10  12

11.union tagAAAA

{

    struct

    {

        char  ucFirst;

        short usSecond;

        char  ucThird;

    }half;

    long  lI;

}number;


struct tagBBBBB

{

    char  ucFirst;

    short usSecond;

    char  ucThird;

    short usForth;

}half;

                                                                                                

struct  tagCCCC

{

    struct

    {

        char  ucFirst;

        short usSecond;

        char  ucThird;

    }half;

    long  lI;

};

                                                                                                    

 在字节对齐为1下,sizeof(uniontagAAAA)、sizeof(struct tagBBBBB)、sizeof(struct tagCCCC)是____  ____  _____

 在字节对齐为4下,sizeof(uniontagAAAA)、sizeof(struct tagBBBBB)、sizeof(struct tagCCCC)是____  ____  _____

答案:4   6   8

      8   8   12

12.struct tagABC 

{                                                                                     

    char  cB;

    short sC;

    char  cD;

    long  lA;

}*pAbc;                                                                                    


pAbc = 0x100000;                                                                            

那么pAbc+0x100 = 0x_________; (ULONG)pAbc + 0x100 = 0x_________;(ULONG *)pAbc + 0x100 = 0x_________;(char *)pAbc + 0x100


= 0x_______;

答案:100C00  100100  100400  100100


14.下面的代码中,函数Test执行完毕后,打印的结果是 _____。

unsigned long g_ulGlobal = 0;

void GlobalInit(unsigned long ulArg)

{

    ulArg = 0x01;


    return;

}


void Test()

{

    GlobalInit(g_ulGlobal);

    printf("%lu", g_ulGlobal);

    return;

}

答案:0


16.以下程序的输出的结果是___________

#pragma pack(4)/*四字节对齐*/

int main(int argc, char* argv[])

{

    unsigned char puc[4];

    struct tagPIM

    {                                                                                                   

        unsigned char ucPim1;

        unsigned char ucData0:1;

        unsigned char ucData1:2;

        unsigned char ucData2:3;

    }*pstPimData;


    pstPimData = (struct tagPIM *)puc;


    memset(puc, 0, 4); //全部置0。(初始化puc,每一位初始化为0,块大小为4)

    pstPimData->ucPim1 = 1;

    pstPimData->ucData0 = 2;

    pstPimData->ucData1 = 3;

    pstPimData->ucData2 = 4;


    printf("%02X %02X %02X %02X/n", puc[0], puc[1], puc[2], puc[3]);

    return 0;

}

#pragma pack()/*恢复缺省对齐方式*/

答案:01   26   00   00

 Q1,4字节对齐下char是否还是1字节?

 Q2,pstPimData共占多少字节内存,即sizeof(pstPimData)的大小,ucPim1 占1个字节,后面三个变量共占1个字节,是这样吗??

解释 :上面那个叫做位结构,就是以二进制位为存储单元的。

memset(puc, 0, 4);

pstPimData->ucPim1 = 1;

pstPimData->ucData0 = 2;

pstPimData->ucData1 = 3;

pstPimData->ucData2 = 4;

由于ucData0的大小是1比特,赋值为2产生了溢出保留低位是0。


赋值以后的内存数据理论上应该是这样的(二进制):

0000 0001 0111 0000 0000 0000 0000 0000

第一字节--第二字节--第三字节--第四字节


但是,在Intel CPU中,使用的小尾字节序,所以内存中的二进制实际上是:

1000 0000 0110 0100 0000 0000 0000 0000

第一字节--第二字节--第三字节--第四字节

即将每次赋值的数都会把二进制反转过来。

0000 0001 变成了 1000 0000

100 变成了 001


当按照unsigned char大小读出来时CPU会对每个字节再反转过来解释,因此每个字节的二进制值分别是:

第一字节:0000 0001 = 0x01

第二字节:0010 0110 = 0x26(这里是十六进制,每四位二进制数为一位十六进制数)

第三字节及第四字节都是0


好了,解释的够全面了吧?ref here

注意:

1. 溢出,保留低位;

2. 第一次反转,是赋值存储时的反转,规则是按照每个变量定义的位数反转;第二次反转,是读取访问时的反转,按照整1ge字节读取,则是整个字节反转。


上面方法解释的繁琐了,这样更好理解,因为是小端(LittleEndian)方式存储,所以按照小端的方式来,即高位在高位,低位在低位,于是有:

ucData0是1比特,赋值2,保留低位0,放在高位;

ucData1是2比特,赋值3,保留低位11,继续放在高位,即ucData0的1比特位置前面;

ucData2是3比特,赋值4,二进制刚好3位100,继续放在高位,即ucData1的2比特的前面;

这样1字节8位还剩两位,补0,最后也就是00 100 11 0,对应的十六进制为:0X26。

ref here


补充一下额外知识点:

void *memset(void *s, int ch, unsigned n);

函数解释:将s中当前位置后面的n个字节 (typedef unsigned int size_t )用 ch 替换并返回 s 。即,将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大小由第三个参数指定, 这个函数通常为新申请的内存做初始化工作, 返回值为指向S的指针

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

Notes :

1. 一定要记住如果要把一个char a[20]清零,一定是 memset(a,0,20*sizeof(char));

2.一个例子

1
2
3
4
5
6
7
8
9
10
11
12
#include <string.h>
#include <stdio.h>
#include <memory.h>
 
int main(void)
{
    char buffer[]="Helloworld\n";
    printf("Buffer before memset:%s\n",buffer);
    memset(buffer,'*',strlen(buffer));
    printf("Buffer after memset:%s\n",buffer);
    return 0;
}
输出结果:
1
2
3
Buffer before memset:Helloworld
 
Buffer after memset:***********
也不一定就是把内容全部设置为ch指定的ASCII值,而且该处的ch可为int或者其他类型,并不一定要是char类型。

比如上例中可以这样:

memset(buffer,3,strlen(buffer));


%02X : 以十六进制长度为2的形式输出

02 表示不足两位,前面补0输出;出过两位,不影响

举例:

printf("%02X", 0x123); //打印出:123

printf("%02X", 0x1); //打印出:01


补充一下,%02X会格式化为大写,%02x会格式化为小写;%2x,不足两位也不补0.


19.UCHAR *pucCharArray[10][10]; 
  typedef
union unRec
  {
      ULONG ulIndex;  
      USHORT usLevel[6];  
      UCHAR   ucPos;  
  }REC_S;
  REC_S   stMax,*pstMax;

  四字节对齐方式时: sizeof(pucCharArray) = ______, sizeof(stMax)=_______, sizeof(pstMax)=________,sizeof(*pstMax)=________. 
答案:400(4*10*10)   12   4   12

Q1,联合体内各个成员变量分别占多少字节?(USHORT usLevel[6]占多少?一个USHORT不就2个了吗?)unRec占多少?

分别占4,12,1;unRec占12。//联合 成员共享内存,取最大的

Q2sizeof(pucCharArray) 为400,是因为pucCharArray是指针而占4个字节的吗?

20.typedef union unHead

{  

    UCHAR aucSrc [6];

    struct tagContent

    {

        UCHAR ucFlag[3];

        ULONG ulNext;

    }Content;

}HEAD_S;

32CPU,VC编译环境下: 

在强制一字节对齐情况下,请指出sizeof(HEAD_S) = ________;

在强制二字节对齐情况下,请指出sizeof(HEAD_S) = ________;

在强制四字节对齐情况下,请指出sizeof(HEAD_S) = ________;

答案:7   8   8

22.  struct BBB

    {

       long     lNum;

       char     *pcName;

       short    sDate;

       char     cHa[2];

       short    sBa[6];      

    }*p;

    p = 0x100000;

    p + 0x1 = 0x____

    (unsigned long)p + 0x1 = 0x______

    (unsigned long *)p + 0x1 = 0x______

    (char *)p + 0x1 = 0x______

答案:100018 100001 100004 100001


23.在4字节对齐的情况:

typedef struct tagRec

{

    long lA1;        

    char cA2;  

    char cA3;

    long lA4;

    long lA5;

} REC_S;


void main(int argc, char *argv[])

{

   REC_S stMax ;      

   printf("/r/n sizeof(stMax)= %d",sizeof(stMax));

   return;

}

输出结果为:

sizeof(stMax)=____

答案:16

24.void main ()

{

    unsigned long ulA = 0x11000000;

    printf("/r/n%x",*(unsigned char *)&ulA);

    return;

}

输出结果为:

答案:0

其实就是考的你,unsigned long ulA在内存怎么存储

由于采用小数端存储,所以内存中为:

00 00 00 11

(unsigned char *)&ulA指向第一位,所以为0


扩展一下,和本题无关

举个例子如下 

 struct test_s

  {

    unsigned char a;

    int b;

  };

  struct test_s s;

  s.a='a';

  printf("a=%c\n",s.a);

  printf("a=%c\n",*(unsigned char *)&s);  //两个printf打印的结果都是一样的

这里 &s为 struct test_s * 类型指针

强制类型转化为unsigned char *

再取unsigned char *指针对应的值,结构体struct test_s第一个元素就是unsigned char类型

所以*(unsigned char *)&s 就对应元素s.a



0 0
原创粉丝点击