《linux c 编程一站式学习》课后部分习题解答(一)
来源:互联网 发布:商品数据库设计 编辑:程序博客网 时间:2024/06/09 18:26
1、假设变量x和n是两个正整数,我们知道x/n这个表达式的结果要取Floor,例如x是17,n是4,则结果是4。如果希望结果取Ceiling应该怎么写表达式呢?例如x是17,n是4,则结果是5;x是16,n是4,则结果是4。
答: (x+n-1)/n
(1). 设x=kn,k为整数,即x为n的整数倍。则(x+n-1)/n=(kn+n-1)/n=((k+1)n-1)/n,此时分子没有达到n的k+1倍,但大于等于n的k倍, 默认计算取下整则为k。符合要求。
(2).设x=kn+m,k为整数,m为整数且0<m<n。则(x+n-1)/n=(kn+m+n-1)/n=((k+1)n+m-1)/n。此时分子的大于等于(k+1)n,小于(k+2)n,按照默认计算应该为k+1。符合要求。
2、编写一个布尔函数int is_leap_year(int year),判断参数year是不是闰年。如果某年份能被4整除,但不能被100整除,那么这一年就是闰年,此外,能被400整除的年份也是闰年。
2
3
4
5
6
7
8
9
10
11
12
13
{
if (year % 4 == 0)
{
if (year % 100 != 0)
return 1;
else return 0;
}
else if (year % 400 == 0)
return 1;
else
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
int sa = 0, si = 0;
if (x == 0.0)
return 0.0;
else if (x > 0.0)
{
sa = (int)x;
si = x + 0.5;
if (sa == floor(si))
return sa;
else return sa + 1;
}
else
{
sa = (int)x;
si = x - 0.5;
if (sa == ceil(si))
return sa;
else
return sa - 1;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
if (greater % less == 0)
return less;
else
return gcd(less, (greater % less));
}
long int fibonacci(int n)
{
if (n == 0 || n == 1)
return 1;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
int i, n = 0;
for (i = 1; i <= 100; i++)
{
if (i / 10 == 9)
{
if (i % 10 == 9)
n = n + 2;
else
n = n + 1;
}
else if (i % 10 == 9)
n = n + 1;
}
return n;
}
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
{
int i, j;
for (i = 1; i <= 9; i++)
{
for ( j = 1; j <= 9; j++)
if (i >= j)
printf("%d\t", i * j);
printf("\n");
}
}
void diamond(int num, char pattern)
{
int row, col;
if (num % 2 == 0)
{
printf("num must be even!\n");
return;
}
for (row = -num; row <= num; row++)
{
for ( col = -num; col <= num; col++)
{
if (fabs(row) + fabs(col) <= num)
printf("%c", pattern);
else printf(" ");
}
printf("\n");
}
}
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
#include <math.h>
#define MAX 20000
struct rational
{
int x, y;
};
int fenzi(struct rational z)
{
return z.x;
}
int fenmu(struct rational z)
{
return z.y;
}
struct rational make_from_fenzi_fenmu(int x, int y)
{
struct rational z;
z.x = x;
z.y = y;
return z;
}
int gcd(int max, int min)
{
int temp = 0;
int fabs_max = fabs(max);
int fabs_min = fabs(min);
if (fabs_max < fabs_min)
{
temp = fabs_max;
fabs_max = fabs_min;
fabs_min = temp;
}
if ((fabs_max % fabs_min) == 0)
return (fabs_min);
else
return gcd(fabs_min, fabs_max % fabs_min);
}
int lcm_(int max, int min)
{
int temp = 0;
int fabs_max = fabs(max);
int fabs_min = fabs(min);
if (fabs_max < fabs_min)
{
temp = fabs_max;
fabs_max = fabs_min;
fabs_min = temp;
}
int i;
for (i = fabs_max; i < MAX; i++)
if (i % fabs_max == 0 && i % fabs_min == 0)
break;
return i;
}
struct rational add(struct rational z1, struct rational z2)
{
struct rational z3;
int lcm = lcm_(fenmu(z1), fenmu(z2));
z3 = make_from_fenzi_fenmu(lcm / fenmu(z1) * fenzi(z1) + lcm / fenmu(z2) * fenzi(z2),
lcm );
int euclid = gcd(z3.y, z3.x);
return make_from_fenzi_fenmu(z3.x / euclid, z3.y / euclid);
}
struct rational sub(struct rational z1, struct rational z2)
{
struct rational z3;
int lcm = lcm_(fenmu(z1), fenmu(z2));
z3 = make_from_fenzi_fenmu(lcm / fenmu(z1) * fenzi(z1) - lcm / fenmu(z2) * fenzi(z2),
lcm );
int euclid = gcd(z3.y, z3.x);
return make_from_fenzi_fenmu(z3.x / euclid, z3.y / euclid);
}
struct rational mul(struct rational z1, struct rational z2)
{
struct rational z3;
z3 = make_from_fenzi_fenmu(fenzi(z1) * fenzi(z2), fenmu(z1) * fenmu(z2));
int euclid = gcd(z3.y, z3.x);
return make_from_fenzi_fenmu(z3.x / euclid, z3.y / euclid);
}
struct rational div(struct rational z1, struct rational z2)
{
struct rational z3;
z3 = make_from_fenzi_fenmu(fenzi(z1) * fenmu(z2), fenmu(z1) * fenzi(z2));
int euclid = gcd(z3.y, z3.x);
return make_from_fenzi_fenmu(z3.x / euclid, z3.y / euclid);
}
int print_rational(struct rational z)
{
if (fenzi(z) == 0)
printf ("0\n");
else if (fenmu(z) == 0)
{
printf("it's error!\n");
return 1;
}
else
printf ("%d/%d\n", fenzi(z), fenmu(z));
return 0 ;
}
int main(void)
{
struct rational z3, z4, z5, z6;
struct rational z1 = { -3, 4 };
struct rational z2 = { 1, 7 };
z3 = add(z1, z2);
print_rational(z3);
z4 = sub(z1, z2);
print_rational(z4);
z5 = mul(z1, z2);
print_rational(z5);
z6 = div(z1, z2);
print_rational(z6);
return 0;
}
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
> File Name: getrandom.c
> Author: Simba
> Mail: dameng34@163.com
> Created Time: Sat 27 Oct 2012 06:55:35 PM CST
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//#define N 10000
#define N 20
int a[N];
void random(int uppernum)
{
int i;
srand(time(NULL));
for (i = 0; i < N; i++)
a[i] = rand() % uppernum;
}
int howmany(int value)
{
int count = 0, i;
for (i = 0; i < N; i++)
if (a[i] == value)
count++;
return count;
}
void print(void)
{
int i;
printf("value\thow many\n");
for (i = 0; i < 10; i++)
printf("%d\t%d\n", i, howmany(i));
printf("\n");
}
int main(void)
{
int i, j, k, histogram[10] = {0};
random(10);
print();
// for (i = 0; i < 10; i++)
// histogram[i] = howmany(i);
for (i = 0; i < N; i++)
histogram[a[i]]++;
for (i = 0; i < 10; i++)
printf("%d\t", i);
printf("\n");
for (j = 0; j < N; j++) {
for (k = 0; k < 10; k++) {
if (histogram[k] > 0) {
printf("*\t");
histogram[k]--;
}
else
printf("\t");
}
printf("\n");
}
return 0;
}
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
> File Name: perm_comb.c
> Author: Simba
> Mail: dameng34@163.com
> Created Time: Sun 28 Oct 2012 09:08:06 AM CST
************************************************************************/
#include<stdio.h>
#define N 4
#define MAX_NUM 5
int a[MAX_NUM];
void swap(char *a, char *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int isswap(char ptr[], int begin, int end)
{
int i;
for (i = begin; i < end; i++)
if (ptr[i] == ptr[end])
return 0;
return 1;
}
void perm(char ptr[], int n, int curr)
{
if (curr == n - 1)
printf("%s\n", ptr);
else
{
int i;
for (i = curr; i < n; i++)
{
if (isswap(ptr, curr, i))
{
swap(ptr + i, ptr + curr);
perm(ptr, n, curr + 1);
swap(ptr + i, ptr + curr);
}
}
}
}
void comb(int m, int k)
{
int i;
for (i = m; i >= k; i--)
{
a[k] = i;
if (k > 1)
comb(m - 1, k - 1);
else
{
int j;
for(j = a[0]; j > 0; j--)
printf("%d", a[j]);
printf("\n");
}
}
}
int main(void)
{
int i;
char ptr[N] = {'0'};
for (i = 0; i < N; i++)
ptr[i] = (i + 1) + '0';
perm(ptr, N, 0);
a[0] = 3;
comb(MAX_NUM, a[0]);
}
2
3
4
5
6
7
8
9
10
11
12
int main(int argc, char **argv)
{
union data
{
char sysbol;
int num;
} test;
test.num = 0x02000001;
printf("%d\n", (int)test.sysbol);
return 0;
}
11、定义以下变量:
char a[4][3][2] = {{{'a', 'b'}, {'c', 'd'}, {'e', 'f'}},
{{'g', 'h'}, {'i', 'j'}, {'k', 'l'}},
{{'m', 'n'}, {'o', 'p'}, {'q', 'r'}},
{{'s', 't'}, {'u', 'v'}, {'w', 'x'}}};
char (*pa)[2] = &a[1][0];
char (*ppa)[3][2] = &a[1];
要想通过pa或ppa访问数组a中的'r'元素,分别应该怎么写?
答:char r2 = pa[5][1]; // (*(pa+5)) 即 pa[5]
char r4 = ppa[1][2][1];
12、自己实现一个strcpy函数,尽可能简洁,按照本书的编码风格你能用三行代码写出函数体吗?
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
size_t i;
for (i = 0; src[i] != '\0'; i++)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
char *strncpy(char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
char *shrink_space(char *dest, const char *src, size_t n)
{
size_t i, j;
dest[0] = src[0];
for (i = 1, j = 1; src[i] != '\0'; i++, j++)
{
if (src[i] == '\t' || src[i] == '\n'
|| src[i] == '\r' || src[i] == ' ')
if (src[i - 1] != '\t' && src[i - 1] != '\n'
&& src[i - 1] != '\r' && src[i - 1] != ' ')
dest[j] = ' ';
else
j--;
else
dest[j] = src[i];
}
dest[j] = '\0';
return dest;
}
14、[K&R]的5.6节有一个qsort函数的实现,可以对一组任意类型的对象做快速排序。请读者仿照那个例子,写一个插入排序的函数和一个折半查找的函数。
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
{
int i, j, tmp;
for (i = 1; i < n; i++)
{
tmp = a[i];
for (j = i; j > 0 && a[j - 1] > tmp; j--)
a[j] = a[j - 1];
a[j] = tmp;
}
}
int binarysearch(int number)
{
int mid, start = 0, end = LEN - 1;
assert(is_sorted()); /* Precondition */
while (start <= end)
{
assert(mustbe(start, end, number)); /* Maintenance */
mid = (start + end) / 2; // 改成 mid = start + (end - start) * (number - a[start])/(a[end] - a[start])
//即变成插值查找
if (a[mid] < number)
start = mid + 1;
else if (a[mid] > number)
end = mid - 1;
else
{
assert(mid >= start && mid <= end && a[mid] == number); /* Postcondition 1 */
return mid;
}
}
assert(!contains(number)); /* Postcondition 2 */
return -1;
}
http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=http://www.baidu.com/s?wd=linux&cl=3
比如上面第一个例子,http://www.google.cn/search是路径部分,?号后面的complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=是查询字符串,由五个“key=value”形式的键值对(Key-valuePair)组成,以&隔开,有些键对应的值可能是空字符串,比如这个例子中的键meta。
现在要求实现一个函数,传入一个带查询字符串的URL,首先检查输入格式的合法性,然后对URL进行切分,将路径部分和各键值对分别传出,请仔细设计函数接口以便传出这些字符串。如果函数中有动态分配内存的操作,还要另外实现一个释放内存的函数
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
> File Name: find_url_token.c
> Author: Simba
> Mail: dameng34@163.com
> Created Time: Sat 26 Jan 2013 04:05:32 PM CST
************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 10
typedef struct
{
char *tokens[N];
int count;
} unit_t;
void find_url_token(char str[], const char tok[], unit_t *ptr)
{
int i;
char *token = NULL;
char *saveptr = NULL;
ptr->count = 0;
const char *needle = "://";
if (strstr(str, needle))
{
for (i = 0; ; str = NULL, i++)
{
token = strtok_r(str, tok, &saveptr);
if (token == NULL)
break;
else
{
ptr->tokens[i] = token;
ptr->count++;
}
}
}
// for (i = 0; i < ptr->count; i++)
// printf("%s\n", ptr->tokens[i]);
// return ptr;
}
int main(void)
{
/* 不能定义为char *url = "..."; 因为此时是定义一个指向字符串字面值(位于.rodata段)的指针,而
调用strtok_r函数会修改这个字符串,运行时会产生段错误 */
char url[] = "http://www.google.cn/search?complete=1&hl=zh-CN&ie=GB2312&q=linux&meta=";
/* 给url初始化用的这个字符串并没有分配在.rodata段,而是直接写在指令里了,
* 运行程序时通过三条movl 指令把12个字节写到栈上,这就是url的存储空间*/
unit_t *ptr = malloc(sizeof(unit_t));
find_url_token(url, "?&", ptr);
int i;
for (i = 0; i < ptr->count; i++)
printf("%s\n", ptr->tokens[i]);
free(ptr);
return 0;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct node {
unsigned char item;
link next;
};
{
link pnode = head;
link pprev = NULL;
while (pnode != NULL)
{
// get the next node, and save it at pNext
link pnext = pnode->next;
// reverse the linkage between nodes
pnode->next = pprev;
// move forward on the the list
pprev = pnode;
pnode = pnext;
}
head = pprev;
}
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
> File Name: consumer.c
> Author: Simba
> Mail: dameng34@163.com
> Created Time: 2012年12月19日 星期三 00时15分47秒
************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
/* 程序演示了一个生产者-消费者的例子,生产者生产一个结构体串在链表的表头上,消费者
从表头取走结构体。注意: 不一定产生一次就取走一次,虽然产生一次就唤醒一次消费者
,但有可能此时并未调度消费者线程运行,但取走的一定是表尾的结构体,即最快生产剩下未被取走的即FIFO */
struct msg
{
struct msg *next;
int num;
};
struct msg *head;
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
struct msg *mp;
for (;;)
{
pthread_mutex_lock(&lock);
while (head == NULL)
pthread_cond_wait(&has_product, &lock);
if (head->next != NULL)
{
mp = head->next;
head->next = mp->next;
}
else
{
mp = head;
head = mp->next;
}
pthread_mutex_unlock(&lock);
printf("Consume %d\n", mp->num);
free(mp);
sleep(rand() % 5);
}
}
void *producer(void *p)
{
struct msg *mp;
for (;;)
{
mp = malloc(sizeof(struct msg));
mp->num = rand() % 1000 + 1;
printf("Produce %d \n", mp->num);
pthread_mutex_lock(&lock);
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
pthread_cond_signal(&has_product);
sleep(rand() % 5);
}
}
int main(int argc, char *argv[])
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
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 <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
pid_t pid; //信号处理函数也要访问,故设置成全局变量
void sig_chld(int signo)
{
int stat_val;
/* pid_t waitpid(pid_t pid, int *status, int options); */
waitpid(pid, &stat_val, 0);
if (WIFEXITED(stat_val))
printf("child exited with code %d\n", WEXITSTATUS(stat_val));
else if (WIFSIGNALED(stat_val))
printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));
}
int main(void)
{
struct sigaction newact, oldact;
newact.sa_handler = sig_chld;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGCHLD, &newact, &oldact);
pid = fork();
if (pid < 0)
{
perror("fork");
exit(1);
}
if (pid > 0) /* parent */
{
while (1);
}
else /* child */
exit(3);
sigaction(SIGCHLD, &oldact, NULL);
return 0;
}
/* 父进程fork 出子进程,子进程调用exit(2)终止,父进程自定
* 义SIGCHLD信号的处理函数,在其中调用waitpid 获得子进程的退出状态并打印。*/
- 《linux c 编程一站式学习》课后部分习题解答(一)
- 《linux c 编程一站式学习》课后部分习题解答
- 《linux c 编程一站式学习》课后部分习题解答
- 周志华《机器学习》课后习题解答系列(一):目录
- 算法导论课后习题部分解答
- 谭浩强C语言程序设计课后习题解答(第二章)
- 谭浩强C语言程序设计课后习题解答(第四章)
- 周志华《机器学习》课后习题解答系列(二):Ch1
- 周志华《机器学习》课后习题解答系列(三):Ch2
- 周志华《机器学习》课后习题解答系列(四):Ch3
- 周志华《机器学习》课后习题解答系列(五):Ch4
- 周志华《机器学习》课后习题解答系列(六):Ch5
- 周志华《机器学习》课后习题解答系列(七):Ch6
- 《学习OpenCV》课后习题解答1
- 《学习OpenCV》课后习题解答2
- 《学习OpenCV》课后习题解答3
- 《学习OpenCV》课后习题解答4
- 《学习OpenCV》课后习题解答5
- 我现写掼蛋游戏就是要努力奋斗
- ajax实现实时刷新
- POJ 3050 Hopscotch (dfs)
- Java性能调优笔记
- 各类C语言查找算法汇总--折半、顺序
- 《linux c 编程一站式学习》课后部分习题解答(一)
- 我的高中生涯大概只有一年半学的是C/C++
- 算法交作业之循环和递归(二)
- jquery实现ajax文件上传
- AOJ 0525 Osenbei (dfs)
- Apache Tiles 布局管理器
- DAY_1
- 美语音标 [ɪ]在下列情况要发[i]的音
- spinlock