1.分析以下代码段,并解释输出结果和原因。
int main(int argc, char *argv[])
{
int nums[3][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
printf("%d\n", nums[1][-2] );
printf("%d\n", (-1)[nums][5] );
printf("%d\n", -1[nums][5] );
return 0;
}
我真不理解最后一个的写发,第二种就是把-1看成第一个index,但是…这么写…
2.分析以下代码段,给出输出结果,并给出自己的理解。
int a[3][2] = { 2, 0, 1, 8 };
char *str = (char *)malloc(sizeof(char) * 20); strcpy(str, "\0101\\xb2");
printf("%zu\n", sizeof(a));
printf("%zu %d\n", sizeof(a[1][1] =0), a[1][1]);
printf("%zu %zu\n", sizeof(str), strlen(str));
return 0;
sizeof返回表达式所占的字节数;a共有6个元素,所以是4 * 6; a[1][1] = 0 表达式所指的对象是一个int, 所以占4字节, 但是却不会进行赋值(weishenme啊); str是指针, 指针一般是占8个字节, strlen算到’\0’,就是\010 .1. \ x.b.2共6个。
3.参考所给代码,简要地谈一谈你对 static 关键字的理解。
static int a = 2018;
static void func(void) {
static int b;
printf("a = %d, b = %d\n", a++, ++b); }
int main()
{
func( );
func( );
func( );
return 0;
}
static 说明的是全局的变量,函数,就将其限定成该文件私有, 别的文件不能访问, 在局部变量中就只是将变成的生存期变成静态。
5.根据所给代码,说明 const 关键字的用法,指出标号为 (1)~(4) 的 代码哪些是错误的。
char y[ ] = “XiyouLinuxGroup”, x[ ] = “2018”;
char *const p1 = y;
const char *p2 = y;
/* (1) */ p1 = x;
/* (2) */ p2 = x;
/* (3) */ *p1 = 'x';
/*(4)*/ *p2='x';
*和 const谁前读谁, 指针常量不能改对象, 常量指针不能改指针。
6.猜想下面程序的输出,并谈谈自己的理解。
int a[5];
printf("%p\n", a);
printf("%p\n", a+1);
printf("%p\n", &a);
printf("%p\n", &a+1);
a 和 &a意义不同, 但是都是指针属性, 起始地址相同,
但是a + 1, a是int *, &a是int ()[5]所以加1便宜量不同。
8.分析以下函数,给出 f(2018) 的值,推测并验证函数的作用。
int f(unsigned int num)
{
for (unsigned int i = 0; num; i++) {
num &= (num - 1);
}
return i;
}
num 和 num - 1肯定会产生一个0(奇偶),并且将一个1的位位置0, 跳出循环的条件是所有位全为0, 也就是说,将所有1变成0, 统计1的个数。
9.分析以下代码段,解释输出的结果。 int main(int argc,
char *argv[])
{
char n[]={1,0,0,0}; printf("%d\n", *(int *)n);
return 0;
}
小端上数组从第地址向高地址写, 所以就是000000000···1
10.分析以下代码段,解释输出的结果。
#define YEAR 2018
#define LEVELONE(x) "XiyouLinux"#x"\n"
#define LEVELTWO(x) LEVELONE(x)
#define MULTIPLY(x,y) x*y
int main(int argc, char *argv[])
{
int x = MULTIPLY(1 + 2, 3);
printf("%d\n", x);
printf(LEVELONE(YEAR));
printf(LEVELTWO(YEAR));
}
宏的替换是照抄的替换, 所以优先级的括号要自己加, 然后
下一个似乎是因为 #运算符的作用, 让year变成字符串没有被直接替换
11.以下代码段输出的两个值相等吗?为什么?
struct icd {
int a;
char b;
double c;
};
struct cdi {
char a;
double b;
int c;
};
int main(){
printf("%zu %zu\n", sizeof(struct icd),
sizeof(struct cdi));
return 0;
}
默认的字节对齐市 1.a的偏移量, 必须是a的基本类型的整数倍或者a的最大基本数据类型整数倍。
2整个结构体大小必须是最大基础类型的整数倍
12.在以下代码段执行完毕后,文件Linux.txt中的内容是什么?
int main(int argc, char *argv[])
{
FILE *fp = fopen("Linux.txt", "wb");
long long a = 0x78756e694c;
fwrite(&a, sizeof(a), 1, fp);
fclose(fp);
}
wb写二进制文件(没有就创建), fwrite就是从&a开始,抄到 起始地址到后面sizeof(a)的东西, 抄1份, 写到fp的文件里
。
13.判断以下代码是否存在问题,如果有请找出并做适当的修改。
typedef struct a {
char *name;
int num;
} A;
void func(A *a) {
a = (A *)malloc(sizeof(A));
strcpy(a->name, "XiyouLinuxGroup");
a->num = 2018;
};
int main(){
A *a;
func(a);
printf("%s %d\n", a->name, a->num);
return 0;
}
想通过函数给外部的指针赋值, 结果传的是参数的copy,所以要改成传指针的指针。
void f(const char *str)
{
long long ans = 0;
char ch = *str;
char *p = str;
while (ch != '\0') {
ans = ans * 10 + ch - '0';
ch = *(++p);
}
printf("%lld", ans);
}
思路就是硬找‘\0’
15.编码题
使输入的整形数组的奇数位位于前半部分, 偶数位位于后半部分。
void f(int *a, int len)
{
int fnt = 0;
int tail = len;
int n = 0;
int temp[len];
while (n != len) {
if(*(a + n) % 2 != 0) temp[fnt++] = *(a + n);
else temp[--tail] = *(a + n);
n++;
}
int *p = a;
for (int i = 0; i < len ; i++)
*(p++) = temp[i];
}
这里偷个懒, 先抄到另一个数组再抄回来