1.根据下面给出的声明和数据,对每个表达式进行求值并写出它的值。在对每个表达式进行求值时使用原先给出的值(也就是说,某个表达式的结果不影响后面的表达式)。假定ints数组在内存中的起始位置是100,整型值和指针的长度都是4字节。
解析:
其中两个表达式的答案无法确定,因为我们不知道编译器选择在什么地方存储ip。
int ints[20] = {
10, 20, 30, 40, 50, 60, 70, 80, 90, 100,
110, 120, 130, 140, 150, 160, 170, 180, 190, 200
};
(Other declarations)
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 | *(ip+4) | 80 |
ints[-2] | 非法 | ip[-2] | 20 |
&ints | 100 | &ip | 未知 |
&ints[4] | 116 | &ip[4] | 128 |
&ints + 4 | 420(modification) | &ip+4 | 未知 |
&ints[-2] | 非法 | &ip[-2] | 104 |
#include <stdio.h>
#include <stdlib.h>
int main( void ){
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;
printf( "ints[4] = %d, *ints + 4 = %d, *(ints + 4) = %d\n",
ints[4], *ints + 4, *(ints + 4) );
printf( "ip[4] = %d, *ip + 4 = %d, *(ip + 4) = %d, ip[-2] = %d\n",
ip[4], *ip + 4, *(ip + 4), ip[-2] );
printf( "&ints[4] = %d, &ints + 4 = %d\n", &ints[4], &ints + 4 );
/*
** can't pass compilation:
** because of [Error] invalid conversion from 'int' to 'int *'
** ip = 100;
*/
return EXIT_SUCCESS;
}
输出:
2.表达式array[i+j]和i+j[array]是不是相等?
解析:
不相等。第二个表达式因为[]的优先级高于+,所以先执行下标运算,再执行加法运算。第一个表达式先进行i+j运算,再进行其它运算。因此不相等。
#include <stdio.h>
#include <stdlib.h>
int main( void ){
int i, j;
int array[6] = { 1, 3, 3, 4, 5, 6 };
int value, value2;
i = 1;
j = 1;
value = array[i+j];
value2 = i + j[array];
printf( "value = %d, value2 = %d\n", value, value2 );
return EXIT_SUCCESS;
}
输出:
3.下面的声明试图按照从1开始的下标访问数组data,它能成功吗?
int actual_data[ 20 ];
int *data = actual_data - 1;
解析:
不能成功。它实际上是从下标为-1的数组访问元素。从1开始的下标访问数组应该为actual_data + 1。
#include <stdio.h>
#include <stdlib.h>
int main( void ){
int actual_data[ 20 ] = { 1, 2, 3, 4, 5, 6 };
int *data = actual_data - 1;
int *data2 = actual_data + 1;
printf( "*data = %d, actual_data[-1] = %d\n", *data, actual_data[-1] );
printf( "*data2 = %d, actual_data[1] = %d\n", *data2, actual_data[1] );
return EXIT_SUCCESS;
}
输出:
3.下面的循环用于测试某个字符串是否是回文,请对它进行重写,用指针变量代替下标。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
int main( void ){
char buffer[SIZE];
strcpy( buffer, "shuauhs" );
/* 计数器形式
int front, rear;
front = 0;
rear = strlen( buffer ) - 1;
while( front < rear ){
if( buffer[front] != buffer[rear] ){
break;
}
front += 1;
rear -= 1;
}
if( front >= rear ){
printf( "%s is a palindrome!\n", buffer );
}
*/
/* 指针形式 */
char *begin, *end;
int len;
len = strlen( buffer );
begin = buffer;
end = buffer + len - 1;
while( begin < end ){
if( *begin != *end ){
break;
}
begin++;
end--;
}
if( begin >= end ){
printf( "%s is a palindrome!\n", buffer );
} else{
printf( "%s is not a palindrome!\n", buffer );
}
r