课内编程作业

编程作业

作业1

题目1

作业9

题目1

编写一个函数int add(int n),使用递归算法求1+2+3+…+n,在main函数中输入n,调用add函数后并输出计算结果。例如:

输入:10,输出:55

输出:100,输出:5050

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
int add(int n);

int main(void)
{
int n, sum;
scanf("%d", &n);
sum = add(n);
printf("%d", sum);
return 0;
}

int add(int n)
{
if(n > 0)
return (add(n-1) + n);
else
return 0;
}

题目2

编写一个函数void string_copy(char *f,char *t),功能是将f字符串得到t中,在main函数中定义两个字符数组char x[100], y[100],输入x字符串,调用string_copy函数将x字符串复制到y中,输出y字符串。例如:

输入:12345,输出:12345

输入:abcde,输出:abcde

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
#include<string.h>
void string_copy(char *f, char *t);

int main(void)
{
char x[100], y[100];
scanf("%s", x);

string_copy(x,y);

printf("%s", y);

return 0;
}

void string_copy(char *f, char *t)
{
strcpy(t,f);
}

题目3

编写一个从小到大排序(选择法)函数void sort(char (*p)[10],int n),其中n为整数个数。在main函数中输入n并输入n个国家英文名称,调用排序函数后输出。例如:

输入:5 China France Britain Russia America

输出:America Britain China France Russia

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <string.h>
void sort(char (*p)[10],int n);

int main(void)
{
char ch[100][10];
int n,m;
scanf("%d", &n);
for (m = 0; m < n; m++)
scanf("%s", ch[m]);

sort(ch,n);
for (m = 0; m < n; m++)
printf("%s ",ch[m]);
}

void sort(char (*p)[10], int n)
{
char a[10];
int m, j;

for(m = 0; m < n-1; m++)
for(j = m+1; j < n; j++)
{
if( strcmp(p[m],p[j]) > 0)
{
strcpy(a, p[m]);
strcpy(p[m],p[j]);
strcpy(p[j],a);
}
}
}

作业111

题目1

有n个学生,每个学生的数据包括姓名(10个字符)、出生日期(年-月-日),编写程序,功能是在main函数中输入n个学生信息,调用void sort(struct student stu[],int n)函数(按姓名从小到大排序)排序以后仍在main()中输出排序后的n个学生信息。输出时姓名和出生日期间用一个空格隔开,出生日期的输入输出格式为:yyyy-mm-dd。

例如:

输入:2

​ zhangsan

​ 2004-2-10

​ lisi

​ 2003-11-20

输出:lisi 2003-11-20

   #include<stdio.h>
   #include<string.h>
   #define LEN 50
   struct student{
       char name[10];
       int year;
       int month;
       int day;
   };

   void sort(struct student stu[], int n);

   int main(void)
   {
       int n, i;
       struct student stu[LEN];
       scanf("%d", &n);

       for (i = 0; i < n; i++)
       {
           scanf("%s%d-%d-%d", stu[i].name,&stu[i].year, &stu[i].month, &stu[i].day);
       }

       sort(stu, n);

       for(i = 0; i < n; i++)
       {
           printf("%s %d-%d-%d", stu[i].name,stu[i].year,stu[i].month,stu[i].day);    
           printf("\n");
       }    

       return 0;
   }

   void sort(struct student stu[], int n)
   {
       struct student change;
       int i,j;

       for (i = 0; i < n-1; i++)
           {
               for(j = i + 1; j < n; j++)
               {
                   if(strcmp(stu[i].name,stu[j].name) > 0)
                   {
                       change = stu[i];
                       stu[i] = stu[j];
                       stu[j] = change;
                   }
               }
           }
   }

题目2

编写一程序,功能是使用尾插法创建一个带有头结点的链表并输出。要求:先定义一个结构体,每个结点包含书号(10个字符)、书名(20个字符,不含空格)和价格(float型)等信息;然后编写一函数struct book *CreateLink()用于创建指定个数(个数n由键盘输入)的链表和函数void PrintLink(struct book *h)用于输出链表信息;最后在main中调用CreateLink和PrintLink函数。输入输出时每个数据间用一个空格隔开,价格的小数保留2位。例如:

输入:2

​ 00001 yuwen 18.20

​ 00002 shuxue 21.59

输出:00001 yuwen 18.20

​ 00002 shuxue 21.59

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct book{
char book_number[10];
char book_name[20];
float value;
struct book *next;
};

struct book *Createlink(int n);
void PrintLink(struct book*h);

int main(void)
{
int n;
struct book *h;
scanf("%d", &n);
h = Createlink(n);
PrintLink(h);

return 0;
}


