表达式求值
根据下面给出的声明和数据,对每个表达式进行求值并写出它的值。在对每个表达式进行求值时使用原先给出的值(每个表达式的结果不影响后面的表达式)。假定ints数组在内存中的起始位置是100,整型值和指针长度都是4字节。
int ints[20] = {
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120, 130, 140, 150, 160, 170, 180, 190, 200
};
int *ip = ints + 3;
表达式 | 值 | 表达式 | 值 |
---|---|---|---|
ints | 100 | ip | 112 |
ints[4] | 50 | ip[4] | 80 |
ints + 4 | 116 | ip + 4 | 128 |
*ints + 4 | 14 | *ip + 4 | 44 |
*(ints + 4) | 50 | *(iip + 4) | 80 |
ints[-2] | 非法 | ip[-2] | 20 |
&ints | 100 | &ip | 未知 |
&ints[4] | 116 | &ip[4] | 128 |
&ints + 4 | 420 | &ip + 4 | 未知 |
&ints[-2] | 非法 | &ip[-2] | 104 |
指针与数组
指针与数据的关系
- 数组名指代一种数据结构,这种数据结构就是数组
- 数组名可以转为其指代实体的指针,而且是一个指针常量,不能自增、自减;不能被修改
- 数组名做为函数形参时,沦为普通指针
示例:
char str[10];
/**
* 结果为 10,此时指针可视为结构体,
* 计算方式如同sizeof(struct S),
* str有十个char,结果应为10.
*/
cout << sizeof(str) << endl;
/**
* 编译错误,str是常量,不能被修改
*/
str ++;
void foo(char str[10]) {
// 结果为sizeof(指针)的大小(WIN32 为4,64位平台为8).
cout << sizeof(str) << endl;
}
指针与数组的一题
下面的声明取自某个源文件:
int a[10];
int *b = a;
但在另一个不同的源文件中,却发现了这样的代码:
extern int *a;
extern int b[];
int x, y;
...
x = a[3]; // 1
y = b[3]; // 2
请解释当两条赋值语句执行时会发生什么?(假定整形和指针的长度都是4字节)
- 语句1中,编译器认为a是一个指针变量,所以它提取存储在那里的指针值,并加上12(3*4(整形长度值)),然后对这个结果执行间接访问操作。但a实际上是整型数组的起始位置,所以作为“指针”获得的这个值实际上是数组的第一个整形元素。它与12相加,其结果解释为一个地址,然后对它进行间接访问。作为结果,它或者将提取一些任意内存位置的内容,或者由于某种地址错误而导致程序失败。
- 语句2中,编译器认为b是一个数组名,所以它把12加到b的存储地址,然后间接访问操作从那里获得值。事实上,b是一个指针变量,所以从内存中提取的后面三个字实际上是从另外的任意变量中取得的。
- 指针和数组虽存在关联,但绝对不是相同的。
解释下面两种const关键字用法的显著区别所在
void function(int const a, int const b[])
- 第一个参数是标量,所以函数得到值的一份拷贝。对这份拷贝的修改并不会影响原先的参数,所以const关键字的作用并不是防止原先的参数被修改
- 第二个参数是一个指向整型的指针。传递给函数的是指针的拷贝 ,对它进行修改并不会影响指针参数本身,但函数可以通过对指针执行间接访问修改调用程序的值。const关键字用于防止这种修改。
- 顶层const(指针本身是常量)与底层const(指针所指对象是常量)
int i = 0;
// 顶层const, p1不可变
int *const p1 = &i;
// 顶层const,ci不可变
const int ci = 42;
// 底层const,p2可变,*p2不可变
const int *p2 = &ci;
// 靠左的为底层cosnt, 靠右为顶层const
const int *const p3 = p2;
// 用于声明引用的const都是底层const
const int &r = ci;
编写一个名叫my_strcpy_end的函数取代strcpy函数,它返回一个指向目标字符串末尾的指针(也就是说,指向NUL字节的指针),而不是返回一个指向目标字符串起始位置的指针
char* my_strcpy_end(char *dst, char *src) {
while((*dst++ = *src++