c语言相关练习理解

c语言相关练习学习有感

本文是我从csdn上一博主上看到 练习以及一些感悟

 原题可以去看这个作者的C语言入门必做踩坑题《篇一》_wh128341的博客-CSDN博客

1.递归题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>

int count = 0;//全局变量
int fib(int n)
{
count++;
if (n == 0)
{
return 1;
}
else if (n == 1)
{
return 2;
}
else return fib(n - 1) + fib(n - 2);
}
int main()
{
int ret=fib(5);
printf("%d\n", count);
printf("%d\n", ret);
return 0;
}

 2.栈返回问题,以及全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>
int a = 1;
void test()
{
int a = 2;
a += 2;//此处对a的变化并不会改变a的值
}
int main()
{
test();//返回栈空间的值,离开函数,内存销毁,
printf("%d\n", a);//a仍然是1,全局变量
return 0;
}

 3.全局变量的初始化及数据存储,sizeof的使用与比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
int i;//i作为全局变量,未初始化,都是0;signed型

int main()
{
i--;//-1
if (i > sizeof(i))//sizeof(i) 中计算的结果是unsigned型,
//而此时的i却是一个signed型,两者进行比较,i强制类型转化为unsigned型,i为-1.
//-1源码1000 0000 0000 0000 0000 0000 0000 0001
//反码1111 1111 1111 1111 1111 1111 1111 1110
//补码1111 1111 1111 1111 1111 1111 1111 1111>远大于4
{
printf(">");//因此结果是>
}
else
{
printf("<");
}
return 0;
}

4.数据存储,强制类型转换(有符号在char类型时就强制类型转换成int),数据截断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
int main()
{
unsigned char a = 200;//unsigned char 无符号整形,范围是0-256,而signed char 范围是在-127~128
unsigned char b = 100;
unsigned char c = 0;
c = a + b;
printf("%d %d\n", a + b, c);//a+b有符号参与就会整形提升a整数原反补相同
//00000000 00000000 00000000 11001000 a
//00000000 00000000 00000000 01100100 b
//00000000 00000000 00000001 00101100 c,结果是300
//而c是char类型的,会发生截断8位00101100 结果是44
return 0;
}

5.二维数组,强制类型转换,

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>
int main()
{
int arr[2][5] = { {10,9,8,7,6,},{5,4,3,2,1}};//
int *ptr1 = (int*)(&arr + 1);//arr是数组指针,里面存放的指针,强制类型转化为整形指针,
//每个元素是int型,&arr取出的是整数数组,&arr+1取到了1后的地址,

int *ptr2 = (int*)(*(arr + 1));//arr除在sizeof内部,和&arr之外,其数组名都是首元素地址,而二维数组的首元素地址是首行的地址
//arr+1得到的是第二行的地址,*(arr+1),对第二行进行解引用,得到的是第二行全部的元素,同时又强制转化位(int*)得到的是第二行第一个元素
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//*(ptr1 - 1)得到的是1,*(ptr2 - 1)得到的是6
return 0;
}

6.强制类型转换

1
2
3
4
5
6
7
8
#include<stdio.h>
int main()
{
int a[5] = { 5,4,3,2,1 };
int *ptr = (int *)(&a + 1);//&a取出的是a整个数组,&a+1指向1后面的地址,同时强制类型转化位(int*)类型
printf("%d, %d", *(a + 1), *(ptr - 1));//a是首元素地址,a+1是4的地址解引用得到4,ptr-1得到1的地址,解引用得到1
return 0;
}

7.联合体.大小计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
union un//计算联合体大小
//1.联合体大小至少是最大成员的大小,2.联合体内也有内存对齐,
//3.当最大对其数非最大对齐数的整数倍时,就要对齐到最大对其数的整数倍
//每个元素都从0对齐数开始,取最大值

{
short a[7];//最大对齐数为2,2*7=14,!=4的整数倍,故对其数为16,大小为16个字节
int n;//最大对齐数为4
};
int main()
{
printf("%d", sizeof(union un));
return 0;
}

8.联合体数据存储.存储方式,大小端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
int main()
{
union un
{
short k;
char i[2];
}*s, a;//*s为指针型,a是变量
s = &a;
s->i[0] = 0x39;//i[0]是16进制数
s->i[1] = 0x38;
printf("%d %x\n",a.k, a.k);//vs里面是小端存储,低数据存在内存低地址(从左向右)0x3839
return 0;
}

9.无符号型

1
2
3
4
5
6
7
8
9
10
11
int main()
{
unsigned char i = 7;//unsigned char 范围为0-255,而signed char 范围为-127到128
int j = 0;
for (; i > 0; i -= 3)//unsigned char 做减法并不会变成负数,7~4~1~254~直到i=0时循环停止,j一直加
{
++j;
}
printf("%d", j);//173
return 0;
}

c语言相关练习理解
http://example.com/2021/10/13/c语言相关练习理解/
作者
Zevin
发布于
2021年10月13日
许可协议