struct book *Createlink(int n)
{
struct book *h, *p, *r;
int i;
h = (struct book*)malloc(sizeof(book));
h->value = NULL;
r = h;
for(i = 0; i < n; i++)
{
p = (struct book*)malloc(sizeof(book));
scanf("%s", p->book_number);
scanf("%s", p->book_name);
scanf("%f", &(p->value));
r->next = p;
p->next = NULL;
r = p;
}
return h;
}


void PrintLink(struct book*h)
{
struct book *p;
p = h->next;
while(p!=NULL)
{
printf("%s %s %.2f\n", p->book_number, p->book_name, p->value);
p = p->next;
}
}

实验程序

实验1

题目1

题目2

题目3

题目4

实验2

题目1

题目2

题目3

编写程序,功能是输入某年某月某日,输出这一天是这一年的第几天。闰年的条件是:能被4整除但不能被100整除,或者能被400整除。运行程序,输入数据(年月日用英文格式“-”连接)并检查结果是否正确。例如:

输入:2020-10-1,输出275

输入:2022-10-1,输出:274。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
int main(void)
{
int year, month, day, sum;
scanf("%d-%d-%d", &year, &month, &day);
sum = 0;
switch(month -1)
{
case 11: sum += 30;
case 10: sum += 31;
case 9: sum += 30;
case 8: sum += 31;
case 7: sum += 31;
case 6: sum += 30;
case 5: sum += 31;
case 4: sum += 30;
case 3: sum += 31;
case 2: if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
sum += 29;
else
sum += 28;
case 1: sum += 31;
}
sum += day;
printf("%d", sum);
return 0;
}

题目4

题目5

实验3

题目1

编写程序,求S=1+2+3+……加到哪一个正整数,S的值刚好超过1000,输出该整数。

程序无输入,输出:45

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
int main(void)
{
int sum, n;
sum = 0;
for (n=1; sum <= 1000; n++)
{
sum += n;
}

printf("%d", n-1);

return 0;
}

题目2

编写程序,输出[m, n]区间的所有素数(即质数),每个素数之间用一个空格隔开,其中m和n由键盘输入,且m<n。

输入:2 20,输出:2 3 5 7 11 13 17 19

输入:100 150,输出:101 103 107 109 113 127 131 137 139 149

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
int main(void)
{
int n, m, i, x, y;

scanf("%d%d", &m,&n);
for (; m<=n; m++)
{
y = 0;

if(m == 2 || m == 3)
{
printf("%d ", m);
continue;
}

for(x = 2; x*x <= m; x++)
{
if(m%x ==0)
y++;
}

if(y==0)
printf("%d ", m);
}
return 0;
}

题目3

编写程序,输出如下规律字母图形(本图行数n=6),其中行数n由键盘输入,第1行左侧无空格。

输入:6,输出: ABCDEFEDCBA

​ ABCDEDCBA

​ ABCDCBA

​ ABCBA

​ ABA

​ A

输入:3,输出:

​ ABCBA

​ ABA

​ A

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
int main(void)
{
int n, m, i;

scanf("%d", &n);
for(m = 0; m < n; m++)
{
for(i = 0; i < m; i++)
printf(" ");
for(i = 0; i < n -1 - m ; i++ )
printf("%c", 'A' + i );
for(; i >= 0; i--)
printf("%c", 'A' + i );
/* for(i = 0; i <= m ;i ++)
printf(" ");*/
printf("\n");
}

return 0;
}

题目4

编写程序,计算自然常数e近似值,精度由键盘输入q值控制,输出时显示6位小数。其中计算e公自然常数e近似值,

精度由键盘输入q值控制,输出时显示6位小数。其中计算e公式如下:

e1+1/1!+1/2!+1/3!+1/4!+e≈1+1/1!+1/2!+1/3!+1/4!+⋯

例如:

输入:0.001,输出:2.718254

输入:0.0001,输出:2.718279

输入:0.00001,输出:2.718282

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
int main(void)
{
float e, f, h;
int i;

i = 1;
e = 1;
h = 1;
scanf("%f", &f);

do
{
h *= i;
e += 1.0/h;
i++;
}while( 1.0/h >= f);

printf("%.6f", e);
return 0;
}

题目5

输入如下程序代码。编程的本意是:1~100的整数,遇到5的倍数就跳出,否则累加。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main()
{
int i = 1,sum = 0;
while (i <= 100)
{
if(i % 5 == 0)
continue;
else
sum += i;
i++;
}
printf("sum=%d",sum);
return 0;
}

试分析以上程序可能存在的问题,应如何改进。

