首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C语言保留字(关键字)详解

1.return:结束一个函数并返回其后面表达式中。初学时候,有些不理解main 函数中return 0;有什么用,在写程序时候老是忘记带上了。其实,带上return 0;是很有必要。...程序中,函数test返回指向局部变量num指针,当主函数调用test函数时候,返回ptr指针并且赋值给p指针变量,即num变量地址赋给了p,但是必须明白,在test函数结束时候,局部变量num...乍一看,和预期一样,但是实际上,这样程序是存在隐患。下面改改这个程序,就知道错在哪了。 运行结果:15,7(也可能是15,9视具体环境而定。)在这里,多了个test2函数。...这时候就会把之前释放那块空间给x,y再次分配使用,使用在赋值语句后,该空间发现了改变,使得*p发生了改变。所以,切记 return不能返回指向局部变量类型。 2.void:空类型。...例如该例中都是限定m10)但是要注意一点,只读变量虽然不能改变,但它还是变量,不是常量。如 int const M = 10; int a[M]; 这样定义数组是错误

1.8K40

一个printf(结构体指针)引发血案

打印内存模型 可以从打印结果看,第一个输出数字是 1,与预期符合;第二个输出 97,很明显是字符 'a' ASCII 码,但是 p 怎么会指到 name 变量地址里呢?...s 与 p 都代表一个地址,打印结果它俩相同,也是符合预期。 那就见鬼了:既然 s 与 p 代表同一个内存地址,但是为什么用 *p 读取 int 型数据时,得到却是字符 'a' 呢? 2....从现象上看,似乎是 printf 语句在执行过程中打印第一个数字之后,影响到了指针 p ,但是具体是怎么影响说不清楚,而且它是系统里库函数,肯定不能改变 p 。..., 30}; printf("%d %d %d \n", a, a, a);} 编译、执行,打印结果:10 20 30,把 3 个成员变量都打印出来了,太诡异了!...因为栈中所有动态参数被提取后,arg 0x01020310(最后一个参数上一个地址),如果不设置 NULL 的话,下面使用的话就得到未知结果,为了防止误操作,需要设置NULL。

85220
您找到你想要的搜索结果了吗?
是的
没有找到

一个printf(结构体指针)引发血案

打印内存模型 可以从打印结果看,第一个输出数字是 1,与预期符合;第二个输出 97,很明显是字符 'a' ASCII 码,但是 p 怎么会指到 name 变量地址里呢?...s 与 p 都代表一个地址,打印结果它俩相同,也是符合预期。 那就见鬼了:既然 s 与 p 代表同一个内存地址,但是为什么用 *p 读取 int 型数据时,得到却是字符 'a' 呢? 2....从现象上看,似乎是 printf 语句在执行过程中打印第一个数字之后,影响到了指针 p ,但是具体是怎么影响说不清楚,而且它是系统里库函数,肯定不能改变 p 。...{10, 20, 30}; printf("%d %d %d \n", a, a, a); } 编译、执行,打印结果:10 20 30,把 3 个成员变量都打印出来了,太诡异了!...因为栈中所有动态参数被提取后,arg 0x01020310(最后一个参数上一个地址),如果不设置 NULL 的话,下面使用的话就得到未知结果,为了防止误操作,需要设置NULL。

67420

C语言中函数参数传递三种方式

从被调用函数角度来说,传递是单向(实参->形参),参数只能传入, 不能传出。当函数内部需要修改参数,并且不希望这个改变影响调用者时,采用传递。...,(不同机器可能会有所差别) 可以看出,实参地址0x22ff44 采用传递时候,函数操作地址是0x22ff20并不是实参本身,所以对它进行操作并不能改变实参 再看引用传递,操作地址就是实参地址...一旦引用被初始化,就不能改变引用关系(指针则可以随时改变所指对象)。 指针传递实质: 指针传递参数本质上是传递方式,它所传递是一个地址。...指针变量在符号表上对应地址指针变量地址,而引用在符号表上对应地址引用对象地址。符号表生成后就不会再改,因此指针可以改变其指向对象(指针变量中可以改),而引用对象则不能修改。...;(具体指没有int& const a这种形式,而const int& a是有 , 前者指引用本身即别名不可以改变,这是当然,所以不需要这种形式,后者指引用所指不可以改变) 引用不能为空

