C语言大法 第一式 数据
基本数据类型
- 整型
整形 | 类型 | 最小范围 |
---|---|---|
字符 | char | 0~127 |
无符号字符 | unsigned char | 0~255 |
有符号字符 | signed char | -127~127 |
短整型 | short或short int | -32768~32767(-2^15 ~ 2^15-1) |
无符号短整型 | unsigned short int | 0~65535(0 ~ 2^16-1) |
整型 | int | -2147483648~2147483647(-2^31 ~ 2^31-1) |
无符号整形 | unsigned int | 0~4294967295(0 ~ 2^32-1) |
长整型 | long或long int | -2147483648~2147483647(-2^31 ~ 2^31-1) |
无符号长整形 | unsigned long int | 0~4294967295(0 ~ 2^32-1) |
更长的整形 | long long或long long int |
长整型至少应该和整形一样长,而整形至少和短整型一样长,字符本质上是小整形值
- 浮点型
浮点型 | 类型 |
---|---|
单精度浮点型 | float |
双精度浮点型 | double |
扩展精度(某部分) | long double |
ANSI标准仅仅规定long double至少和double一样长,而double至少和float一样长
最小范围:所有的浮点类型至少能够容纳10-37~1037之间的任何值
在vs2019中32位机器下类型所占字节数(sizeof用来计算内存中所占字节数)
- 指针
变量的值存储与计算机的内存中,每个变量都占据一个特定的位置。每个内存位置都由地址唯一确定并引用。指针只是地址的另外一个名字。
指针就如此,可以把计算机的内存想象成一条长街上的一间间房子,每间房子都用一个唯一的号码码进行标识,每个位置包含一个值,这和它的地址是独立且显著不同的,即使他们都是数字。
关于指针在后面章节会具体说明
- 聚合类型(比如数组和结构)
int arr[5] = {1,2,3,4,5};//声明一个整型数组
由上所写,这是一个整形数组,数组里面包含5个整形元素,数组的下标总是从0开始,最后一个元素的下标是元素数目的数目减1
访问数组的元素就用下标进行访问比如:arr[0] 这个数就是数组里面存放第一个数‘1’
链接
标识符的链接属性决定如何处理不同文件中出现的标识符
链接属性一共有三种—external(外部)、internal(内部)、none(无)
- external链接属性的标识符无论声明多少次,在多少源文件中都表示同一实体
- internal链接属性的标识符在同一源文件中的所有声明表示同一实体,在不同源文件表示不同实体
- none链接属性总被当作单独的个体,就是多个声明彼此都是独立的
变量
变量:可更改的数据
- 变量的存储类型是指存储变量的内存类型
- 存储变量的位置——普通内存、运行时堆栈、硬件寄存器
- 存储类型变量——自动变量(auto)、静态变量(static)、外部变量(extern)、寄存器变量(register)
位于一对花括号之间的所有语句称为一个代码块
1.*自动变量*:在代码块内部声明的变量,存储于堆栈中。
程序执行到该代码块时自动变量创建,离开该代码块自动变量销毁。
自动变量每次执行都会重新创建。
2.*静态变量*:在代码块之外创建的变量,存储在静态内存中。
在整个程序开始前创建,整个执行期间一直存在,一直到程序结束。
在代码块内部声明的变量加上关键词(static)可以使它的存储类型从自动转为静态。但它的作用域不变。
函数的形式参数不能声明为静态,因为实参总在堆栈中传递函数,用于支持递归。
3.*外部变量*:用于对全局变量的扩展。
在另外一个源文件声明的全局变量‘a’(整个工程存在)用extern声明就可以在此文件中使用比如——extern int a;
4*寄存器变量*:存储在机器的寄存器中的变量。
关键词(register)可用于声明变量存储于寄存器中,
但是编译器不一定会理睬register,可能有多个变量用register声明而编译器只选择前面几个其余就按普通自动变量处理。
典型情况下我们希望把使用频率最高的变量声明在寄存器内。
全局变量 ——{} 外部定义的
局部变量 —— {} 内部定义的
变量的生命周期:变量的创建和销毁之间的时间段
局部变量的生命周期:进入局部范围生命开始,出局部范围生命结束
全局变量的生命周期:程序的生命周期
局部变量的作用域:就是变量所在的局部范围
全局变量的作用域:整个工程
#include <stdio.h>
int num = 10;//全局变量
int main()
{
int num = 1;//局部变量
printf("num = %d\n",num);
return 0;
}
声明的变量是同名的时候局部变量优先全局变量使用
不建议把全局变量和局部变量的名字写成一样
常量
常量:不可更改的数据
-
字面常量
-
const 修饰的常变量
-
#define 定义的标识符常量
-
枚举常量
-
字符串常量
1.字面常量:字面形式上即可识别的常量叫做字面常量
直接的数字 1 2 3 4
2.常变量:用const关键字修饰比如:(const int a)
把a声明为整数,它的值不能被更改。
int *p;//1
int const *p;//2
int * const p;//3
int const * const p;//4
1.p是一个普通的指向整形的指针
2.这是一个指向整形常量的指针,你可以修改指针的值,但是你不能修改他所指向的的值
3.这是一个指向整形的常量指针,这个指针是常量不可更改,但是可以修改它所指向的值
4.这样无论是指针还是它所指向的值都是常量,不可更改
3.#define指令是另外一种创建名字常量的机制,它在预处理阶段替换它所表示的值
用名字常量来定义能够提高程序的可维护性,更改一个值只需要更改其声明。
#define MAX 10
int a = MAX;//a = 10
4.枚举常量——可以一一列举的常量
enum DAY
{
MON,
TUE,
WED
};
由上所述枚举是一般情况是连续的,从0开始,一开始赋初值进行更改后续结果,但是在出代码块后面不可更改。
5.字符串——一串以 NUL (\0)字节结尾的 0 个或多个字符组成的序列。
字符串通常存储字符串数组中,它是以NUL字节作为终止条件,所以字符串内部不能有NUL字节。
char arr1[] = "hello";
char arr2[] = {'h','e','l','l','o'};//直到在后面内存中找到NUL后停止,打印的是随机的值
char arr3[] = {'h','e','l','l','o','\0'};
字符串如果声明在数组内部则可以通过下标来更改它的值,如果单个单个字符的声明则需要在后面加上NUL(\0)
但是如果不声明在数组中时:直接以双引号括起来,它的值直接存储在首字母的地址处,且字符串存储在静态区。所以调用字符串常量一般是调用首字母的地址。
char *p = "hello";
char *pp = "hello";
可见同样的一个字符串常量它的存储地址是在同一个地方
不会因为指向它的指针变量不同而变化
作用域、链接属性和存储类型的总结
变量类型 | 声明的位置 | 是否存于堆栈 | 作用域 | 如果声明为static |
---|---|---|---|---|
全局 | 所有代码块之外 | 否 | 从声明处到文件尾 | 不允许从其他源文件访问 |
局部 | 代码块起始处 | 是 | 整个代码块 | 变量不存储于堆栈中,它的值在程序整个执行期一直保存 |
形式参数 | 函数头部 | 是 | 整个函数 | 不允许 |
表格摘自《c和指针》
这里只浅浅的提一下后面会具体深入的学习
如果博客里面有错误欢迎大家评论
从小白到武林之巅让我们一起学好c语言大法