程序运行无输入,输出:sum=4000

修改后的程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
int main(void)
{
int i = 0, sum = 0;
while(i <= 99)
{
i++;
if(i % 5 == 0)
continue;
else
sum += i;
}
printf("sum=%d", sum);
return 0;
}

实验4

题目1

编写一程序,输入三个整数a、b、c,并定义三个指针变量pa、pb、pc分别引用它们,并按降序输出,输出时数据间用一个空格隔开。例如:

输入:1 3 5,输出:5 3 1

输入:50 34 65,输出:65 50 34

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
int main(void)
{
int a, b, c, d, n, *pa, *pb, *pc;
scanf("%d%d%d", &a, &b, &c);

pa = &a;
pb = &b;
pc = &c;

if(*pa < *pb)
{
d = *pb;
*pb = *pa;
*pa = d;
}
if(*pa < *pc)
{
d = *pc;
*pc = *pa;
*pa = d;
}
if(*pb < *pc)
{
d = *pc;
*pc = *pb;
*pb = d;
}


printf("%d %d %d", *pa, *pb, *pc);
return 0;
}

题目2

编写一程序,输入n个成绩,然后使用指针变量p输出高于平均值的各个成绩,输出时成绩保留1位小数,成绩间用一个空格隔开。

输入:5 76 87 67 90 60,输出:87.0 90.0

输入:10 67 87 99 76 70 87 64 45 89 80,输出:87.0 99.0 87.0 89.0 80.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h>
#define SIZE 100
int main(void)
{
float a[SIZE], *p, aver;
int n, j;
aver = 0;

scanf("%d",&n);

for( j=0;j < n; j++)
{
scanf("%f", &a[j]);
aver += a[j];
}
aver = aver / n ;
p = a;

for(j=0; j<n; j++)
{
if(*(p + j) > aver)
printf("%.1f ", *(p+j));
}

return 0;
}

题目3

编写一程序,首先定义一个容量15的数组(如:int a[15]),输入n(n<15)个数,然后使用选择法对这n个进行升序排序后输出;再输入一个数并插入到已排好序的数组中并保持有序,最后输出这n+1个数。输出时每个数据间用一个空格隔开。

输入:5

4 5 2 9 3

第1次输出:2 3 4 5 9

再输入:6

第2次输出:2 3 4 5 6 9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
int main(void)
{
int a[15], n, j, k, t;

scanf("%d", &n);

for (j = 0; j < n; j++)
scanf("%d", &a[j]);

for (j = 0; j < n-1; j++)
{
for(k = j+1; k < n; k++)
{
if(a[j] > a[k])
{
t = a[j];
a[j] = a[k];
a[k] = t;
}
}
}
for (j = 0; j < n; j++)
printf("%d ", a[j]);
printf("\n");
scanf("%d", &a[n]);

for (j = 0; j < n; j++)
{
for(k = j+1; k < n + 1; k++)
{
if(a[j] > a[k])
{
t = a[j];
a[j] = a[k];
a[k] = t;
}
}
}

for (j = 0; j < n+1; j++)
printf("%d ", a[j]);
return 0;
}

题目4

编写一程序,输入以下4×4矩阵,并将其转置,即行列互换,然后使用指向一维数组的指针变量(int (*q)[4])输出转置后的矩阵。输出时每个数据间用一个空格隔开。

转置换

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

转置后

1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <stdio.h>
int main(void)
{
int a[4][4], r, c, (*q)[4], t;

for (r = 0; r < 4;r++)
{
for (c = 0; c < 4 ; c++)
{
scanf("%d", &a[r][c]);
}
}

for(r = 0; r < 4; r++)
{
for(c = 0; c < 4; c++)
{
t = a[r][c];
a[r][c] = a[c][r];
a[c][r] = t;
}
}
q = a;
for (r = 0; r < 4; r++)
{
for(c = 0; c < 4; c++)
printf("%d ", *(*(q+c)+r));
printf("\n");
}

return 0;
}

题目5

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main()
{
int i=0;
int a[]={1,2,3,4,5,6,7,8,9,10};
for(i=0;i<=10;i++)
{
a[i]=0;
printf("Hello World!\n");
}
return 0;
}

试分析以上程序可能存在的问题,为什么,以后应如何避免出现类似的问题。

1
2
3
// 数组a的索引是从0开始到9,而不是到10
// 可以利用sizeof(a)/sizeof(a[0])得出数组长度再减去1
// 这样就避免了认为的错误

实验5

题目1

编写一程序,功能是输入一个字符串,输出字符串的长度,不能使用strlen函数。例如:

输入:abcd123 输出:7