2K10

详解准确率、精确率、召回率、F1等评价指标的含义

先看预测结果(P|N),然后再针对实际结果对比预测结果,给出判断结果(T|F)。按照上面逻辑,重新分配后为 ? TP、FP、FN、TN可以理解 TP:预测1,实际1,预测正确。...2.准确率 首先给出准确率(Accuracy)定义,即预测正确结果占总样本百分比,表达式 ? 虽然准确率能够判断总正确率,但是在样本不均衡情况下,并不能作为很好指标来衡量结果。...5.F1分数 精确率和召回率又被叫做查准率和查全率,可以通过P-R图进行表示 ? 如何理解P-R(精确率-召回率)曲线呢?或者说这些曲线是根据什么变化呢? 以逻辑回归举例,其输出是0-1之间数字。...上图P-R曲线中,平衡点就是F1分数。 6.Roc、AUC曲线 正式介绍ROC和AUC之前,还需要再介绍两个指标,真正率(TPR)和假正率(FPR)。...因此我们从实际表现各个结果出发,就能避免样本不平衡问题,这就是为什么用TPR和FPR作为ROC、AUC指标的原因。

35.3K53

独家 | 115个AB测试分析结果︰平均提升为4%,大部分缺乏统计检定力

2. p(统计显著度)和置信区间是为了计算绝对差异,但推断目标却是百分比改变(百分比提升)。因此,笔者用了恰当p和置信区间来表示百分比提升。...我们可以看到,115个测试中有18个测试结果重新评级︰ 根据GoodUI定义,有︰ p小于等于0.03结果p小于等于0.25可能结果p大于0.25不显著结果。...每一个评级结果都是连续(例如若果p0.01,则测试评级不能同时强和可能)。...举个例子,一个有着实际上0.08p测试,在经过5次窥探后,就可以得到一个名义上0.025 p,这里实际上p大大偏离了0.05阈值,且是名义上p3.2倍。...这里便出现了问题,因为我们不能简单地进行成对t检定或z检定,就像GoodUI中对一个个变量和对照进行p计算。

33830

C语言:深入理解指针(1)

通过如图代码,可以得到3个结论: 1.const如果在*左边,const修饰是*p,也就是修饰指针指向内容,保证指针指向内容不能通过指针来改变,但是指针变量p本身内容是可以改变。...(*p=20是不可行p=&a是可行) 2.const如果在*右边,const修饰p本身,保证指针变量p内容不能被修改,但是指针指向内容是可以改变。...= '\0')//这里也可以写成*p,因为'\0'ascii是0 p++;//p加1一次就往后移动4个字节 return p - s;//指针-指针得到绝对是指针之间元素个数(前提条件:...,此时再去访问得到就是一个随机。      ...如果该表达式假(返回零), assert() 就会报错,在标准错误 流 stderr 中写⼊⼀条错误信息,显⽰没有通过表达式,以及包含这个表达式⽂件名和⾏号。

11610

指针(1)--对于指针基本概念介绍

也就是说虽然指针变量大小不会改变,但是它可以被类型给区分从而得出不同操作结果。...其实const使用是非常灵活,它既可以放在*p又可以修饰p,其结果是不同。...const* p = &n; *p = 20; p = &m; //A和B两种情况都将const放在*左边,此时限制是*p 修饰是指针指向内容,保证指针指向内容不能通过指针来改变。...⾝,保证了指针变量内容不能修改,但是指针指 向内容,可以通过指针改变。...(3)传址调用 设想:通过函数来交换 得到结果是: 原因就是,形参和实参都有自己独立空间,对于在函数内部形参交换并不会影响到主函数内实参变量改变。对形参影响是不会影响实参

