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为指向函数的指针。