输入:!@#$ABC123 输出:10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main(void)
{
char ch[100];
int n = 0;
scanf("%s",ch);

while(ch[n] != '\0' && ch[n] !='\n')
{
n++;
}

printf("%d",n);

return 0;
}

题目2

编写一程序,功能是输入一个字符串,分别统计大写字母、小写字母、数字和其它字符的个数,并输出各类字符的个数,数字间用一个空格隔开。例如:

输入:!@#$ ABC abc 123,输出:3 3 3 7

输入:&*AbdEF12G4,输出:4 2 3 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <string.h>
int main(void)
{
char ch[100];
int big, small, count, other, n, j;
big = small = count = other = 0;
gets(ch);
n = strlen(ch);
for(j = 0; j < n; j++)
{
if(ch[j] >= 'A' && ch[j] <= 'Z')
big++;
else if(ch[j] >= 'a' && ch[j] <= 'z')
small++;
else if(ch[j] >= '0' && ch[j] <= '9')
count++;
else
other++;
}
printf("%d %d %d %d", big, small, count, other);

return 0;
}

题目3

编写一程序,功能是输入一个字符串,删除尾部连续的“*”号,前导和中间的保留。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
输入:ab*c*12*3****,输出:***ab*c*12*3

输入:**12*78*89,输出:**12*78*89

#include <stdio.h>
#include <string.h>
int main(void)
{
char ch[100];
int n, j;
scanf("%s", ch);
n = strlen(ch);
for(j = n - 1; j >= 0; j--)
{
if(ch[j] == '*')
ch[j] = '\0';
else
break;
}
printf("%s", ch);

return 0;
}

题目4

编写一程序,功能是输入一个身份证号,把身份证号的第7~14位替换成*,并把末位字母转换为大写。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
输入:35010120031005123x,输出:350101********123X。

#include <stdio.h>
int main(void)
{
int n;
char ch[18];
scanf("%s", ch);

for (n = 6; n <= 13; n++)
{
ch[n] = '*';
}
if(ch[17] == 'x')
ch[17] ='X';
printf("%s",ch);

return 0;
}

题目5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
输入如下程序代码。
#include<stdio.h>
#include<string.h>
int main() {
char password[1024];
int valid;
char buffer[8];
while (1) {
printf("请输入密码\n");
scanf("%s", password);
valid = strcmp(password, "1234567");
strcpy(buffer, password);
if (valid) {
printf("登录失败\n");
}
else {
printf("登录成功\n");
break;
}
}
return 0;
}
编译运行以上程序,分别输入:11111111(8位)、123456722222222(8位)等三个密码,观察运行情况,试分析为什么会出现这种情况,应如何避免出现类似的问题。

#include<stdio.h>
#include<string.h>
int main() {
char password[1024];
int valid;
char buffer[8];
while (1) {
printf("请输入密码\n");
scanf("%s", password);
valid = strcmp(password, "1234567");
strncpy(buffer, password,8);
if (valid) {
printf("登录失败\n");
}
else {
printf("登录成功\n");
break;
}
}
return 0;
}

实验6

题目1

编写一函数int swap(int x,int y),功能是交换两个数并返回两数之和。在main函数中输入两个数x和y,调用swap函数后,输出交换后的两个数x、y以及两数之和(每个数后留一个空格)。例如:

输入:3 5

输出:5 3 8

输入:8 3

输出:3 8 11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stdio.h>
int swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
return 0;
}

int main()
{
int x,y;
scanf("%d%d",&x,&y);
swap(&x,&y);
printf("%d %d %d",x,y,x+y);
return 0;
}

题目2

写一函数void radix(int x,int d),功能是使用递归调用方法将十进制数x转化为d(如2、8)进制并输出。在main函数中输入正整数x和d(2或8)后调用radix函数。

输入:23 2

输出:10111

输入:31 8

输出:37

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>
void radix(int x, int d);
int main(void)
{
int x,d;
scanf("%d%d", &x, &d);
radix(x,d);
return 0;
}

void radix(int x, int d)
{
int a, b;
if(x < d)
{
printf("%d", x);
}
else
{
a = x;
x = x/d;
radix(x,d);
printf("%d", a%d);

}

}

题目3

编写两个函数void sort(int a[],int n)和int search(int a[],int n,int x),其中sort功能是对传入的n个数进行升序排序;search功能是使用折半查找法(即二分法)在一组有序(升序)的n个数中查找指定数x,若找到,返回x在该组数中的位置(下标+1),若没找到,则返回-1。在main函数中输入n及n个数,调用sort函数后输出;再输入一个数x,调用search函数后,输出查找结果,若找到输出位置(如:Position:3),若没有找到,则输出:No find。注意:输出时英文大小写,以及Position后的冒号为英文格式。例如:

