C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

文章目录

return

#include<stdio.h>
char* show(){
	char str[] = "hello world";
	return str;
}
int main(){
	char *ch = show();
	printf("%s\n", ch);
	return 0;
}

我们先看一下这个代码,这个代码是有问题的,大家可能都能知道,str数组,在show函数里面定义,是局部变量,出了作用域会销毁,所以打印乱码,但是知道这一点还是太浅显了,接下来讲一些干货!!!!!!!
**先问两个问题:

1.C语言中有字符串和字符串类型吗?

C语言中没有字符串类型但是有字符串,定义一个字符串可以利用指针,或者数组,字符串的末尾是以反斜杠0结尾,不作为字符串的一部分,只是作为一个结束标识符要明确,求字符串长度和大小是不一样的,求字符串的长度是不包含反斜杠0的,求字符串的大小是本质就是求在这字符串占用几个字节空间,所以要加上反斜杠0.

2.我们平常删除数据,比如说删除一部电影是真的在内存中删除了吗

在计算机中删除一个数据就是清空为0/1吗?
不是的,比如说:我们下载一部电影3个G,需要5分钟,但是你删除的时候,2~3秒就删除了呢
其实计算机删除数据只要把个数据,设置为无效就欧克了
,可能是通过一些协议啥的,这样设置完之后,你就可以再次利用这块空间,进行写入。

接下我们在栈帧方面解释上面那个代码

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

现在我们谈一个问题:函数调用会开辟栈帧,函数中的变量,会在栈帧中开辟空间,问题来了,你咋确保你开辟的栈帧,一定够函数中变量开辟空间用呢

解释:我们函数中变量定义肯定是有类型的这是毋庸置疑的,我们的程序没有运行之前,编译器就会根据我们的类型来预估最少开辟多大的空间,根据这个预估,编译器就会合理的开辟出我们所需要的空间
这也体现了我们关键字的作用,就是告诉编译器我需要多大的空间

经过上面的学习我们就可以理解一下递归的问题了

递归在没有出口的时候,函数就会重复的被调用,每次调用的也没释放,就会在栈空间连续的向下放,最后就会发生栈溢出

为什么临时变量具有临时性?

大家都知道了,函数调用形成栈帧,返回函数释放栈帧,C语言中的变量大部分都是在函数中定义的,就说明是局部变量,除了static修饰的。
函数调用,栈帧就开辟,该函数里的变量,就会在栈帧中开辟自己的空间,函数返回,栈帧释放,栈帧都释放了,在该栈帧中定义的变量,肯定也被释放了呗,好比,宇宙都毁灭了,还会有星球吗

言归正传继续讲解return

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
我们看着个代码,经过上面所说函数调用形成栈帧,函数返回,释放栈帧,哪这个GetData函数,为啥还可以返回x值呢???
解释:
直接查看反汇编
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
F10直接进去
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
接着返回主函数
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
从这我们可以明白,我们之前理解的没错,函数返回就是释放栈帧,x的值为啥能返回来是因为:函数的返回值是通过,寄存器的方式,返回函数调用方的!!!
------------------------------------------------------------------------------------------------
我们如果要是不接收函数的返回值会怎末样呢?
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】继续反汇编
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

在返回主函数
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】总结:函数的返回值是通过寄存器的方式返回调用方的;
如果函数的返回值没有被接收的,被调函数还是会把返回值放到寄存器;

---------------------------------------------------------------------------------------------

const

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
const修饰的变量是不能直接修改的,是可以间接修改的
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
const修饰的变量可以间接的被修改,那const的意义何在呢
1,const修饰的变量,并非是,不可修改的常量
2,const修饰变量是给编译器看的,告诉编译器,这个变量是不可以修改的,如果有人修改了,你就直接报错
3,const修饰的变量是给兄弟们看的,告诉兄弟们,这个变量不要改

看一个真的不能修改的
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

如果编译器对const报错是在编译的时候报错的,不是在运行之后报错的,
const修饰变量就是给编译器看的

const修饰出数组

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
const修饰的数组,数组的每个元素都不能被修改