6710

shared_ptr是线程安全吗?

预期结果: *global_instance is 200000000 画外音: 执行结果 不是预期结果,肯定不是线程安全。 为什么还说内置安全。...画外音 智能指针有2个成员,一个是引用计数是原子,另外一个原始指针 不是 综合来说 就不是 继续查看文档shared_ptr_thread_safety Examples: 引用计数改变 原子操作...Writing different shared_ptr instances from two threads 引用计数改变 原子操作 安全 // thread A p.reset(new int(1912...为了简化并突出重点,后文只画出 use_count : ? 以上是 shared_ptr x(new Foo); 对应内存数据结构。...为什么用一个类来管理另外一个指针呢 提示: 聚合关系图: ? 组合关系图: ? 2. 共享指针缺点 提示: ? ?

10.3K31

《C++Primer》第四章 表达式

但是在C++语言中,两者区别没有那么简单: 左表达式求值结果是一个对象或者一个函数,但是以常量对象代表某些左不能作为赋值语句左侧运算对象 虽然某些表达式求值结果是对象,但是它们实际上是右而不是左...递增和递减运算符 前置版本和后置版本 后置版本也会将运算对象加/减一,但是求值结果是运算对象改变之前副本。...运算得到指针你指向对象所占空间大小,指针本身不需要有效 对数组执行sizeof运算得到整个数组所占空间大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和 对string对象或...void*指针中: void* p = &d; double *dp = static_cast(p); const_cast const_cast只能改变运算对象底层const...= const_cast(pc); // 正确,但是通过p是未定义行为 reinterpret_cast 使用reinterpret_cast是非常危险,主要是因为类型改变了但是编译器没有给出任何警告或者错误提示信息

83910

让人头大各种锁,从这里让你思绪清晰

CAS操作过程就是将内存中将要被修改数据与预期进行比较,如果这两个相等就修改,否则就不做操作也就是说CAS需要三个操作预期 A 内存中V 将要修改B 简单来说CAS就是一个死循环...,在循环中判断预期和内存中是否相等,如果相等的话就执行修改,如果如果不相等的话就继续循环,直到执行成功后退出。...CAS问题 CAS虽然很牛逼但是它也存在一些问题比如ABA问题,举个例子,现在有内存中有一个共享变量XA,这个时候出现一个变量想要去修改变量X,首先会获取X这个时候获取是A,然后使用CAS...这样看起来是没有问题,那如果在线程1获取变量X之后,执行CAS之前出现一个线程2把X修改成B然后CAS操作执行又修改成了了A,虽然最后执行结果共享变量A但是此A已经不是线程1获取A了。...它允许一个资源可以被多个读操作访问,或者被一个 写操作访问,但两者不能同时进行。

20720

让人头大各种锁,从这里让你思绪清晰

CAS操作过程就是将内存中将要被修改数据与预期进行比较,如果这两个相等就修改,否则就不做操作也就是说CAS需要三个操作预期 A 内存中V 将要修改B 简单来说CAS就是一个死循环...,在循环中判断预期和内存中是否相等,如果相等的话就执行修改,如果如果不相等的话就继续循环,直到执行成功后退出。...CAS问题 CAS虽然很牛逼但是它也存在一些问题比如ABA问题,举个例子,现在有内存中有一个共享变量XA,这个时候出现一个变量想要去修改变量X,首先会获取X这个时候获取是A,然后使用CAS...这样看起来是没有问题,那如果在线程1获取变量X之后,执行CAS之前出现一个线程2把X修改成B然后CAS操作执行又修改成了了A,虽然最后执行结果共享变量A但是此A已经不是线程1获取A了。...它允许一个资源可以被多个读操作访问,或者被一个 写操作访问,但两者不能同时进行。

32920

让人头大各种锁,从这里让你思绪清晰