输入:10

21 34 5 22 43 65 78 31 65 9

输出:5 9 21 22 31 34 43 65 65 78

输入:34

输出:Position:6

再如:

输入:8

23 45 21 54 78 54 31 17

输出:17 21 23 31 45 54 54 78

输入:19

输出:No find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include<stdio.h>
#define N 99
void sort(int a[], int n);
int search(int a[], int n, int x);

int main(void)
{
int a[N], n, i, x, position;
scanf("%d", &n);
for(i = 0; i < n; i++)
{
scanf("%d",&a[i]);
}
sort(a, n);

scanf("%d", &x);
position = search(a, n, x);
if(position == -1)
{
printf("No find");
}
else
printf("Position:%d", position);

return 0;
}

void sort(int a[], int n)
{
int i, j, t;
for (i = 0; i < n - 1; i++)
{
for (j = i + 1; j < n; j++)
{
if(a[i] > a[j])
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
for (i = 0; i < n; i++)
printf("%d ", a[i]);
}

int search(int a[], int n, int x)
{
int r, l, m;
l = 0;
r = n;
while(l <= r)
{
m = (r+l)/2;
if(x > a[m])
l = m;
else if(x < a[m])
r = m;
else if(x == a[m])
return m+1;
}

return 0;
}

题目4

编写一函数void encrypt(char s[],int d),功能是将字符串中的每个字母用其之后(或之前)的第d个字母替换,如:d=4,则:AàE,BàF,…,WàA,XàB,aàe,bàf,…,wàa,xàb;如:d=-4,则:A变W,BàX,…,aàw,bàx,…,其他字符不变。在main函数中输入一个字符串s和d,调用encrypt(s,d)后,输出s,执行d=-d后再次调用encrypt(s,d)后,输出s。例如:

输入:Windows

4

输出:Amrhsaw

Windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<stdio.h>
#include<string.h>
void encrypt(char s[], int d);
int main(void)
{
char s[100];
int d;
gets(s);
scanf("%d", &d);
encrypt(s,d);
encrypt(s,-d);

return 0;
}


void encrypt(char s[], int d)
{
int len, n;
len = strlen(s) ;

for (n = 0; n < len ; n++)
{
if(s[n] >= 'A' && s[n] <= 'Z')
{
s[n] = (s[n] - 'A' + d + 26)%26 + 'A';
}
else if(s[n] >= 'a' && s[n] <= 'z')
{
s[n] = (s[n] - 'a' + d + 26)%26 + 'a';
}
}

printf("%s ", s);
}

题目5

输入以下代码,编译运行,并分析运行结果。理解局部变量和全局变量、动态变量与静态变量的区别。

#include <stdio.h>

int x;

void fun()

{

​ int x;

​ static int y;

​ x=x+1;

​ y=y+2;

​ printf(“fun:x=%d,y=%d\n”,x,y);

}

int main()

{

​ int y=0;

​ x=x+3;

​ y=y+4;

​ printf(“main1:x=%d,y=%d\n”,x,y);

​ fun();

​ printf(“main2:x=%d,y=%d\n”,x,y);

​ {

​ int x;

​ x++;y++;

​ printf(“main3:x=%d,y=%d\n”,x,y);

​ }

​ printf(“main4:x=%d,y=%d\n”,x,y);

​ fun();

​ x++;y++;

​ printf(“main5:x=%d,y=%d\n”,x,y);

​ return 0;

}

题目6

输入以下代码,编译运行,并分析运行结果。理解缓冲区溢出漏洞利用原理。

#include <stdio.h>

void printtest()

{

​ printf(“test”);

}

void gettest()

{

​ char str[15]={‘0’};

​ int p=(int)&printtest;

​ char ap[15];

​ ap[0]=p>>24 & 0x000000FF; //取地址的高字节

​ ap[1]=p<<8>>24 & 0x000000FF;//取地址的第二字节

​ ap[2]=p<<16>>24 & 0x000000FF; //取地址的第三字节

​ ap[3]=p<<24>>24 & 0x000000FF; //取地址的末字节

​ str[12]=ap[3];

​ str[13]=ap[2];

​ str[14]=ap[1];

​ str[15]=ap[0];

}

void main()

{

​ gettest();

}

实验7

题目1

写一程序求两个复数之和。要求:首先定义一个表示复数的结构体struct complex,包含两个成员:实部x(int型)和虚部y(int 型);然后写一个函数struct complex add(struct complex a, struct complex b)求两个复数之和;最后在main函数中输入两个复数的实部和虚部,调用add函数后,输出两复数之和。例如:

输入:3 5 4 -7

输出:7-2i

输入:20 30 -30 -20

输出:-10+10i

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>
struct complex{
int x;
int y;
};

struct complex add(struct complex a, struct complex b);

int main(void)
{
struct complex a;
struct complex b;
struct complex addition;

scanf("%d%d", &(a.x), &(a.y));
scanf("%d%d", &(b.x), &(b.y));
addition = add(a, b);

(addition.y > 0)? printf("%d+%di", addition.x, addition.y) : printf("%d%di", addition.x,addition.y);

return 0;
}


struct complex add(struct complex a, struct complex b)
{
struct complex c;
c.x = a.x + b.x;
c.y = a.y + b.y;

return c;
}

题目2

编写一程序对学生成绩进行处理,学生的信息包括学号(字符不超过10个)、姓名(字符不超过10个,不含空格)、3门课程的成绩(float型)以及平均分(float型)。要求:先定义一个表示学生信息的结构体struct student;然后定义3个函数,分别用于输入数据(含计算平均分)void input_data(struct student stu[ ],int n)、按平均分升序排序void sort(struct student stu[ ],int n)和输出数据void print_data(struct student stu[ ],int n);最后在main函数中输入学生人数n,依次调用input_data(stu,n)、sort(stu,n)和print_data(stu,n)函数。输入输出时每个数据间用一个空格隔开,成绩及平均分的小数保留1位。例如:

输入:3

00001 zhangsan 89 78 67

00002 lisi 70 66 72

00003 wangwu 78 77 70

输出:00002 lisi 70.0 66.0 72.0 69.3

00003 wangwu 78.0 77.0 70.0 75.0

00001 zhangsan 89.0 78.0 67.0 78.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include<stdio.h>
struct student{
char stu_number[10];
char stu_name[10];
float score[3];
float aver;
};

void input_data(struct student stu[], int n);
void sort(struct student stu[], int n);
void print_data(struct student stu[], int n);

int main(void)
{
struct student stu[100];
int n;
scanf("%d", &n);

input_data(stu,n);
sort(stu,n);
print_data(stu,n);


return 0;
}


void input_data(struct student stu[], int n)
{
int i;

for (i=0; i < n; i++)
{
scanf("%s%s%f%f%f",
stu[i].stu_number, stu[i].stu_name,&(stu[i].score[0]), &(stu[i].score[1]), &(stu[i].score[2]));
stu[i].aver = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2])/3;
}

}


