文章目录
一、两个常见的关键词的大概了解
1、typedef
typedef的作用是类型的重命名,对一个类型起一个别名
张三->小三
unsigned int ->uint
例:
#include<stdio.h>
typedef unsigned int uint_32;
int main() {
unsigned int num1 = 1;
uint_32 num2 = 2;
printf("%d %d",num1,num2);
return 0;
}
2、static
static用来修饰变量和函数,具体有三个作用:
1:修饰局部变量,称为静态局部变量,
2:修饰全局变量,称为静态全局变量,
3:修饰函数,称为静态函数。
细节详解:
1:修饰局部变量,称为静态局部变量
static在修饰局部变量的时候,其实是相当于修改了局部变量的生命周期,实质上是改变了局部变量的存储位置。
局部变量在创建的时候,要向内存中申请空间,在没有static修饰时,,空间在内存中的存储位置是在栈区,一旦有了static修饰,局部变量的存储位置就由栈区到了静态区。此时局部变量变成了静态局部变量,使得生命周期延长了,即使出了局部变量的作用范围,局部变量仍然不会销毁,空间也不会销毁,直到程序结束,局部变量才会销毁。
例:
此时,a变量未被static修饰,当进入到test函数内部,进入时,变量a被创建,出去时,变量a被销毁,所有在控制台输出了10个2
此时,加上了static修饰,在进入test函数时,变量a不会重复创建,在程序再次执行到这行代码时,会自动跳过,在每次出test函数时,变量a便不会被销毁,直到程序执行结束,变量a才会被销毁。
所有在控制台才会输出2-10这几个数字,a变量里面的值不会再被销毁,会一直保存。
2:修饰全局变量,称为静态全局变量
static修饰全局变量,修改了全局变量的外部链接属性,从原先的外部链接属性变为了内部链接属性,使得全局变量的作用范围变小了,也就使得其他的源文件无法在使用这个全局变量。
全局变量在大括号以外创建,作用范围是整个工程。
例:
创建两个源文件,全局变量a,在add.c中,在test.c中使用全局变量a,在使用之前,需要在test.c中进行声明,因为全局变量a是外部文件里面的,属于外部符号,要想在别的源文件使用,需要让其他的源文件认识,就要使用extern关键字进行声明。
此时,成功在控制台打印了1,是因为全局变量具有外部链接属性,“身在曹营心在汉”。
此时,添加了static修饰,外部链接属性变为内部链接属性,无法在另一个源文件中使用全局变量a,在编译执行时,编译器会报错!
3:修饰函数,称为静态函数。
函数其实和全局变量一样,也是具有外部链接属性
当被static修饰时,外部链接属性变为了内部链接属性。
未被static修饰:
被static修饰:
二、指针
1、32位的计算机如何管理4GB的内存空间?
32位的机器在管理内存时,为每个内存单元赋予地址。
32位机器有32根地址线,相当于32根电线,为了产生地址,就要充电,产生电信号。
每一根数据线都会产生0/1的电信号,32根地址线同时产生电信号,那么所组成的电信号序列的组合就有2的32次方个,也就是产生了2的32次方个二进制序列,每一个二进制序列会对应一个十进制数,这个十进制数,可以看作每一个内存单元的编号。
也就是有2的32次方个地址,每个地址管理一个内存单元,一个内存单元的空间是一个字节,也就是说,2的32次方个地址管理2的32次方个字节,2的32次方的字节=4GB
就是说,32位的机器,管理4GB的内存空间。
细节解释:
1:为什么内存会分为一个一个的内存单元?
首先,内存是存储器,程序的运行是在内存中运行的,为了方便管理,有效使用内存,便把内存分为一个一个的内存单元。
????????????????????????????????
2:为什么要给内存单元进行编号?
是为了能够有效的访问到每一个内存单元,便给内存单元进行了编号,这些编号也就是内存单元的地址。
可以类比于,两个人玩游戏,A和B,A躲进了一栋楼的某一个房间,B如何才能找到A?B可以一个一个房间的进行寻找,然而效率太低了,是无效的,此时给每一个房间进行编号,A告诉B,他所在的房间的门牌号是多少,那么B就可以直接找到A,效率得到了提升。
2、变量是如何在内存中申请空间,并存储数据的?
#include<stdio.h>
int main(){
int a = 10;
return 0;
}
第一步:向内存中申请空间
使用int类型,创建变量a,向内存中申请了四个字节的空间,那么此时a占用了四个内存单元。
第二步:存储数据10
由于变量a申请了四个字节的空间,就要使10占满四个字节???????????????????
表现成二进制数:0000 0000 0000 0000 0000 0000 0000 1010 =10
此时正好占满四个字节,四个字节=32个比特位,一个比特位放一个二进制数,所有一共存放32个二进制数。
因为二进制数太多了,不好表示,所以改用十六进制进行表示,四位二进制数表示一位十六进制数,大大缩减了个数,方便了表示。
3、如何取出变量的地址?
变量a,占用四个字节的空间,所以有了四个地址,由于内存单元有地址,所以变量也是有地址的,但是在取地址的时候,为了方便,只取第一个字节的地址,作为a的地址。
#include<stdio.h>
int main(){
int a = 10;
int* p = &a;
return 0;
}
p是指针变量,里面存放a的地址
*表示p是指针变量,里面只能存放地址
int在此时表示,p作为指针,根据它存放的地址,指向的对象的数据类型是 int 类型的
为什么说p是指针变量?
在内存中,每一个内存单元有一个编号,编号就是地址,地址就是指针,变量p存放地址,也就是存放指针,所以p叫做指针变量
4、指针变量的大小是多大?
无论是int还是short等等,
在x64,64位的机器上,各种指针变量的大小均为8,在内存里面占八个字节的大小。
在x86,32位的机器上,各种指针变量的大小均为4,在内存里面占四个字节的大小。
**解释:**指针变量里面是存放指针的,也就是存放地址的,要看变量的大小,具体要看地址的大小,地址是由一串二进制序列组成的,32位机器可以产生一组由32个二进制数组成的序列,也就是说一个地址占32个比特位,也就是占四个字节,同理可知,64位机器可以产生一组由64个二进制数组成的序列,也就是说一个地址占64个比特位,也就是占8个字节。
三、结构体
结构体就是把单一的数据类型组合在一起。
比如:char,int ,short,double ,fioat,这些数据类型只能单一的表示一种数据。
如果要表示一个人,这些单一的数据类型是无法表示的,人=姓名+性别+身份证号+手机号+住址。。。。等等
复杂的对象就要用复杂的类型的表示
c语言设置了自定义数据类型:struct
1、结构体如何表示?
struct xxp 是我们自己设定的数据类型
z是根据数据类型,创建的变量
2、结构体如何使用?
有两种方法可以使用对象 z 的成员
第一种:结构体对象名.成员名
第二种:结构体指针变量.成员名