变量和数据类型
C 语言共有 4 个关键字用来指明变量的存储类别: auto(自动的)、static(静态的)、register(寄存器的)、extern(外部的)。
- 基本数据类型 int/float/double/char
* int
* long int 、long: 8个字节 %ld(64位)
* short int 、 short: 2个字节 %d %i (64位)
* unsigned int 、unsigned: 4个字节 %zd
* signed int 、signed: 4个字节 %d %i
* float/double:float 4个字节 %f,double 8个字节 %f
* char: 1个字节 %c %d
* char类型,保存在内存中的是它的ASCII码值
* 'A' --> 65
* 'a' --> 972
3
4
5
6
7
8
9
10
- 构造类型
* 数组、数据类型、数组名[数组个数]
* 结构体
* 指针类型: int *p,间接操作变量的值
* 枚举类型: 变量的值只有几个固定的值2
3
4
类型修饰符
- short: 只能支持int, 减少int类型的字节数,从4个字节减到2个字节
- long: 只能支持int, 把int类型从4个字节扩充到8个字节,long num == long int num,打印需要用"%ld"
- signed: 有符号,正数 0 负数 signed int = signed
- unsigned: 无符号, 正数 0 没有负数,unsigned int = unsigned int的取值范围变成 0~2的32次方-1,因为最高比特位不需要当做符号位了
int 在32位编译器上只有2个字节,long long int 在64位编译器上还是8个字节,在32位编译器上代表也代表8个字节。 printf("long :%lu -- short :%lu",sizeof(long long int),sizeof(short int));
Char 字符类型
- 字符类型只有一个字节,一个字节是8个二进制位,减去最高位,对应的取值范围-128~127
- 字符类型在ASCII码上都有对应的字符,比如大写A对应的是65,小写a对应的是97
- 汉字占三个字节,汉字不能使用char类型存储
- 单引号 'a' 是字符,双引号 "a" 是字符串
输出大写A-Z和小写 a-z
字母在ASCII码中对应的只是一个数,把对应的数用字符的形式输出就可以得到对应的字母,小写比大写字母固定的大32
for (int i = 65; i < 91; i++)
{
printf("大写%c,小写%c\n",i,i+32);
}2
3
4
数组
数组元素存储
计算数组的个数,数组内存大小/类型内存大小,比如
int ary[] = {1,2,3}
int count - sizrof(ary) / sizeof(int)2
数组占多少内存
数组的多少字节的计算方式: 类型的内存大小 个数,比如int ary[4], int 是4个字节,4 * 4 = 16,ary占16个字节
数组的内存地址
数组的内存地址就是第一条数据的内存地址,数组内的元素内存地址按下标顺序进行排列
int ary[] = {1,2,3};
printf("ary --%p\n",&ary);
for (int i = 0; i < sizeof(ary)/sizeof(int); i++) {
printf("ary[%d] --%p\n",i,&ary[i]);
}
打印结果:
ary --0x7ffee7b23b80
ary[0] --0x7ffee7b23b80
ary[1] --0x7ffee7b23b84
ary[2] --0x7ffee7b23b882
3
4
5
6
7
8
9
10
11
数组传参
数组当做参数传到方法中时,传过去的实际是数组的指针,指针在64位编辑器中占8个字节,在32位占4个字节,
MAC系统查看自己的编译器是多少位的命令 uname -a , x86_64 表示系统为64位 i686 表示系统32位的
字符串
- 在C语言中字符串是以字符数组的形式存储的,如 char string[5] = "asds"
- 在C语言中字符串结尾都以\0为结束符,\0在ASCII码中是0 ,char string[3] = {'i','t','\0'} == char string[3] = "it"
\0的用途
\0是结束符,C语言中如果没有找到\0,会继续向下面的内存中寻找直到遇到\0结束,举例:
char name[4] = "12345"; char
name1[] = {'a','b'};
printf("%s",name1);
打印结果: ab123452
3
4
5
strlen
strlen函数是计算字符串长度,需要导入#include <string.h> strlen 函数计算的是字符数,汉字占三个字节,一个汉字等于三个字符 不计算尾部的\0
枚举
枚举只在确定只有固定几个值的时候使用 enum Sex {Man,Woman,Unkown}
typedef
定义类型,给已经存在的类型取一个新的名称
typedef int MyInt; //给int类型定义别名MyInt
typedef char * String; //也可以定义指针
struct Student{
int age;
};
typedef struct Student MyStu; // 定义结构体
enum Sex{Man,woMan}
typedef enum Sex MySex; // 定义枚举
typedef int (*Point)(int,int); // 定义函数指针2
3
4
5
6
7
8
9
10
11
12
13
static - 静态变量
- 静态局部变量:一般在函数内部或复合语句内部使用,特征是程序执行钱变量的存储空间被分配在静态区,并赋初值一次,若没有显示的赋初值,系统自动赋值为0,其值一直存在,知道程序结束
- 静态全局变量:只能被所定义的本文件中所有函数引用,不能被其他文件中的函数引用。(全局变量可以被整个程序的不同文件中的函数引用)
extern - 导出函数
全局变量作用域是从变量定义的位置开始到文件结束,可被文件内的所有函数所共用,如果想在 全局变量定义的位置之前或其他文件中 的函数所引用时,必须对变量使用 extern 声明。比如
创建两个源文件 main.c 和 module.c:
module.c是整个程序的一个模块,我们在其中定义了一个全局变量和一个函数;
#include <stdio.h>
int m = 100;
void func(){
printf("Multiple file programming!\n");
}2
3
4
5
main.c是程序的主模块(主文件),它使用到了 module.c 中的变量和函数。
#include <stdio.h>
extern void func();
extern int m;
int n = 200;
int main(){
func();
printf("m = %d, n = %d\n", m, n);
return 0;
}2
3
4
5
6
7
8
9
10
使用下面的命令来编译和运行程序:
gcc main.c module.c #编译
./a.out #运行2
m 和 n 是在所有函数之外定义的全局变量(Global Variable),它的作用域默认是整个程序,也就是所有的代码文件,包括.c 和.h 文件。
C 语言代码是由上到下依次执行的,不管是变量还是函数,原则上都要先定义再使用,否则就会报错。但在实际开发中,经常会在函数或变量定义之前就使用它们,这个时候就需要提前声明。
所谓声明(Declaration),就是告诉编译器我要使用这个变量或函数,你现在没有找到它的定义不要紧,请不要报错,稍后我会把定义补上。
extern的另一个技巧是获取其他文件定义的全局变量,比如在一个文件内使用static定义了一个全局变量,如果要在另一个文件内获取到,可以使用extern进行重新定义获取。