void sort(struct student stu[], int n)
{
int i, j;
struct student t;

for(i = 0; i < n-1; i++)
{
for(j = i+1; j < n; j++ )
{
if(stu[i].aver > stu[j].aver)
{
t = stu[i];
stu[i] = stu[j];
stu[j] = t;
}
}
}
}

void print_data(struct student stu[],int n)
{
int i;
for(i = 0; i < n; i++)
{
printf("%s %s %.1f %.1f %.1f %.1f",
stu[i].stu_number, stu[i].stu_name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].aver);
printf("\n");
}
}

题目3

编写一个程序使用链表操作学生信息,学生的信息包括学号(字符不超过10个)、姓名(字符不超过10个,不含空格)和年龄(int型)。要求:先定义一个表示学生信息的结点struct student;然后定义5个函数,分别用于:创建一个带有头结点的链表(头插法,按学号降序输入数据,学生个数为n,本函数中输入)函数struct student *create()、插入数据(任意位置插入,保持学号有序,新生信息结点由main传递过来)函数void insert(struct student *h, struct student *x)、删除数据(删除指定学号的学生数据,学号由main传递过来)函数void dele (struct student *h,char num[])、输出数据函数void print(struct student *h)和菜单(用于显示1. create、2. insert、3. delete、4. print和0. exit)函数void menu();最后在main函数中用一个死循环实现可重复显示菜单及通过输入整数(0~4)选择调用相应功能函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student{
char stu_num[10];
char stu_name[10];
int stu_age;
struct student *next;
};

struct student *create();
void insert(struct student *h, struct student *x);
void dele(struct student*h,char num[]);
void print(struct student *h);
void menu();


int main(void)
{
char num[10];
struct student *h, *r, *p;
int n, a;
int b = 1;
while(b)
{
menu();
scanf("%d", &a);
switch(a)
{
case 1:
h = create();
break;
case 2:
p = (struct student *)malloc(sizeof(struct student));
scanf("%s%s%d", p->stu_num, p->stu_name, &(p->stu_age));
insert(h, p);
case 3:
scanf("%s",num);
dele(h,num);
break;
case 4:
print(h);
break;
case 0:
b = 0;
break;
}
getchar();
}

return 0;
}


