请试着解释其输出。
int main(int argc, char *argv[])
{
unsigned char a = 255;
char ch = 128;
a -= ch;
printf("a = %d ch = %d\n", a, ch);
}
char的范围是-128~127,所以给一个char赋128时,实际上计算机会把它当作-127。
unsigned char的范围是0~256。
下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
char *str = "Xi You Linux Group 20";
printf("%d\n", printf(str));
return 0;
}
Xi You Linux Group 2021
printf的嵌套使用,会先输出内部的printf,然后printf的返回值为输出的字符的多少,即在外层的printf输出的内容。
这段代码的输出结果是什么?为什么会出现这样的结果?
int i = 2;
void func()
{
if (i != 0)
{
static int m = 0;
int n = 0;
n++;
m++;
printf("m = %d, n = %d\n", m, n);
i--;
func();
}
else
{
return;
}
}
int main(int argc, char *argv[])
{
func();
return 0;
}
m = 1, n = 1
m = 2, n = 1使用static修饰符定义静态局部变量,它的生命周期是整个应用程序的运行时间,它只会被初始化一次。
下面程序会出现什么结果?为什么会出现这样的结果?
int main(int argc, char *argv[])
{
char ch = 'A';
int i = 65;
unsigned int f = 33554433;
*(int *)&f >>= 24;
*(int *)&f = *(int *)&f + '?';
printf("ch = %c i = %c f = %c\n", ch, i, *(int *)&f);
return 0;
}
ch = A i = A f = A
65是'A'的ASCII码。
*(int *)&f相当于作强制类型转换,在左移24位之后对应的10进制数字再加上'?'对应的ASCII码,即为'A'的ASCII码。
下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
int a[2][2];
printf("&a = %p\t&a[0] = %p\t&a[0][0] = %p\n", &a, &a[0],
&a[0][0]);
printf("&a+1 = %p\t&a[0]+1 = %p\t&a[0][0]+1= %p\n", &a + 1,
&a[0] + 1, &a[0][0] + 1);
return 0;
}
&a = 0x7fff765fd630 &a[0] = 0x7fff765fd630 &a[0][0] = 0x7fff765fd630
&a+1 = 0x7fff765fd640 &a[0]+1 = 0x7fff765fd638 &a[0][0]+1= 0x7fff765fd634(本机,本次)
数组的地址是数组内第一个元素的地址,地址+1则相当于指向下一个元素。在&a[0]中的元素是一维数组。
下列程序的功能是什么?有什么问题,你能找出问题并解决它吗?
int *get_array()
{
int array[1121];
for (int i = 0; i < sizeof(array) / sizeof(int); i++)
{
array[i] = i;
}
return array;
}
int main(int argc, char *argv[])
{
int *p = get_array();
}
该程序返回的是一个本地数组,出了该函数,就出了该数组的生命周期,可能导致出错。用指针创建该数组即可。
下面代码的运行输出结果是什么,并说说你的理解。
int main(int argc, char *argv[])
{
char str[] = "XiyouLinuxGroup";
char *p = str;
char x[] = "XiyouLinuxGroup\t\106F\bamily";
printf("%zu %zu %zu %zu\n", sizeof(str), sizeof(p),
sizeof(x), strlen(x));
return 0;
}
16 8 25 24
sizeof计算的是所占内存的大小。而strlen计算的是字符串的长度(不包含结尾的'\0')。
如下程序,根据打印结果,你有什么思考?
int add(int *x, int y)
{
return *x = (*x ^ y) + ((*x & y) << 1);
}
int a;
int main(int argc, char *argv[])
{
int b = 2020;
if (add(&b, 1) || add(&a, 1))
{
printf("XiyouLinuxGroup%d\n", b);
printf("Waiting for y%du!\n", a);
}
if (add(&b, 1) && a++)
{
printf("XiyouLinuxGroup%d\n", b);
printf("Waiting for y%du!\n", a);
}
return 0;
}
XiyouLinuxGroup2021
Waiting for y0u!^或运算,&与运算,<<右移
||在第一个式子成立后,不再进行第二个式子的判断,
&&在第一个式子不成立后,不再进行第二个式子的判断。
在下段程序中,我们可以通过第一步打印出 a 的地址,假如在你的机器上面打印结果是 0x7ffd737c6db4;我们在第二步用 scanf 函数将这个地址值输入变量 c 中;第三步,随机输入一个数字,请问最终输出了什么结果,你知道其中的原理吗?
void func()
{
int a = 2020;
unsigned long c;
printf("%p\n", &a);
printf("我们想要修改的地址:");
scanf("%lx", &c);
printf("请随便输入一个数字:");
scanf("%d", (int *)c);
printf("a = %d\n", a);
}
int main(int argc, char *argv[])
{
func();
}
运行开始输出的是a所在的地址,通过修改该地址的内容来达到修改a的值的作用。
请问一个 C 语言程序从源代码到可执行文件中间会进行哪些过程,你能简单描述一下每个环节都做了什么事情吗?
1、预处理
在预处理阶段,编译器主要作加载头文件、宏替换、条件编译的作用。一般处理带“#”的语句。
2、编译
在编译过程中,编译器主要作语法检查和词法分析。我们可以通过使用 -S 选项来进行查看,该选项预处理之后的结果翻译成汇编代码。
3、汇编
在汇编过程中,编译器把汇编代码转化为机器代码。
4、链接
链接就是将目标文件、启动代码、库文件链接成可执行文件的过程,这个文件可被加载或拷贝到存储器执行。
请解释一下这行代码做了什么?
puts((char *)(int const[]){
0X6F796958, 0X6E694C75, 0X72477875,
0X3270756F, 0X313230, 0X00000A});
定义了一个新数组const,并初始化。之后强制类型转换为char类型指针,其内容被作为char类型输出了出来。
请随机输入一串字符串,你能解释一下输出结果吗?
int main(int argc, char *argv[])
{
char str[1121];
int key;
char t;
fgets(str, 1121, stdin);
for (int i = 0; i < strlen(str) - 1; i++)
{
key = i;
for (int j = i + 1; j < strlen(str); j++)
{
if (str[key] > str[j])
{
key = j;
}
}
t = str[key];
str[key] = str[i];
str[i] = t;
}
puts(str);
return 0;
}
通过冒泡排序实现对字符的排序。其中使用fgets来读取用户的输入。
用循环和递归求 Fibonacci 数列,你觉得这两种方式那种更好?说说你的看法。如果让你求 Fibonacci 数列的第 100 项,你觉得还可以用常规的方法求解吗?请试着求出前 100 项的值(tip 大数运算)。
递归代码简洁,但时间复杂度高。循环代码较递归繁琐,但耗时短。
使用大数加法实现斐波那契数列
#include <stdio.h>
#include <string.h>
int a[1005][1005];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
int c;
int d=0;
memset(a,0,sizeof(a));
a[1][0]=1;a[2][0]=1;
for(int i=3;i<=n;i++)
{
c=0;
for(int j=0;j<=d;j++)
{
a[i][j]=a[i-1][j]+a[i-2][j]+c;
c=a[i][j]/10;
a[i][j]%=10;
}
while(c!=0)
{
a[i][++d]=c%10;
c/=10;
}
}
for(int i=d;i>=0;i--)
{
printf("%d",a[n][i]);
}
printf("\n");
}
return 0;
}