基础不牢地动山摇之牛客刷题《二》
个人主页:欢迎大家光临——>沙漠下的胡杨
各位大帅哥,大漂亮
如果觉得文章对自己有帮助
可以一键三连支持博主
你的每一分关心都是我坚持的动力
![]()
☄: 本期重点:牛客刷题《二》
希望大家每天都心情愉悦的学习工作。
牛客刷题
一.实参和形参
二.空指针是什么呢?
三.const修饰变量
四.负数取模
五.全局变量和改变循环条件的影响
六.逗号表达式
七:sizeof和数组名以及 数组和指针的关系
一.实参和形参
看一下代码,输出结果为什么呢?
void fun(char* p){p = p + 1;}int main(){char a[] = { '1', '2', '3', '4' };fun(a);printf("%c\n", *a);return 0;}
首先分析下:
其中p是临时变量,改变p不会改变a的内容的。
看下示意图:
![]()
![]()
我们可以看出,p的值发生改变啦,但是a的内容是没有改变的,这是一个典型的形参和实参关系的代码,其中可以进一步观看栈帧的形成来理解——》函数栈帧
二.空指针是什么呢?
空指针是什么呢?下面哪一个是正确的呢?
我们来看图:
这个图我知道了,NULL其实就是0地址的空间。
这个值我们不能调用,不能直接使用。
其实NULL本质上是把 0 强制转化为 void *后定义的值。
我们这样进行写,也是可以的(非常不建议):
是没有警告的,这样赋值也没错(非常不建议)。
三.const修饰变量
const修饰变量:
int b;(1)const int *a = &b;(2)int const *a = &b;(3)int *const a = &b;
下面那两个代码一样呢?
首先我们看下是关于const知识点的,const修饰变量时,就看是在 * (解引用)前还是后,如果在前,就是修饰变量的值不可直接改变,可以通过一级指针间接改变。
如果在后,就是修饰变量的地址不可直接改变,可以通过二级指针改变。
详情见————》const讲解
四.负数取模
我们看个比较新鲜的,负数取模问题
int main(){int a = 5, b = -5;printf("%d,%d", a % (-4), b % (-4));}
推荐大家先阅读下这篇文章 ——》负数取模详解
不然下面的概念就不太清楚啦~
下面我们先看下 5 %(-4)可能是什么呢?
商是 -1.25,怎么取整呢?在C语言是0向取整,所以商是-1,那么余数也就是-1啦。
同理看下 (-5)%(-4)呢?
商是1.25,C语言默认 0 向取整,所以商为1,那么余数就是 1 啦。
五.全局变量和改变循环条件的影响
看个代码,输出结果是什么:
#include int i;void prt(){ for (i = 5; i < 8; i++) printf("%c", '*'); printf("\t");}main(){ for (i = 5; i <= 8; i++) prt();}
我们一点点分析,首先 i 是全局变量,第一次循环,进入 prt 函数中 i = 5,然后再函数中进行打印 *号,出函数时 i 变为 8 了,在进行 i++,就变成 9 啦,结束main函数。
我们接着看图吧:
六.逗号表达式
我们看下逗号表达式的东西吧~!
首先逗号表达式是:
逗号表达式,是c语言中的逗号运算符,优先级别最低,它将两个及其以上的式子联接起来,从左往右逐个计算表达式,整个表达式的值为最后一个表达式的值。
第一:首先x = y = 8,然后x+y没有赋值, x+1就是9。
第二和第一是一样的。
第三:x = 8,然后x +1还没有赋值,y = 8,此时x+y 为 18。
第四:y = 8,y+1没有赋值,x = y = 8,然后 x + 1 为 9 。
七:sizeof和数组名以及 数组和指针的关系
看个代码,函数返回结果是什么?
struct TEST_TYPE { int a; int b;};int testSize(struct TEST_TYPE val[10]) { return sizeof(val);}
我们可以看出,是先创建一个结构体,然后我们传的参数是一个结构体数组,然后我们这里用sizeof计算数组的大小,理论上应该为40,但是结果为4,为什么呢?
这里给大家推荐一篇详解 数组和指针关系的文章 ——》指针和数组的亲密关系
虽然我们在这里用的是数组传参,其实上实际上 val 已经是一个指针啦,我们计算的是指针大小,当然是 4 个字节啦。