CAS操作过程就是将内存中将要被修改数据与预期进行比较,如果这两个相等就修改,否则就不做操作也就是说CAS需要三个操作预期 A 内存中V 将要修改B 简单来说CAS就是一个死循环...,在循环中判断预期和内存中是否相等,如果相等的话就执行修改,如果如果不相等的话就继续循环,直到执行成功后退出。...CAS问题 CAS虽然很牛逼但是它也存在一些问题比如ABA问题,举个例子,现在有内存中有一个共享变量XA,这个时候出现一个变量想要去修改变量X,首先会获取X这个时候获取是A,然后使用CAS...这样看起来是没有问题,那如果在线程1获取变量X之后,执行CAS之前出现一个线程2把X修改成B然后CAS操作执行又修改成了了A,虽然最后执行结果共享变量A但是此A已经不是线程1获取A了。...它允许一个资源可以被多个读操作访问,或者被一个 写操作访问,但两者不能同时进行。

29610

让人头大各种锁,从这里让你思绪清晰

CAS操作过程就是将内存中将要被修改数据与预期进行比较,如果这两个相等就修改,否则就不做操作也就是说CAS需要三个操作预期 A 内存中V 将要修改B 简单来说CAS就是一个死循环...,在循环中判断预期和内存中是否相等,如果相等的话就执行修改,如果如果不相等的话就继续循环,直到执行成功后退出。...CAS问题 CAS虽然很牛逼但是它也存在一些问题比如ABA问题,举个例子,现在有内存中有一个共享变量XA,这个时候出现一个变量想要去修改变量X,首先会获取X这个时候获取是A,然后使用CAS...这样看起来是没有问题,那如果在线程1获取变量X之后,执行CAS之前出现一个线程2把X修改成B然后CAS操作执行又修改成了了A,虽然最后执行结果共享变量A但是此A已经不是线程1获取A了。...它允许一个资源可以被多个读操作访问,或者被一个 写操作访问,但两者不能同时进行。

29340

Golang “omitempty” 关键字详解

":"小饭"} 但是我们实际运行一下返回结果却是 {"Name":"小饭","Age":0} 这明显是不符合我们预期,因为Age字段是我们不需要。...「没有初始化结构体任何属性」,所以转换成json之后打印结果应该是只有{"Num":5},但是我们实际运行之后发现打印结果却是 {"Num":5,"Person":{"Name":"","Age...为什么用指针类型就可以解决这个问题?因为「指针是基本类型,Golang知道他是啥」,所以就直接赋值nil(指针类型)。...{ Per := Person{ Age: 0, } res, _ := json.Marshal(Per) fmt.Println(string(res)) } 按照咱们预期,应该给输出...「因为Golang把0当成了零,所以跟没有赋值是一样」如果想解决这种问题一种方法是「使用int指针」,因为int指针nil,当我想输出0时候,我传进去地址,地址肯定不是空nil,这样肯定会显示出来

1.1K10

让人头大各种锁,从这里让你思绪清晰

CAS操作过程就是将内存中将要被修改数据与预期进行比较,如果这两个相等就修改,否则就不做操作也就是说CAS需要三个操作预期 A 内存中V 将要修改B 简单来说CAS就是一个死循环...,在循环中判断预期和内存中是否相等,如果相等的话就执行修改,如果如果不相等的话就继续循环,直到执行成功后退出。...CAS问题 CAS虽然很牛逼但是它也存在一些问题比如ABA问题,举个例子,现在有内存中有一个共享变量XA,这个时候出现一个变量想要去修改变量X,首先会获取X这个时候获取是A,然后使用CAS...这样看起来是没有问题,那如果在线程1获取变量X之后,执行CAS之前出现一个线程2把X修改成B然后CAS操作执行又修改成了了A,虽然最后执行结果共享变量A但是此A已经不是线程1获取A了。...它允许一个资源可以被多个读操作访问,或者被一个 写操作访问,但两者不能同时进行。

32520
领券