1.关于++a与a++

 

   int a = 5; 那么++(a++)的值是多少?

         

   说到这道题,我们先来研究++a与a++的区别,编译器对++a的调用,相当于int operator++ (int),可以看

   出,返回的依然是int类型,所以无论在a的左边无论有多少个++都是可以的。而对于a++则不同,在编译器中,

   相当于调用const int operator++ (),这里的const是一个常量,所以只能作为右值,不能再进行++,所

   以a++++就不合法了。另外++a执行后的结果还是保存在a中,即相当于a = ++a,而对于a++,执行后的结果是

   保存在一个临时变量中,这个临时变量是一个const右值,用后很快就会消失的。所以,上面的++(a++)编译会

   出错。

 

   那么,经过上面的分析,我们来看下面这个题就容易多了。

   int a = 3;

   int b = (++a) + (++a);

   int c = (a++) + (a++);

   求b和c的值。

 

   对于b来说,我们先看++a,它相当于a = ++a,执行完毕后,还有一个++a,所以得到a = 5,最终就

   是b = a + a = 10

 

   对于c来说,由于a++是先使用再++,即c = a + a = 6,而a++的结果是一个临时变量,后来就很快消失了,

   根本没有用到。

 

2.指针

 

   求下面的代码输出结果

   int a[5] = {1,2,3,4,5};

   int *p = (int *)(&a + 1);

   printf("%d %d\n",*(a+1),*(p-1));

 

   注意看清楚,这里是(&a + 1),而不是(a + 1),&a是指向数组的指针,是一个行指针,那么实际

   上(&a + 1)越界了,我们的p-1恰好是数组的最后一个元素,所以应该输出2 5。实际上一维数组可以看成是特

   殊的二维数组,即a[1][5],那么上面的代码与如下代码是等价的:


   int a[1][5] = {1,2,3,4,5};

   int *p = (int *)(&a + 1);

   printf("%d %d\n",*(a[0]+1),*(p-1));

 

3.char s[]与char *s

 

    char s1[] = "abc";

    char s2[] = "abc";

    char *s3 = "abc";

    char *s4 = "abc";

    cout<<(s1 == s2)<<endl;

    cout<<(s3 == s4)<<endl;


上面的代码会输出什么结果?

 

这就要来弄清楚char s[]与char *s的区别。对于char s[]来说,它是每次都会开辟一段内存空间来存储后面的

字符串内容,有自己的存储空间,无论字符串内容是否一样。而对于char  *s来说,是字符指针,不分配存储空

间,而后面的字符串内容存储于静态存储区,那么对应的所有s指针都指向这个常量字符串,所以应该输出0 1。

 

4.关于sizeof

    

sizeof不是函数,尽管它是这样sizeof(str),或许你不知道,它其实还可以这样sizeof str,所以sizeof在C++中其实是一个关键字。

 

 char s1[] = "abcdefg";

     char *s2 = "abcdefg";

 char s3[105] = "abcdefg";

 cout<<sizeof(s1)<<endl;

 cout<<sizeof(s2)<<endl;

 cout<<sizeof(s3)<<endl;

 

输出结果依次为8 4 105

首先对于s1它是数组名字,对于s1[] ,它在内存中开辟了空间,所以sizeof s1代表整个数组的长度,注意数组

末尾还有一个’\0’,所以长度为8。而对于s2,它是一个指针,我们知道指针存储的是地址,在C++中一个地址是

用4字节来存储的,所以s2永远是4。对于s3[105]来说,因为本身开辟了105字节的空间,所以输出105。

 

5.字符串拷贝函数

     

写一个函数,实现字符串拷贝功能,返回函数的指针,函数原型如下:

char *strcpy(char *strDest, const char *strSrc);


char *strcpy(char *strDest,const char *strSrc)
  {
      assert(strDest != NULL && strSrc != NULL);
      char *address = strDest;
      while((*strDest++ = *strSrc++) != '\0');
      return address;
}




为什么还要返回一个address,目的是实现链式表达式。

    

上面的拷贝中似乎已经达到很完美了,但是它只适用内存空间不重叠的情况。如果内存空间有重叠呢,就必须分情况进行正向拷贝或者逆向拷贝。


void *memcpy(void *strDest,const void *strSrc,size_t cnt)
    {     
           assert(strDest != NULL && strSrc != NULL);
           assert(cnt > 0);

           char *psrc = (char *)strSrc;
           char *pdest = (char *)strDest;
           if(pdest < psrc)
           {
                 while(cnt--)
                    *pdest++ = *psrc++;
           }
           else if(psrc < pdest)
           {
                 psrc += cnt - 1;
                 pdest += cnt - 1;
                 while(cnt--)
                    *pdest-- = *psrc--;
           }
           return strDest;
    }




6.常见指针

 

    int *p[n];     -----指针数组,每个元素均为指向整型数据的指针。

    int (*)p[n];   -----p为指向一维数组的指针,这个一维数组有n个整型数据。

    int *p();      ------函数返回指针,指针指向返回的值。

    int (*)p();    ------p为指向函数的指针。