void menu()
{
printf("*************************************\n");
printf("* 1.create *\n");
printf("* 2.insert *\n");
printf("* 3.delete *\n");
printf("* 4.print *\n");
printf("* 0.exit *\n");
printf("*************************************\n");
}


struct student *create(void)
{
int n = 0;
char quit;
struct student *h, *p;

h = (struct student*)malloc(sizeof(struct student));
h->next = NULL;
while(1)
{
p = (struct student*)malloc(sizeof(struct student));
printf("Please input the data about student:\n");
scanf("%s%s%d", p->stu_num, p->stu_name, &(p->stu_age));
p->next = h->next;
h->next = p;
getchar();
printf("continue or not (N to quit)\n");
scanf("%c", &quit);
n++;
if(quit == 'N' || quit == 'n')
break;
}

printf("You create %d student(s)\n", n);

return h;
}


void print(struct student *h)
{
printf("\n");
printf("\n");
printf("-----------------------------------------------\n");
struct student *p;
p = h->next;
while(p != NULL)
{
printf("%s %s %d", p->stu_num, p->stu_name, p->stu_age);
printf("\n");
p = p->next;
}
printf("\n");
printf("\n");
printf("------------------------------------------------\n");
}

void dele(struct student *h,char num[])
{
struct student *p, *q;
q = h;
p = h->next;
while(p != NULL)
{
if(strcmp(p->stu_num, num) == 0)
{
q->next = p->next;
free(p);
break;
}
q = q->next;
p = p->next;
}
}

void insert(struct student *h, struct student*x)
{
struct student *p, *q;
p = h->next;
q = h;

while(p != NULL)
{
if(strcmp(p->stu_num, x->stu_num) > 0)
{
x->next = p;
q->next = x;
break;
}
p = p->next;
q = q->next;
}
}

题目4

题目5

课外编程练习

C语言经典例题100道系列

题目1 组成不同不重复的三位数

有1、2、3、4个数字,能组成多少个互不相同且无重复数字(不能重复使用数字)的三位数?都是多少?

程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去掉不满足条件的排列。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main(void)
{
int i, j, k;
for(i=1; i<=4; i++)
for(j=1;j<=4;j++)
for(k=1;k<=4;k++)
{
if( i != j && i != k && k!= j)
printf("%d%d%d ", i, j, k);
}
}

题目2 企业发放的奖金根据利润提成

企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高 于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提 成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于 40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于 100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 #include<stdio.h>
int main(void)
{
float bouns, sum;
int boun;

scanf("%f", &bouns);

if(bouns > 100)
sum = 10*0.1 + 10*0.075 + 20 * 0.05 + 20*0.03 + 40*0.015 + (bouns-100)*0.01;
else if(bouns > 60)
sum = 10*0.1 + 10*0.075 + 20 * 0.05 + 20*0.03 + (bouns-60)*0.015 ;
else if(bouns > 40)
sum = 10*0.1 + 10*0.075 + 20 * 0.05 + (bouns-40)*0.03;
else if(bouns > 20)
sum = 10*0.1 + 10*0.075 + (bouns - 20) * 0.05;
else if(bouns > 10)
sum = 10*0.1 + (bouns - 10)*0.075;
else if(bouns > 0)
sum = bouns*0.1;
printf("%.2f", sum);

return 0;
}

题目3 猜数字

题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <math.h>
int main(void)
{
long int i, x, y, z;
for (i = 1; i < 100000; i++)
{
x = sqrt(i+100);
y = sqrt(i+268);
if(x*x == i+100 && y*y == i +268)
printf("%ld\n", i);
}

return 0;
}

题目4 判断第几天

输入某年某月某日,判断这一天是这一年的第几天?(同实验2 第3题)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
int main(void)
{
int year, month, day, sum;
scanf("%d-%d-%d", &year, &month, &day);
sum = 0;
switch(month -1)
{
case 11: sum += 30;
case 10: sum += 31;
case 9: sum += 30;
case 8: sum += 31;
case 7: sum += 31;
case 6: sum += 30;
case 5: sum += 31;
case 4: sum += 30;
case 3: sum += 31;
case 2: if ((year%4 == 0 && year%100 != 0) || year%400 == 0)
sum += 29;
else
sum += 28;
case 1: sum += 31;
}
sum += day;
printf("%d", sum);
return 0;
}

题目5 由小到大输出整数

