260922注意这个不然你scanf连着直接让你暴雷信不信空格空格空格3.scanf读取char用%c%c会读取空格如要取消其对空格的读取在%c前加上空格即可charc;scanf( %c,c);260925递归函数还是太神了无敌套娃定义函数 factorial 计算阶乘递归的核心思想把大问题拆成同构的小问题自己调用自己直到遇到终止条件base case才停止。阶乘的递归公式为factorial(n) n * factorial(n-1)当n 0或n 1时返回 1。没用递归之前belike#includestdio.hlonglongfactorial(intn){longlonga1;for(longlongi(longlong)n;i0;--i){a*i;}returna;}intmain(){intj0;printf(Enter a integer:\n);scanf(%d,j);printf(%ds factorial is %lld\n,j,factorial(j));return0;}对比一下两种写法循环版用for累乘直观但代码稍长递归版代码更简洁但每次调用都会占用栈空间n过大时可能栈溢出。建议先理解递归的「递推 回归」过程再动手写代码。用递归之后belike#includestdio.hlonglongfactorial(intn){if(n1||n0){return1;}else{returnn*factorial(n-1);}}intmain(){longlonga0;printf(Enter a positive integer:\n);scanf(%lld,a);printf(%llds factorial is %lld,a,factorial(a));return0;}小练习试着把「计算素数」一节也改写成递归思路比如用递归判断一个数是否为素数从sqrt(p)往下试除。这样能把今天学的递归和素数判断串起来。计算素数毫无头绪这都哪跟哪跟我说一个非素数p肯定可以表示为a*ba,b必有一个数小于p的开平方然后去试开平方函数sqrt()需引用math.h一个函数可以有多个return语句但是只会执行其中一个函数也就执行并返回一次://自定义素数判断函数intis_prime(intn){for(inti2;i(int)aqrt(n);i){if(n%i0){return0;}}return1;//只能返回一次所以当判断为合数的时候就直接return 0;了不会走return 1;}被自己整红温了我靠下面放错误代码#includestdio.h#includemath.hintis_prime(intn){doublessqrt(n);for(inti2;i(int)s;i)//错误就在这里{if(n1){return0;}if(n%i0){return0;}}return1;//只能返回一次所以当判断为合数的时候就直接return 0;了不会走return 1;}intmain(){inta0;printf(Please enter a positive integer:\n (0 means that %d is not prime, 1 means that %d is prime)\n,a,a);scanf(%d,a);printf(%d,is_prime(a));return0;}以下是左右脑互博过程乍一看没毛啊但是当输入n 1的时候返回值就变成1了 然后分析了一遍当n1的时候s1for循环里面判断条件变成了2 1循环直接判false了循环爆了剩return 1了所以1也是素数了但是啊我在打下上面一段话的时候鬼脑突然发动把n2带进去分析了一遍发现for循环也false了冤种但是2真的是素数所以return 1也没毛。。真的是一个bug是bug一堆bug能work。我没招了我要想想怎么修。。我绷不住了n3的话for也爆但是结果还是对的啊啊啊啊不对好像这么判断就是对的因为这段代码的思路就是把n拆成两个数的乘积然后除那个比较小的数那2和3拆完比较小的数都是1肯定不能除1for循环判false是对的不是bug我是傻逼好了经过左右脑互搏后我知道改n1那个bug就行订正代码#includestdio.h#includemath.hintis_prime(intn){doublessqrt(n);if(n1){return0;}for(inti2;i(int)s;i){if(n%i0){return0;}}return1;//只能返回一次所以当判断为合数的时候就直接return 0;了不会走return 1;}intmain(){inta0;printf(Please enter a positive integer:\n (0 means that %d is not prime, 1 means that %d is prime)\n,a,a);scanf(%d,a);printf(%d,is_prime(a));return0;}其实就是把n 1的if语句放到for循环前面了260926运算符运算先后顺序补充括号 () 逻辑非 ! 算术运算符(, /) 关系运算符(!) 逻辑逻辑与左右两边只要有一个为假结果就为假。逻辑或||只有两边都为假时结果才为假。‘\0’ 只出现在字符串里比如charstr[4]abc;解释str[0] ‘a’str[1] ‘b’str[2] ‘c’str[3] ‘\0’关于指针inta10;int*pa;//指针变量是p不是*p。并且不能掉int *p取的是地址不是变量a的值printf(%d\n,*p);//输出10因为*p是a的地址通过*p找到了a的值*p20;//a的值通过指针变量p找到了地址并赋值20int*p1NULL;//p1指针变量还没有目标的地址一定要先赋NULL不然程序就爆了printf(指针 p 里存的地址是: %p\n,p);//%p是用来打印p的地址的输出结果为类似0x7ffee4b5c8acswap自定义函数用指针成功实现#includestdio.hvoidswap(int*a,int*b)//定义交换值函数swap{intc*b;*b*a;*ac;}intmain(){intinteger10;intinteger20;printf(Enter two integers:(like 3 4)\n);scanf(%d %d,integer1,integer2);swap(integer1,integer2);//交换两个整数值不要忘记取地址printf(%d %d,integer1,integer2);return0;}关于swap函数中int *a和int *b算不算野指针未初始化voidswap(int*a,int*b)不算野指针。int *a和int *b是swap函数的函数形式参数形参 形参的特点是在函数被调用的时候一定会被实际参数实参赋值注意数组名本身就是首元素地址intarr[3]{10,20,30};int*parr;//数组名本身就是首元素地址printf(%d\n,*p);printf(%d\n,*(p1));//p 1不是加 1 个字节而是加 1 个int大小通常4字节指向下一个元素printf(%d\n,*(p2));arr 等价于 arr[0]即数组名传参时退化为指针并且是首元素的指针*(p i) 等价于p[i]二级指针晕晕晕理解inginta10;int*pa;// 一级指针指向 intint**ppp;// 二级指针指向 int*鲸鱼娘给的解释痛苦理解理解不了。。。每天看一遍得了