const修饰指针

在此我们先谈一下指针!!!

指针变量和指针是一个概念吗?

指针

简单说一下指针是什么为啥要有呢?
我们都住过宿舍,每个宿舍都有门牌号吧,这就是个标识,能告诉别人,你住在那个屋子里面。
指针也是对每个内存单元的一个标识,这样在使用这块空间的时候,才能找到。换句话说其实指针就是地址。
为啥要有指针是为了提高查找效率。如果没有指针还有遍历整个内存找数据吗?如果没有门牌号找人还要搜查整个宿舍楼吗

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
指针变量
指针变量,是变量呀,指针就是数据呀,是数据就可以被存放呀,所以指针变量就是用来存放指针相关数据的变量,在32位平台,4字节,在64位平台,8字节
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

左值与右值

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】任何变量名在不同的场景中代表不同的含义!!!
指针也是一样的
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
第7行指针变量p在这代表的是p的空间,存放的是b的地址。
第8行指针变量p代表的是p空间里面的内容,即b的地址,存到指针变量q中

解引用

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
(类型相同)对指针进行解引用,代表指针所指向的目标
p指向a,解引用p,就是a!!!


言归正传const修饰指针

第一种

#include<stdio.h>
int main(){
	int a = 10;
	const int *p = &a;//const修饰*号,表示p指向的变量不可以修改
	*p = 100;
	p = 100;
	return 0;
}

第二种

#include<stdio.h>
int main(){
	int a = 10;
      int  const *p = &a;//const修饰*号,表示p指向的变量不可以修改
	*p = 100;
	p = 100;
	return 0;
}

第三种

#include<stdio.h>
int main(){
	int a = 10;
    int * const p = &a;//const修饰p,表示p的内容不能被修改,即p的指向不能被修改,只能指向a
	*p = 100;
	p = 100;
	return 0;
}

第四种

#include<stdio.h>
int main(){
	int a = 10;
    int const * const p = &a;//const修饰p,表示p的内容不能被修改,即p的指向不能被修改,只能指向a
	*p = 100;               //const修饰*,表示p指向的变量不能直接被修改
	p = 100;
	return 0;

我们再看两种情况!!!
第一种:
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
第二种:
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】------------------------------------------------------------------------------------------

const修饰函数参数

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

void show(const	int *_p){
	printf("%d\n", *_p);
}
int main(){
	int a = 10;
	int*p = &a;
	show(p);
	return 0;
}

临时拷贝的知识点

函数调用时,会形成一份临时拷贝,那么参数要是指针变量呢,会形成临时拷贝吗?
C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
答案是也会形成临时拷贝,指针变量也是变量呀,里面存放的是地址,地址也是数据呀,是数据就要形成临时拷贝呀
C中,任何函数参数都一定要形成临时变量,包括指针变量

const修饰返回值

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】

volatile

首先要明确,在没有加volatile的代码,默认会被优化,加上就不会被优化。
大概解释一下:
不加volatile

#include <stdio.h>
int pass = 1;
int main()
{
while(pass){ //思考一下,这个代码有哪些地方,编译器是可以优化的。
} 
return 0;
}

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
加volatile

#include <stdio.h>
volatile int pass = 1; //加上volatile
int main()
{
while(pass){
} 
 return 0;
}

C深刨7 完全搞懂 return const volatile 干货多多!!!【建议收藏!!!】
结论: volatile 忽略编译器的优化,保持内存可见性
其他问题:

const volatile int a = 10;
在vs2013和gcc 4.8中都能编译通过
const是在编译期间起效果
volatile在编译期间主要影响编译器,形成不优化的代码,进而影响运行,故:编译和运行都起效果。
const要求你不要进行写入就可以。volatile意思是你读取的时候,每次都要从内存读。两者并不冲突。
虽然volatile就叫做易变关键字,但这里仅仅是描述它修饰的变量可能会变化,要编译器注意,并不是它要求对应变量必须变化!这点要特别注意

完结

上一篇:ConcurrentHashMap的简介


下一篇:volatile探秘