输入三个整数x,y,z,请把这三个数由小到大输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
int main(void)
{
int a, b, c, t;
scanf("%d%d%d", &a, &b, &c);

if(a > b)
{
t = a;
a = b;
b = t;
}

if(a > c)
{
t = a;
a = c;
c = t;
}

if(b > c)
{
t = b;
b = c;
c = t;
}
printf("%d %d %d", a,b,c);

return 0;
}

题目6 用*号输出字母C的图案。

用*号输出字母C的图案。

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main(void)
{
printf("*********\n");
for (int i = 0; i < 5; i++)
{
printf("*\n");
}
printf("*********\n");

return 0;
}

题目7

题目8 九九乘法表

输出9*9口诀

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(void)
{
int i, j, n;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= i; j++)
printf("%d × %d = %d ", i,j,i*j);
printf("\n");
}
}

题目9 输出国际象棋棋盘

题目10 打印楼梯和笑脸

打印楼梯,同时在楼梯上方打印两个笑脸。

C Primer Plus编程练习

第9章 函数

题目1

设计一个函数min(x, y),返回两个double类型值的较小值。在一个简单的驱动程序中测试该函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
double min(double x, double y);
int main(void)
{
double n, m, small;
scanf("%lf%lf", &n, &m);

printf("%.3lf", min(n,m));

return 0;
}

double min(double x, double y)
{
return (x < y ? x : y);
}

题目2

设计一个函数chline(ch, i, j),打印指定的字符ji列。在一个简单的驱动程序中测试该函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
void chline(char (*c)[10],int i,int j);
int main(void)
{
int i,j;
char ch[10][10];
scanf("%s", ch[0]);
scanf("%d%d", &i, &j);

chline(ch, i, j);

return 0;
}

void chline(char (*c)[10], int i, int j)
{
printf("%c", c[i][j]);
}

// 做此题时出现把指针形参的声明与数组形参的声明混用

题目3

编写一个函数,接受3个参数:一个字符和两个整数。字符参数是待打印的字符,第1个整数指定一行中打印字符的次数,第2个整数指定打印指定字符的行数。编写一个调用该函数的程序。

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>
void printch(char ch,int i,int j);
int main(void)
{
int r, c;
char ch;
scanf("%c", &ch);
scanf("%d%d", &r, &c);
printch(ch, r, c);

return 0;
}

void printch(char ch, int i, int j)
{
for(int n = 0; n < j; n++)
{
for(int n = 0; n < i; n++)
printf("%c", ch);
printf("\n");
}
}
// 出现的问题:在声明和定义函数,在声明形参时,不声明其类型

题目4

两数的调和平均数这样计算:先得到两数的倒数,然后计算两个倒数的平均值,最后取计算结果的倒数。编写一个函数,接受两个double类型的参数,返回这两个参数的调和平均数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
double average(double a,double b);
int main(void)
{
double x, y, aver;
scanf("%lf%lf", &x, &y);
aver = average(x , y);
printf("%lf", aver);

return 0;
}

double average(double a, double b)
{

return (2/((1/a) + (1/b)));
}

题目5

编写并测试一个函数larger_of(),该函数把两个double类型变量的值替换为较大的值。例如,larger_of(x, y)会把xy中较大的值重新赋给两个变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
double larger_of(double n, double m);
int main(void)
{
double n, m;
scanf("%lf%lf", &n, &m);

m = n = larger_of(n, m);
printf("%.2lf %.2lf", n, m);
return 0;
}

double larger_of(double n, double m)
{
return (n > m)? n : m;
}

题目6

编写并测试一个函数,该函数以3个double变量的地址作为参数,把最小值放入第1个变量,中间值放入第2个变量,最大值放入第3个变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
void exchange(double *min, double *mid, double *max);
int main(void)
{
double n, m, k;
scanf("%lf%lf%lf", &n, &m, &k);
exchange(&n, &m ,&k);

printf("%.2lf %.2lf %.2lf", n,m,k);

return 0;
}

void exchange(double *min,double *mid, double *max)
{
double t;

if(*min > *mid)
{
t = *min;
*min = *mid;
*mid = t;
}

if(*min > *max)
{
t = *min;
*min = *max;
*max = t;
}

if(*mid > *max)
{
t = *mid;
*mid = *max;
*max = t;
}
}

题目7

编写一个函数,从标准输入中读取字符,直到遇到文件结尾。程序要报告每个字符是否是字母。如果是,还要报告该字母在字母表中的数值位置。例如,c和C在字母表中的位置都是3。合并一个函数,以一个字符作为参数,如果该字符是一个字母则返回一个数值位置,否则返回-1。

1

第11章 字符串和字符串函数

1