一生一芯--c语言学习(linux c 编程一站式学习)
习题1-8,11-12稍微鸽下,还在感悟中.21-24
第一章程序的基本概念
第二章-常量,变量和表达式
1、总结前面介绍的转义序列的规律,想想在printf的格式化字符串中怎么表示一个%字符?写个小程序试验一下。
void test01()
{
printf("%%\n");
}
2、假设变量x和n是两个正整数,我们知道x/n这个表达式的结果是取Floor,例如x是17,n是4,则结果是4。如果希望结果取Ceiling应该怎么写表达式呢?例如x是17,n是4,则结果是5,而x是16,n是4,则结果是4。
void test02()
{
int a, b;
scanf_s("%d %d", &a,&b);
printf("%d", (a-1)/b+1);
}
第三章-简单函数
1、定义一个函数increment,它的作用是将传进来的参数加1,然后在main函数中用increment函数来增加变量的值:
void increment(int *x)
{
*x=*x + 1;
}
int main(int argc,char *argv[])
{
int i = 1, j = 2;
increment(&j);
increment(&i);
printf("%d %d", i, j);
return 0;
}
2、函数的声明,定义,原型
main() {}, int bar(void) {}是函数定义
int foo();函数声明
void baz(int i, int);函数原型
第四章-分支语句
1、以下程序段编译能通过,执行也不出错,但是执行结果不正确(根据第 3 节 “程序的调试”的定义,这是一个语义错误),请分析一下哪里错了。还有,既然错了为什么编译能通过呢?
int x = -1;
if (x > 0);
printf("x is positive.\n");
if判断后有个分号; 但是这不是语法错误,所以能够编译通过。
void test04()
{
int x = -1;
if (x > 0)
printf("x is positive");
else
printf("x is negetive");
}
2、写两个表达式,分别取整型变量x的个位和十位。
void test05()
{
printf("请输入一个整数:\n");
int x = 0;
scanf_s("%d", &x);
printf("他的个位是:%d\n", x % 10);
printf("他的十位是:%d\n", (x / 10) % 10);
}
3、写一个函数,参数是整型变量x,功能是打印x的个位和十位
void print_digits(int x)
{
int units = x % 10;
int tens = (x / 10) % 10;
printf("个位:%d,十位:%d\n", units, tens);
}
p50-p51 1-3,5页 easy
以下哪一个if判断条件是多余的可以去掉?这里所谓的“多余”是指,某种情况下如果本来应该打印Test OK!,去掉这个多余条件后仍然打印Test OK!,如果本来应该打印Test failed!,去掉这个多余条件后仍然打印Test failed!。
if (x<3 && y>3)
printf("Test OK!\n");
else if (x>=3 && y>=3)
printf("Test OK!\n");
else if (z>3 && x>=3)
printf("Test OK!\n");
else if (z<=3 && y>=3)
printf("Test OK!\n");
else
printf("Test failed!\n");
正确的:
void test06_1()
{
int x=0, y=0,z=0;
if(x < 3 && y>3)
printf("ok");
else if (x >= 3 && y >= 3)//多余
printf("ok");
else if (z > 3 && y > +3)
printf("ok");
else if (z <= 3 && y >= 3)
printf("ok");
else
printf("no");
}
第五章-深入理解函数
1、编写一个布尔函数int is_leap_year(int year),判断参数year是不是闰年。如果某年份能被4整除,但不能被100整除,那么这一年就是闰年,此外,能被400整除的年份也是闰年。
int is_leap_year(int year) {
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return 1; // 是闰年
}
else {
return 0; // 不是闰年
}
}
int main() {
int year;
printf("请输入一个年份:");
scanf_s("%d", &year);
if (is_leap_year(year)) {
printf("%d 是闰年\n", year);
}
else {
printf("%d 不是闰年\n", year);
}
return 0;
}
2、编写一个函数double myround(double x),输入一个小数,将它四舍五入。例如myround(-3.51)的值是-4.0,myround(4.49)的值是4.0。可以调用math.h中的库函数ceil和floor实现这个函数。
double myround(double x)
{
double a, b;
if (x >= 0)
{
return ceil(x - 0.5);
}
else if (x == 0)
return 0;
else
return floor(x + 0.5);
}
int main()
{
double data,pro_data;
printf("请输入一个数:");
scanf_s("%lf", &data);
pro_data = myround(data);
printf("data进行四舍五入后结果为%lf", pro_data);
}
3、编写递归函数求两个正整数a和b的最大公约数(GCD,Greatest Common Divisor),使用Euclid算法:
如果a除以b能整除,则最大公约数是b。
否则,最大公约数等于b和a%b的最大公约数。 Euclid算法是很容易证明的,请读者自己证明一下为什么这么算就能算出最大公约数。
int gcd_euclid(int a, int b)
{
a = (a < 0) ? -a : a;
b = (b < 0) ? -b : b;
if (a % b == 0)
return b;
else
{
return gcd_euclid(b, a % b);
}
}
int main()
{
int x, y;
printf("请输入两个数:");
scanf_s("%d %d", &x, &y);
printf("最大公约数是:%d",gcd_euclid(x, y));
}
4、编写递归函数求Fibonacci数列的第n项,这个数列是这样定义的: fib(0)=1 fib(1)=1 fib(n)=fib(n-1)+fib(n-2) 这个递归函数做两次递归调用,会形成树状的调用关系,需要画图解释。
int fib(int n)
{
int result;
if (n == 1 || n == 0)
return 1;
else
{
result = fib(n - 2) + fib(n - 1);
return result;
}
}
int main()
{
int n;
printf("请输入1个数:");
scanf_s("%d",&n);
printf("他的fib是:%d", fib(n));
}
第六章-循环语句
1、使用while实现:
int gcd_euclid_while(int a, int b) {
// 步骤1:先处理负数,取绝对值
a = (a < 0) ? -a : a;
b = (b < 0) ? -b : b;
while (b != 0 && a % b != 0) {
int temp = b; // 保存当前b的值
b = a % b; // 更新b为a除以b的余数
a = temp; // 更新a为原来的b
}
return (b == 0) ? a : b;
}
int fib_while(int n) {
if (n == 0 || n == 1) {
return 1;
}
int a = 1;
int b = 1;
int result = 0;
int i = 2; // 从第2项开始计算(n>=2)
while (i <= n) {
result = a + b; // 当前项 = 前两项之和
a = b; // 更新前一项
b = result; // 更新当前项为下一次的前一项
i++;
}
return result;
}
2、编写程序数一下1到100的所有整数中出现多少次数字9。在写程序之前先把这些问题考虑清楚:
- 这个问题中的循环变量是什么?
- 这个问题中的累加器是什么?用加法还是用乘法累积?
- 在第 2 节 “if/else语句”的习题1写过取一个整数的个位和十位的表达式,这两个表达式怎样用到程序中?
void test09()
{
int n = 100;
int i = 0;
while (n>0)
{
if ((n % 10) == 9 || ((n / 10) % 10) == 9)
{
i++;
printf("包含数字9:%d\n", n);
}
n--;
}
printf("包含数字9的数有%d个",i);
}
3、求素数这个程序只是为了说明break和continue的用法才这么写的,其实完全可以不用break和continue,请读者修改一下循环的结构,去掉break和continue而保持功能不变
int is_prime(int n) {
if (n <= 1) {
return 0;
}
if (n == 2) {
return 1;
}
if (n % 2 == 0) {
return 0;
}
for (int i = 3; i * i <= n; i += 2) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
int main5()
{
int i;
for (i = 1; i<= 100;i++)
{
if (is_prime(i))
printf("%d不是素数\n", i);
else
printf("%d是素数\n", i);
}
return 0;
}
4、上面打印的小九九有一半数据是重复的,因为89和98的结果一样。请修改程序打印这样的小九九:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72 81
void test10()
{
int n = 9;
int i, j;
for (i = 1;i <= n;i++)
{
for (j = 1;j <= i;j++)
{
printf("%d ", i * j);
}
printf("\n");
}
}
5、编写函数diamond打印一个菱形。如果调用diamond(3, '*')则打印:(看书p74)
void diamond(int n, char ch)
{
if (n % 2 == 0)
{
printf("error");
return;
}
//上半部分
for (int i = 0; i < n / 2 + 1; i++)
{
for(int j =n/2-i;j>0;j--)
{
printf(" ");
}
for (int k = 0;k<2*i+1;k++)
{
printf("%c",ch);
}
printf("\n");
}
//上半部分
for(int i = 0; i < n / 2 ; i++)
{
for (int j=0;j<i+1;j++)
{
printf(" ");
}
for (int k = 2*(n/2-i)-1;k>0;k--){
printf("%c", ch);
}
printf("\n");
}
}
6、以下代码编译没有问题, 但运行结果却和预期不符合, 不能打印出other number, 请分析原因.
#include <stdio.h>
int main(void){
int n = 3;
switch(n) {
case 1:
printf("1\n");
break;
case 2:
printf("2\n");
break;
default:
printf("other number\n");
}
return 0;
}
正确的:
void test12()
{
int n = 3;
switch (n)
{
case 1:
printf("1\n");
break;
case 2:
printf("2\n");
break;
default:
printf("other number\n");
}
}
7、这题我使用visual studio能正常打印出other number
第七章-结构体
1、在本节的基础上实现一个打印复数的函数,打印的格式是x+yi,如果实部或虚部为0则省略,例如:1.0、-2.0i、-1.0+2.0i、1.0-2.0i。最后编写一个main函数测试本节的所有代码。想一想这个打印函数应该属于上图中的哪一层?
#include <stdio.h>
#include <math.h>
//p85页习题
struct complex_num {
double x, y;
};
double real(struct complex_num z)
{
return z.x;
}
double img(struct complex_num z)
{
return z.y;
}
void printf_complex_num(struct complex_num z)
{
if (real(z) == 0 && img(z) == 0)
printf("0\n");
else if (real(z) == 0)
printf("%fi\n", img(z));
else if (img(z) == 0)
printf("%f\n", real(z));
else
printf("%f+%fi\n", real(z), img(z));
}
2、实现一个用分子分母的格式来表示有理数的结构体rational以及相关的函数,rational结构体之间可以做加减乘除运算,运算的结果仍然是rational 注意要约分为最简分数,例如1/8和-1/8相减的打印结果应该是1/4而不是2/8,可以利用第 3 节 “递归”练习题中的Euclid算法来约分。在动手编程之前先思考一下这个问题实现了什么样的数据抽象,抽象层应该由哪些函数组成。
struct rational {
int x, y;
};
//注意到例子,make_ratonal返回值是一个结构体
struct rational make_rational(int numerator, int denominator)
{
struct rational a;
a.x = numerator;
a.y = denominator;
return a;
}
//一个细节,这里分数加法需要取最小公倍数使用函数章节例题gcd
int gcd_euclid(int a, int b)
{
a = (a < 0) ? -a : a;
b = (b < 0) ? -b : b;
if (a % b == 0)
return b;
else
{
return gcd_euclid(b, a % b);
}
}
void printf_rational(struct rational num)
{
printf("%d/%d\n", num.x, num.y);
}
struct rational add_rational(struct rational a, struct rational b)
{
struct rational result;
int max, gcm;
//百度下,最大公倍数=axb/gcd_eucild(a,b)
max = gcd_euclid(a.x, b.y);
gcm = (a.x * b.y) / max;
result.y = gcm;
result.x = (a.x * gcm / a.y) + (b.x * gcm / b.y);
return result;
}
struct rational sub_rational(struct rational a, struct rational b)
{
struct rational result;
int max, gcm;
//百度下,最大公倍数=axb/gcd_eucild(a,b)
max = gcd_euclid(a.x, b.y);
gcm = (a.x * b.y) / max;
result.y = gcm;
result.x = (a.x * gcm / a.y) - (b.x * gcm / b.y);
return result;
}
struct rational mul_rational(struct rational a, struct rational b)
{
struct rational result;
result.x = a.x * b.x;
result.y = a.y * b.y;
return result;
}
struct rational div_rational(struct rational a, struct rational b)
{
struct rational result;
result.x = a.x * b.y;
result.y = a.y * b.x;
return result;
}
void main()
{
struct complex_num z1 = { 1,1 };
printf_complex_num(z1);
struct complex_num z2 = { 0,1 };
printf_complex_num(z2);
struct complex_num z3 = { 1,0 };
printf_complex_num(z3);
struct complex_num z4 = { 0,0 };
printf_complex_num(z4);
struct rational a = make_rational(1, 8);
struct rational b = make_rational(-1, 8);
printf_rational(add_rational(a, b));//0/8
printf_rational(sub_rational(a, b));//2/8
printf_rational(div_rational(a, b));//8/-8
printf_rational(mul_rational(a, b));//-1/64
return 0;
}
3、本节只给出了make_from_real_img和make_from_mag_ang函数的实现,请读者自己实现real_part、img_part、magnitude、angle这些函数。
enum coordinate_type { RECTANGULAR,POLAR};
struct complex_struct1
{
enum coordinate_type t;
double a, b;
};
double real_part(struct complex_struct1 z) {
if (z.t == RECTANGULAR)
return z.a;
else
return z.a * cos(z.b);
}
double imag_part(struct complex_struct1 z) {
if (z.t == RECTANGULAR)
return z.b;
else
return z.a * sin(z.b);
}
double magnitude(struct complex_struct1 z) {
if (z.t == RECTANGULAR)
return sqrt(z.a * z.a + z.b * z.b);
else
return z.a;
}
double angle(struct complex_struct1 z) {
if (z.t == RECTANGULAR) {
double PI = acos(-1.0);
if (z.a > 0)
return atan(z.b / z.a);
else
return atan(z.b / z.a) + PI;
}
else
return z.b;
}
int main(void)
{
int RECTANGULAR;
printf("%d %d\n", RECTANGULAR, POLAR);
return 0;
}
4、编译运行下面这段程序:
#include <stdio.h>
enum coordinate_type { RECTANGULAR = 1, POLAR };
int main(void)
{
int RECTANGULAR;
printf("%d %d\n", RECTANGULAR, POLAR);
return 0;
}
结果是什么?并解释一下为什么是这样的结果。
解答:结果是一个随机值,polAr是2,但是int rectangular没有别初始化。
第八章-数组
1、编写一个程序,定义两个类型和长度都相同的数组,将其中一个数组的所有元素拷贝给另一个。既然数组不能直接赋值,想想应该怎么实现。
#include<stdio.h>
#include<stdlib.h>
#define N 20
int a[N];//定义一个全局变量
//习题1在 C 语言中,字符串是以空字符 (\0) 结尾的。当循环执行时,b[i] 会取源字符串 b 中索引为 i 的字符。在 C 语言的布尔表达式中,任何非零值都被视为真,零值(\0) 被视为假
void copy(char *a, char *b) {
int i;
for (i = 0; b[i]; ++i)
a[i] = b[i];
}
2、用rand函数生成10~20之间的随机整数,表达式应该怎么写?
num=rand()%11+10
3、补完本节直方图程序的main函数,以可视化的形式打印直方图。 注:其他随机数程序写一块了,mainx去掉对应的x就可以用
void gen_random(int upper_bound)
{
int i;
for (i = 0;i < N;i++)
{
a[i] = rand() % upper_bound;
}
}
void print_random()
{
int i;
for (i = 0;i < N;i++)
printf("%d ", a[i]);
printf("\n");
}
int main1(void)
{
gen_random(1000);
print_random();
return 0;
}
int howmany(int value)
{
int count = 0, i;
for (i = 0;i < N;i++)
{
if (a[i] == value)
++count;
}
return count;
}
int main2(void)
{
int i;
gen_random(10);
printf("value\thow many\n");
for (i = 0;i < 10;i++)
{
printf("%d\t%d\n", i, howmany(i));
}
return 0;
}
int main3(void)
{
int i, histogram[10] = { 0 };
gen_random(10);
for (i = 0;i < N;i++)
histogram[a[i]]++;
return 0;
}
void printf0_9()
{
int i;
for(i=0;i<10;i++)
printf("%d ",i);
printf("\n");
}
void num_count(int *num)
{
int i, histogram[10] = { 0 };
gen_random(10);
for (i = 0;i < N;i++)
histogram[a[i]]++;
for (i = 0;i < N;i++)
num[i]=histogram[i];
}
int main4(void)
{
printf0_9();
int i;
int histogram[10];
num_count(histogram);
printf("实际个数统计如下:\n");
for (i = 0;i < 10;i++)
printf("%d ", histogram[i]);
int max = histogram[0];
for (i = 0;i < 9;i++)
{
if (histogram[i] >= max)
max = histogram[i];
}
printf("出现次数最多是:%d\n",max);
int j;
for (i = 0;i <max;i++)
{
for (j = 0;j < 10;j++)
{
if (histogram[j] > i)
printf("* ");
else
printf(" ");
}
printf("\n");
}
}
4、定义一个数组,编程打印它的全排列
//p97 习题2
#define N 3
int a[N] = { 1, 2, 3 }; // 原始数组
int result[N]; // 存储当前排列的数组
int used[N] = { 0 }; // 标记数组:used[i] = 1 表示 a[i] 已经被使用
// 函数声明
void permute(int k);
int main() {
printf("--- 数组 {1, 2, 3} 的全排列 ---\n");
permute(0); // 从第0个位置开始生成排列
return 0;
}
void permute(int k)
{
if (k == N) {
for (int i = 0; i < N; i++) {
printf("%d ", result[i]);
}
printf("\n");
return;//第一轮循环时候,permute(3)是permute(2)调用因此return是回到permute(2)
}
else
for (int i = 0; i < N; i++)
{
if (used[i] == 0) {
result[k] = a[i];
used[i] = 1;
//递归调用,去填充下一个位置 k+1
permute(k + 1);
used[i] = 0;
}
}
}
5、p103思考题,石头剪刀布
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void)
{
char gesture[3][10] = { "scissor","stone","cloth" };
int man, computer, result, ret;
srand(time(NULL));//随机数相关,time时间戳srand重置随机数种子
while (1)
{
computer = rand() % 3;
printf("0-scissor,1-stone,2-cloth \n");
ret = scanf("%d", &man);//scanf实际上也是一个函数,合法时候返回1
if (ret != 1 || man < 0 || man>2)
{
printf("invalid input\n");
return 1;
}
printf("you: %s\tcomputer:%s\n",gesture[man], gesture[computer]);
result = (man - computer + 4) % 3 - 1;//数值带入进去展开就知道了
if (result > 0)
{
printf("you win\n");
}
else if (result == 0)
{
printf("Draw\n");
}
else
printf("you lose\n");
}
return 0;
}
第十一十二章(难)
插入排序
这个图很形象:
https://www.runoob.com/wp-content/uploads/2019/03/insertionSort.gif
算法过程(自己的理解):
(1)取数 定义一个for循环,j自加取数
(2)比较 将取出的数和j前面的数组的数进行比较
(3)插入 找到合适位置进行插入
(4) 循环 下一轮循环
习题:p341页
1、定义一个二维数组,例如int a[][5]={23,43,4,5,7,45,42,12,11,66,55,47,33,89,1};,编写程序进行排序(从小到大)
#思路就是展开成为一维数组处理
#include <stdio.h>
int main() {
int a[][3] = { // 假设3列
23, 43, 4, 5, 7, 45,
42, 12, 11, 66, 55, 47,
33, 89, 1
};
int rows = sizeof(a) / sizeof(a[0]); // 行数
int cols = sizeof(a[0]) / sizeof(a[0][0]); // 列数
int total = rows*cols; // 总元素个数
printf("%d\n",total);
int flat[15];//这里的数组,我的编译器要求数组大小必须是常量
int index = 0;
int key,i,j;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
flat[index++] = a[i][j];
}
}
for (i = 1;i < total;i++)
{
key = flat[i];
j = i - 1;
while (j >= 0 && key<=flat[j])
{
flat[j + 1] = flat[j];
j--;
}
flat[j + 1] = key;
}
index = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
a[i][j] = flat[index++];
}
}
printf("排序后的二维数组:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%3d ", a[i][j]);
}
printf("\n");
}
return 0;
}
选择排序
https://www.runoob.com/wp-content/uploads/2019/03/selectionSort.gif
上面的使用选择排序实现
#include <stdio.h>
int main1() {
int a[][3] = { // 假设3列
23, 43, 4, 5, 7, 45,
42, 12, 11, 66, 55, 47,
33, 89, 1
};
int rows = sizeof(a) / sizeof(a[0]); // 行数
int cols = sizeof(a[0]) / sizeof(a[0][0]); // 列数
int total = rows*cols; // 总元素个数
printf("%d\n",total);
int flat[15];
int index = 0;
int key,i,j;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
flat[index++] = a[i][j];
}
}
for (i = 1;i < total;i++)
{
key = flat[i];
j = i - 1;
while (j >= 0 && key<=flat[j])
{
flat[j + 1] = flat[j];
j--;
}
flat[j + 1] = key;
}
index = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
a[i][j] = flat[index++];
}
}
printf("排序后的二维数组:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%3d ", a[i][j]);
}
printf("\n");
}
return 0;
}
int main() {
int a[][3] = { // 假设3列
23, 43, 4, 5, 7, 45,
42, 12, 11, 66, 55, 47,
33, 89, 1
};
int rows = sizeof(a) / sizeof(a[0]); // 行数
int cols = sizeof(a[0]) / sizeof(a[0][0]); // 列数
int total = rows * cols; // 总元素个数
// 创建一维数组
int flat[15];
// 将二维数组展平
int index = 0;
int min, i, j,tmp;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
flat[index++] = a[i][j];
}
}
printf("展平后的一维数组(排序前): ");
for (int i = 0; i < total; i++) {
printf("%d ", flat[i]);
}
printf("\n\n");
for (j = 0;j < total;j++)
{
min = flat[j];
for (i = j+1;i<total;i++)
{
if (flat[i] < min)
{
min = flat[i];
flat[i] = flat[j];
flat[j] = min;
}
}
}
printf("\n排序后的一维数组: ");
for (int i = 0; i < total; i++) {
printf("%d ", flat[i]);
}
printf("\n\n");
// 将排序后的一维数组放回二维数组
index = 0;
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
a[i][j] = flat[index++];
}
}
printf("排序后的二维数组:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%3d ", a[i][j]);
}
printf("\n");
}
return 0;
}
归并排序
void merge(int start, int mid, int end) {
int n1 = mid - start + 1;
int n2 = end - mid;
// 动态分配内存
int *left = (int *)malloc(n1 * sizeof(int));
int *right = (int *)malloc(n2 * sizeof(int));
if (left == NULL || right == NULL) {
printf("内存分配失败!\n");
return;
}
int i, j, k;
// 复制数据
for (i = 0; i < n1; i++)
left[i] = a[start + i];
for (j = 0; j < n2; j++)
right[j] = a[mid + 1 + j];
i = j = 0;
k = start;
// 合并
while (i < n1 && j < n2)
if (left[i] < right[j])
a[k++] = left[i++];
else
a[k++] = right[j++];
while (i < n1)
a[k++] = left[i++];
while (j < n2)
a[k++] = right[j++];
// 释放内存
free(left);
free(right);
}
void sort(int start, int end)
{
int mid;
if (start < end)
{
mid = (start + end) / 2;
printf("sort(%d-%d,%d-%d) %d %d %d %d %d %d %d %d\n", start, mid, mid + 1, end, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
sort(start, mid);
sort(mid + 1, end);
merge(start, mid, end);
printf("sort(%d-%d,%d-%d)to %d %d %d %d %d %d %d %d\n", start, mid, mid + 1, end, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
}
}
int main(void)
{
sort(0, LEN - 1);
return 0;
}
深度优先算法
广度优先算法
第22章-指针
1、思考一下,为什么要用typedef定义类型名而不用#define定义类型名?比如:
typedef int *pint_t
#define pint_t int *
有何区别
网上这个解答很好:
typedef是类型别名,define是文本替换
//typedef版本
pint_t a, b;
// 等价于:int *a, *b; (a和b都是int*类型,符合预期)
// #define版本
pint_t a, b;
// 预处理后替换为:int *a, b;
// 实际效果:a是int*,b是int(仅第一个变量是指针)
2-3
对照本节的描述,像图 23.1 “指针的基本概念”那样画图理解函数的调用和返回过程。在下一章我们会看到更复杂的参数和返回值形式,在初学阶段对每个程序都要画图理解它的运行过程,只要基本概念清晰,无论多复杂的形式都应该能正确分析。
现在回头看第 3 节 “形参和实参”的习题1,那个程序应该怎么改?
改成用地址传递了
4、

浙公网安备 33010602011771号