建设中网站,建企业网站公司,wordpress 本地环境,wordpress 未找到1、数据类型
1.1、基本数据类型 数据类型分2类#xff1a;基本数据类型复合类型 基本类型#xff1a;char short int long float double 复合类型#xff1a;数组 结构体 共用体 类#xff08;C语言没有类#xff0c;C有#xff09;
1.1.1、内存占用与sizeof运算符 数据…1、数据类型
1.1、基本数据类型 数据类型分2类基本数据类型复合类型 基本类型char short int long float double 复合类型数组 结构体 共用体 类C语言没有类C有
1.1.1、内存占用与sizeof运算符 数据类型就好像一个一个的模子这个模子实例化出C语言的变量。变量存储在内存中需要占用一定的内存空间。一个变量占用多少空间是由变量的数据类型决定的。 每种数据类型在不同的机器平台上占用内存是不同的。我们一般讲的时候都是以32位CPU为默认硬件平台来描述
char 1字节 8位
short 2字节 16位
int 4字节 32位
long 4字节 32位
float 4字节
double 8字节
1.1.2、有符号数和无符号数 对于char short int long等整形类型的数都分有符号有无符号数。 而对于float和double这种浮点型数来说只有有符号数没有无符号数。 对于C语言来说数也就是变量是存储在内存中一个一个的格子中的。存储的时候是以二进制方式存储的。对于有符号数和无符号数来说存储方式是不同的。 unsigned int 无符号数32位(4字节)全部用来存数的内容 所以表示的数的范围是0 ~ 4294967295(2^32 - 1)。 signed int 有符号数32位中最高位用来存符号0表示正数1表示负数剩余的31位用来存数据。所以可以表示的数的范围是 -2147483648(2^32) ~ 2147483647(2^31 - 1)。 结论从绝对数值来说无符号数所表示的范围要大一些。因为有符号数使用1个二进制位来表示正负号。
1.1.3、整形数和浮点型数存储方式上的不同 对于float和double这种浮点类型的数它在内存中的存储方式和整形数不一样。所以float和int相比虽然都是4字节但是在内存中存储的方式完全不同。所以同一个4字节的内存如果存储时是按照int存放的取的时候一定要按照int型方式去取。如果存的时候和取的时候理解的方式不同那数据就完全错了。 备注详细的数制存储可以查找资料计算机原码、反码、补码等知识。 总结存取方式上主要有两种一种是整形一种是浮点型这两种存取方式完全不同没有任何关联所以是绝对不能随意改变一个变量的存取方式。
1.2、空类型关键字void C语言中的void类型代表任意类型而不是空的意思。任意类型的意思不是说想变成谁就变成谁而是说它的类型是未知的是还没指定的。 void * 是void类型的指针。void类型的指针的含义是这是一个指针变量该指针指向一个void类型的数。void类型的数就是说这个数有可能是int也有可能是float也有可能是个结构体哪种类型都有可能只是我当前不知道。 void型指针的作用就是程序不知道那个变量的类型但是程序员自己心里知道。程序员如何知道当时给这个变量赋值的时候是什么类型现在取的时候就还是什么类型。这些类型对不对能否兼容完全由程序员自己负责。编译器看到void就没办法帮你做类型检查了。 在函数的参数列表和返回值中void代表的含义是一个函数形参列表为void表示这个函数调用时不需要给它传参。返回值类型是void表示这个函数不会返回一个有意义的返回值。所以调用者也不要想着去使用该返回值。
1.3、数据类型转换 C语言中有各种数据类型写程序时需要定义各种类型的变量。这些变量需要参与运算。C语言有一个基本要求就是不同类型的变量是不能直接运算的。也就是说int和float类型的变量不能直接加减等运算。你要运算必须先把两种类型转成相同的类型才可以。
1.3.1、隐式转换 隐式转换就是自动转换是C语言默认会进行的不用程序员干涉。当编译器发现ab中a和b的类型不同时。这时候两个要加编译器会进行隐式类型转换把两个转成类型相同。根据隐式类型转换的规则编译器构造了一个临时变量例如叫 float f1然后把f1赋值为a转成float类型的值之后参与运算时是用f1去和b相加的加完之后得到一个临时变量例如叫float f2.这个临时变量再参与之后的运算。 C语言的理念隐式类型转换默认朝精度更高、范围更大的方向转换。赋值时必须以 左边的类型为准。
1.3.2、强制类型转换 C语言默认不会这么做但是程序员我想这么做所以我强制这么做了。
1.4、C语言与bool类型 C语言中原生类型没有boolC中有。在C语言中如果需要使用bool类型可以用int来代替。很多代码体系中用以下宏定义来定义真和假
#define TRUE 1
#define FALSE 0
2、变量和常量
2.1、变量 变量指的是在程序运行过程中可以通过代码使它的值改变的量。
int g_a; // g_a定义在函数外面因此是全局变量int main(void)
{int a; // a定义在main函数中所以是局部变量return 0;
}
2.1.1、局部变量 定义在函数中的变量就叫局部变量。
2.1.1.1、普通局部变量(auto) 普通的局部变量定义时直接定义或者在定义前加auto关键字。
#include stdio.hvoid func1(void); //声明函数int main(void)
{func1(); // i 2func1(); // i 2func1(); // i 2return 0;
}void func1(void)
{int i 1; // 普通的局部变量auto可以省略的//auto int i 0; // 自动局部变量其实就是普通局部变量i;printf(i %d.\n, i);
}
局部变量i的解析 在连续三次调用func1中每次调用时在进入函数func1后都会创造一个新的变量i并且给它赋初值1然后i时加到2然后printf输出时输出2.然后func1本次调用结束结束时同时杀死本次创造的这个i。这就是局部变量i的整个生命周期。下次再调用该函数func1时又会重新创造一个i经历整个程序运算最终在函数运行完退出时再次被杀死。
2.1.1.2、静态局部变量(static) 静态局部变量定义时前面加static关键字。
#include stdio.hvoid func_static(void); //声明函数int main(void)
{func_static(); // i 2func_static(); // i 3func_static(); // i 4return 0;
}void func_static(void)
{static int i 1; // 静态的局部变量i;printf(i %d.\n, i);
}2.1.1.3、静态局部变量和普通局部变量对比 1、静态局部变量和普通局部变量不同。静态局部变量也是定义在函数内部的静态局部变量定义时前面要加static关键字来标识静态局部变量所在的函数在多调用多次时只有第一次才经历变量定义和初始化以后多次在调用时不再定义和初始化而是维持之前上一次调用时执行后这个变量的值。本次接着来使用。 2、静态局部变量在第一次函数被调用时创造并初始化但在函数退出时它不死亡而是保持其值等待函数下一次被调用。下次调用时不再重新创造和初始化该变量而是直接用上一次留下的值为基础来进行操作。 3、静态局部变量的这种特性和全局变量非常类似。它们的相同点是都创造和初始化一次以后调用时值保持上次的不变。不同点在于作用域不同。
2.1.1.4、register关键字 register(寄存器),C语言的一个关键字
register int i 3;
总结 register类型的局部变量表现上和auto是一样的这东西基本没用知道就可以了。register被称为C语言中最快的变量。C语言的运行时环境承诺会尽量将register类型的变量放到寄存器中去运行普通的变量是在内存中所以register类型的变量访问速度会快很多。但是它是有限制的首先寄存器数目是有限的所以register类型的变量不能太多其次register类型变量在数据类型上有限制例如你就不能定义double类型的register变量。一般只在内核或者启动代码中需要反复使用同一个变量这种情况下才会使用register类型变量。
2.1.2、全局变量 定义在函数外面的变量就叫全局变量。 main函数是一个程序运行最开始执行的东西所有的其他函数都只能在main函数中被直接或者间接的调用才能被执行。main函数的执行其实就是整个程序的生命周期main函数一return返回整个程序就结束了。 全局变量的定义和初始化就是在main函数运行之前发生的。
2.1.2.1、普通全局变量 普通全局变量就是平时使用的定义前不加任何修饰词。普通全局变量可以在各个文件中使 用可以在项目内别的.c文件中被看到所以要确保不能重名。
2.1.2.2、静态全局变量 静态全局变量就是用来解决重名问题的。静态全局变量定义时在定义前加static关键字告诉编译器这个变量只在当前本文件内使用在别的文件中绝对不会使用。这样就不用担心重名问题。所以静态的全局变量就用在我定义这个全局变量并不是为了给别的文件使用本来就是给我这个文件自己使用的。
2.1.2.3、跨文件引用全局变量(extern) 就是说你在一个程序的多个.c源文件中可以在一个.c文件中定义全局变量g_a,并且可以在别的另一个.c文件中引用该变量g_a引用前要声明。 函数和全局变量在C语言中可以跨文件引用也就是说他们的连接范围是全局的具有文件连接属性总之意思就是全局变量和函数是可以跨文件看到的直接影响就是我在a.c和b.c中各自定义了一个函数func名字相同但是内容不同编译报错。。
2.1.2.4、全局变量的特点 在整个文件中所有的函数内都可以访问该全局变量而且访问的都是该全局变量本身。如果你在之前某个函数中更改了它的值则后面再引用时它的值就是前面那次更改之后的值。
2.1.3、局部变量和全局变量的对比 1、定义同时没有初始化则局部变量的值是随机的而全局变量的值是默认为0。 2、使用范围上全局变量具有文件作用域而局部变量只有代码块作用域。 3、生命周期上全局变量是在程序开始运行之前的初始化阶段就诞生到整个程序结束退出的时候才死亡而局部变量在进入局部变量所在的代码块时诞生在该代码块退出的时候死亡。 4、变量分配位置全局变量分配在数据段上而局部变量分配在栈上。
注意 判断一个变量能不能使用有没有定义必须注意两点第一该变量定义的作用域是否在当前有效是否包含当前位置第二变量必须先定义后使用。所以变量引用一定要在变量定义之前。
基本概念 作用域起作用的区域也就是可以工作的范围。 代码块所谓代码块就是用{}括起来的一段代码。 数据段数据段存的是数像全局变量就是存在数据段的 代码段存的是程序代码一般是只读的。 栈(stack)先进后出。C语言中局部变量就分配在栈中。栈是C语言对内存的管理方式。
2.2、常量 常量程序运行过程中不会被改变的量。常量的值在程序运行之前初始化的时候给定一次以后都不会变了以后一直是这个值。
2.2.1、#define定义的常量
#define N 20 // 符号常量
int a[N];
2.2.2、const关键字
const int i 14
//const和指针结合共有4种形式
const int *p; //p是一个指针指针指向一个int型数据。p所指向的是个常量。
int const *p; //p是一个指针指针指向一个int型数据。p所指向的是个常量。
int *const p; //p是一个指针指针指向一个int型数据。p本身是常量p所指向的是个变量
const int *const p; //p是一个指针指针指向一个int型数据。p本身是常量指向的也是常量结论和记忆方法 1、const在*前面就表示const作用于p所指向的量。所以这时候p所指向的是个常量。 2、const在*后面表示p本身是常量但是p指向的不一定是常量。
const型指针有什么用
//字符串处理函数strcpy它的函数功能是把src指向的字符串拷贝到dst中。
char *strcpy(char *dst, const char *src);
2.2.3、枚举常量 枚举常量是宏定义的一种替代品在某些情况下会比宏定义好用。 关键字enum