目录
1、在不开辟新的内存空间的情况下,如何交换a,b两个变量中的值?
2、全局变量和局部变量在内存中是否有区别?如果有是什么区别?
3、队列和栈有什么区别?
4、 局部变量能否和全局变量重名?
5、如何引用一个已经定义过的全局变量?
6、全局变量可不可以定义在可被多个.C文件包含的头文件中?
7、do···while 和while···do有什么区别?
8、static 全局变量、局部变量、函数与普通全局变量、普通的局部变量、普通函数有什么区别?
9、程序的内存分配?
10、描述内存分配方式以及它们的区别?
11、简述数组和指针的区别
12、关键字static的作用是什么?
13、引用与指针的区别是什么?
14、malloc 和 calloc的区别
void swap1(int &a,int &b)
{
a = a + b;
b = a - b;
a = a - b;
}
void swap2(int &a,int &b)
{
a = a * b;
b = a / b;
a = a / b;
}
前两种方法是采用一种简单的加减法、乘除法算法来达到交换两个值的目的。这种方法的缺点是做加法、减法、乘法的时候可能会导致数据溢出。
void swap3(int &a,int &b) //最安全效率最高
{
a = a ^ b;
b = a ^ b;
a = a ^ b;
}
第三种方法是通过按位异或的方式交换两个值。按位异或运算符"^"的功能是将参与运算符的两个数各对应的二进制位相异或,如果对应的二进制位相同,则结果为0,否则结果为1。这样运算3次即可交换两个数。如:3(0011)和4(0100),异或一次后为7(0111),再和4异或得3(0011),7和3再异或得4(0100)。
有。
(1)生存周期不同。全局变量的生命周期和整个程序相同,只有程序运行结束全局变量才会被撤销其内存空间才会被释放;而局部变量在程序运行期间不是一直存在,而是只在其所在函数执行期间存在,函数的一次调用执行结束后,局部变量就会被撤销,其所占的内存也被释放。
(2)作用范围不同。全局变量具有全局作用域,全局变量只需在一个源文件中定义,就可以作用于所有的源文件;局部变量只有局部作用域,其作用范围只是在它所在的函数或者循环内。
(3)在内存中的位置不同。全局变量存放在内存中的全局区(静态区);而局部变量是在内存中的栈区。
队列是先进先出(First In First Out),从rear进队从front出队。
栈是先进后出(First In Last Out),只有一个口供进出。
能。因为局部变量会屏蔽全局变量。若要使用全局变量,需要使用域解析符“::”。
(1)用引用头文件的方式。可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时链接不会出错
(2)用extern关键字。
可以。但引用改变量的地方要先用extern声明。但是不推荐这种写法。
(不同的编译器处理结构不同,Dev C++中编译运行没问题)
头文件尽量只有声明,不要有定义。这么做不仅仅可以减弱文件间的编译依存关系,减少编译带来的时间性能消耗,更重要的是可以防止重复定义现象的发生,防止程序崩溃。
变量的定义只能出现一次,否则会导致重复定义。但却可以声明多次。因此全局变量不建议定义在头文件中。因为当该头文件被多个c文件包含的话,会导致重复定义。因此一般做法是在某个特定的头文件中用extern声明,而在另外一个特定的.c文件中定义。需要使用就包含前者。
//可以这样定义的例子
https://blog.csdn.net/qq_39490500/article/details/79402320
//对如此定义可能编译或链接出错的例子
https://blog.csdn.net/yuqian123455/article/details/102856728
do-while是一种“后判定”循环结构,它先执行循环体,后判断条件,因此无论条件是否成立,将至少执行一次循环;而while语句则是先判断条件,后执行循环体,因此可能一次循环也不执行。
1) 全局变量的说明之前再加static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。
2) 把局部变量改变为静态变量后,改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
3) static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为static函数,static函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件。
综上所述:
static全局变量与普通的全局变量有什么区别:
static全局变量只初始化一次,防止在其他文件单元中被引用; static局部变量和普通局部变量有什么区别: static局部变量只被初始化一次,下一次依据上一次结果值; static函数与普通函数有什么区别: static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。
//摘自
https://blog.csdn.net/subo86/article/details/4814874?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
可执行程序主要分为:
数据段、代码段、bss段(Block Started by Symbol)
(1) 数据段存放已初始化的全局变量和静态变量,数据段属于静态内存分配。
(2) 代码段用来存放程序的代码内存空间。它的大小在程序运行前就已经确定了,并且该区域只能读不能写。在代码段中,也有可能包含了一些只读的常数变量,例如字符串常量等。
(3) BSS段(Block Started by Symbol)存放未初始化的全局变量和静态变量。BSS段的数据是可读写的,链接器从可执行文件中得到BSS段的大小,然后申请得到这块内存空间,这块内存空间紧跟在数据段的后面。由此可知BSS段并不占用可执行文件的大小。在使用BSS段之前,BSS段会自动初始化为0。所以,未初始的全局变量和静态变量在程序执行之前已经是0了。BSS段属于静态内存分配。
(1) 从静态存储区分配内存。如全局变量和静态变量,内存在程序编译的时候就分配好,且这些内存在程序运行期间都存在。
(2) 从栈区分配内存。在执行函数时,函数内部局部变量的存储单元都在栈上创建,函数结束时这些内存会被自动释放。栈内存分配运算内置于处理器的指令集。
(3) 从堆区分配内存,也叫动态分配内存。程序运行时用malloc函数申请任意大小的内存,在不用时由程序员free释放内存。
1.概念
数组:存储连续多个相同类型的数据;
指针:变量,存的是地址
2.赋值
同类型的指针变量可以相互赋值,数组不行,只能一个一个元素的赋值或拷贝
3.存储方式
数组:连续内存空间。
指针:灵活,可以指向任意类型的数据。指向的是地址空间的内存。
4.所占内存的大小(用sizeof)
用运算符sizeof可以计算出数组的容量(字节数)。但sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。在32位平台下,无论指针的类型是什么,sizeof(指针名)都是4,在64位平台下,无论指针的类型是什么,sizeof(指针名)都是8。c++/c语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
5.传参
作为参数时,数组名退化为常量指针。当数组作为函数进行传递时,该数组自动退化为同类型的指针。
static主要用于定义全局静态变量、定义局部静态变量、定义静态函数。
(1)修饰局部变量
static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。
(2)修饰全局变量
全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被该包含该定义的文件访问(即改变了作用域)。
即,全局的静态变量的作用范围和生命周期都是从文件的定义开始到整个文件结束;而局部的静态变量生命周期是从文件的定义开始到整个文件结束,作用范围是从该语句块的定义开始到该语句块结束。
(3)修饰函数
static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,声明和定义需要放在同一个文件夹中。
https://blog.csdn.net/zzyzgg/article/details/89842744 //可参考
本质区别:指针是地址,是一个实体,需要分配内存空间;
引用是变量的别名,不需要分配内存空间。
(1) 指针在定义的时候不一定要初始化,并且指向的空间可变;
引用在定义的时候必须进行初始化,并且不能够改变。
(2) 指针和引用的自增运算结果不一样。
指针是指向下一个内存空间,而引用是引用的变量值加1。
(3) 引用求sizeof得到的是所指向的变量(对象)的大小,
而指针求sizeof得到的是指针本身的大小。
(4) 引用访问一个变量是直接访问,
而指针访问一个变量是间接访问。
//可参考
https://blog.csdn.net/u012611644/article/details/89055038
https://blog.csdn.net/zhengqijun_/article/details/54980769?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
C语言的标准内存分配函数:malloc,calloc,realloc,free等。
它们都是动态分配内存,先看看它们的原型:
void *malloc( size_t size ); //分配的大小
void *calloc( size_t numElements, size_t sizeOfElement ); // 分配元素的个数和每个元素的大小
共同点就是:
它们返回的是 void * 类型,也就是说如果我们要为int或者其他类型的数据分配空间必须显式强制转换;
不同点是:
用malloc分配存储空间时,必须由我们计算需要的字节数。如果想要分配5个int型的空间,
那就是说需要 5*sizeof(int)的内存空间:
int * ip_a;
ip_a = (int*)malloc( sizeof (int) * 5 );
而用calloc就不需要这么计算了,直接:
ip_a = ( int* )calloc( 5, sizeof(int) );
这样,就分配了相应的空间,而他们之间最大的区别就是:
用malloc只分配空间不初始化,也就是依然保留着这段内存里的数据, 而calloc则进行了初始化,calloc分配的空间全部初始化为0,这样就避免了可能的一些数据错误。
malloc与calloc的区别为1块与n块的区别:
malloc调用形式为 (类型)malloc(size):在内存的动态存储区中分配一块长度为“size”字节的连续区域,返回该区域的首地址。
calloc调用形式为 (类型)calloc(n,size): 在内存的动态存储区中分配n块长度为“size”字节的连续区域,返回首地址。
realloc调用形式为(类型)realloc(ptr,size):将ptr内存大小增大到size。
free的调用形式为free(void*ptr):释放ptr所指向的一块内存空间。
C++中为new/delete函数。