黑马程序员-C语言基础知识-数据

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

数据分类

计算机中存储的数据可以分为两类:静态数据和动态数据。
一、
静态数据
静态数据是指一些永久性的数据,一般存储在硬盘中。计算机关闭之后再开启,这些数据依旧存在,只要不主动删除或者硬盘损坏这些数据永远都在。

二、
动态数据(临时数据)
动态数据指在程序运行过程中,动态产生的临时数据,一般存储在内存中。计算机关闭之后这些临时数据就会被清除。

数据大小

一、
C语言源程序写成后被编译器翻译成计算机可以识别的机器码,机器码用0和1组成的二进制编码表示。机器码就是计算机内部存储的数据的表示形式,0和1是最小的数据存储单位,这个最小单位被称为bit位,通常计算机中8个bit位等于一个字节(byte),字节就是数据存储的基本单位。

二、
下面是数据存储单位的换算:
1KB = 1024B(byte), 1MB = 1024KB, 1GB = 1024MB, 1TB = 1024GB。

关键字和标示符

一、
C语言中有32个关键字,它们是:
auto double int struct
break else long switch
case enum register typedef
char extern union return
const float short unsigned
continue for signed void
default goto sizeof volatile
do while static if

二、
C语言中为了在程序运行过程中可以使用变量、常量、函数、数组等,就要为这些形式设定一个名称,而设定的名称就是所谓的标识符。标识符由26个英文字母、数字、下划线组成,它有以下几点命名规则:
1. 必须以字母或者下划线开头,不能以数字开头;
2. 英文字母的大小写代表不同的标识符;
3. 标识符不能是关键字;
4. 标识符的命名最好有相关含义。

常量和变量

一、
常量就是在程序运行过程中其值是不可改变的,C语言中用关键词const修饰的数据表示常量,比如:const int a,此处的a就被定义为常量。常量分多种类型,如整型常量、浮点型常量、字符常量、字符串常量等。

二、
变量就是程序运行过程中值可以变化的量,变量也分为整型变量、浮点型变量、字符型变量等等。
1. 根据变量作用域的不同可以分为全局变量和局部变量。
1> 在所有函数外部定义的变量称为全局变量。全局变量的作用域是从定义变量的位置开始到程序结束。
2> 在函数内部定义的变量称为局部变量。局部变量只在定义它的函数内部或者代码块内部有效。
示例1:

int x;
int main()
{
    int y;
    return 0; 
}

示例1中的x即为全局变量,y即为局部变量。
2. 变量有不同的存储类型,根据存储类型的不同可以分为自动(auto)变量、static变量、全局(extern)变量、寄存器(register)变量。
1> auto关键字修饰的局部变量(不能用来修饰全局变量)就是自动的,默认情况下所有的局部变量都是自动的。这意味着每次执行到定义该变量时,都会产生一个新的变量,并且重新对其进行初始化。
示例2:

int main()
{
    int a;
    auto int b;
}

示例2中a和b都是自动局部变量。
2> 所有的全局变量都是静态的,默认情况下全局变量就是static的,又被称为内部变量,在由多个源文件组成的源程序中它只能在它被定义的那个源文件中使用。
static修饰局部变量,意味着该局部变量是静态的,也就是说从它被定义开始一直到程序结束,都有效,在内存中占有固定的存储空间一直到程序结束才被销毁。
定义静态局部变量的函数如果被重复调用,该函数的静态局部变量是不会重复分配存储空间的,它的值也不会重归为刚刚定义时的状态,其值的变化是延续性的。
示例3:

int a;
static int b;
void fun()
{
     static int c;
}

示例3中的a、b都是静态的全局变量,c是静态局部变量。
3> extern修饰的全局变量称为外部变量。再由多个c文件组成的工程项目中,如果一个全局变量被定义为外部变量那么它可以在所有的文件中使用。
示例4:

extern int a;
int main()
{
    int a++;
    return 0;
}

示例4中的变量a即为外部变量。
4> register修饰的变量被称为寄存器变量。寄存器变量比放在内存中的变量访问效率高。它只能修饰自动局部变量,全局变量和静态局部变量不行,而且只限于整型、字符型、指针型变量使用。
因为寄存器变量本身就是自动变量,所以函数中的寄存器变量在调用该函数时占用寄存器中存放的值,当函数结束时释放寄存器,变量消失。
由于计算机中寄存器数目有限,不能使用太多的寄存器变量。寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理。
为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存。
示例5:

int main()
{
    register int a;
    return 0;
}

示例5中的a便是寄存器变量。

数据类型

这里写图片描述
一、
基本数据类型:
1. 整型:它又可以分为6种类型,下面一一列举([ ]中的关键字可以省略)。
1> 有符号基本整型([signed] int),该型数据在内存中占4个字节,取值范围是-2147483648~2147483647。
2> 无符号基本整型(unsigned [int]),在内存中占4个字节,取值范围是0~4294967295。
3> 有符号短整型([signed] short [int]),在内存中占2个字节,取值范围是-32768~32767。
4> 无符号短整型(unsigned short [int]),在内存中占2个字节,取值范围是0~65535。
5> 有符号长整型([signed] long [int]),在内存中占4个字节,取值范围是-2147483648~2147483647。
6> 无符号长整型(unsigned long [int]),在内存中占4个字节,取值范围是0~4294967295。
2. 浮点型:分为三种类型。
1> 单精度类型(float),在内存中占4个字节,取值范围是-3.4e-38~3.4e38。
2> 双精度类型(double),在内存中占8个字节,取值范围是-1.7e-308~1.7e308。
3> 长双精度类型(long double),在内存中占8个字节,取值范围是-1.7e-308~1.7e308。
3. 字符型:用关键词char来定义,在内存中占1个字节,取值范围是-128~127。
字符数据在内存中存储的是字符的ASCII码,即一个无符号整数,它与整数的存储形式一样,因此c语言中允许字符型数据与整型数据之间通用。下面附上ASCII码表(常用部分):
这里写图片描述
4. 指针型:指针存储的是其它变量的地址,我们称该指针指向这个变量的地址,根据指针指向的这个地址就可以访问这块内存地址中存储的变量。
1> 指针的定义及使用:(&是取地址符,专门用来获取变量存储的地址值)
示例6:

int main()
{
    int a = 10;
    int b = 5;
    int *p = &a;//定义并初始化一个指针变量,指针变量指向的地址存储的变量是什么类型它就用相应的关键字修饰
    int c = *p;//等价于int c = a;*p用来取出它所指向的内存地址存放的变量的值;
    p = &b;//将b的地址赋给指针p,此时*p = b;
}

2> 指针什么类型的变量都可以指,包括指针变量,我们称这样的指针为指向指针的指针。
指向指针的指针:
示例7:

int main()
{
    int a = 1;
    int *p = &a;
    int **q = &p;
    /* 这样定义之后指针p指向a的地址,q指向p的地址;这样做会产生如下效果:q == &p,*q == p == &a,**q == *p == a */ 
}

3> 指针也可以指向函数在内存中的存储地址,通过指针亦可调用函数。
示例8:

int fun(int x, int y)
{
    return x + y;
}
int main()
{
    int (*myfun)(int, int);//定义指向函数的指针,它指向的函数返回值是int型,有两个int型的形参
    myfun = fun;//指针myfun指向函数fun在内存中的存储地址
    int a = 0, b = 1;
    myfun(a, b);//可以这样利用指针myfun调用函数fun
    (*myfun)(a, b);//也可以这样利用指针myfun调用函数fun
    return 0; 
}

二、
构造类型:
1. 数组:存储数据的集合就是数组。数组中的单个数据被称为数组元素,数组只能存储相同类型的数据。数组分为一维数组、二维数组、多维数组和字符串数组,下面一一介绍。
1> 一维数组:存储一维数列数据的集合就是一维数组。
示例9:

int main()
{
    int x;
    int array1[x] = {0,1};//错误写法,数组的下标在定义时只能是常量或者常量表达式 
    int array1[2] = {0,1};//正确写法
    int array2[2];
    array2 = {23};//错误写法,数组只能在定义的同时这样初始化
    array2[0] = 2 ,array2[1] = 3;//正确写法
    int array3[2] = {4, 5, 6};//错误写法,数组初始化时越界,即元素个数超出了数组定义的范围
    int array3[] = {4, 5, 6};//正确写法,数组在定义时可以不写下标,根据数组元素个数动态分配存储空间
    return 0;
}

示例9介绍了一维数组定义及初始化的正确写法。
2> 二维数组:存储二维数列数据的集合就是二维数组。
示例10:

int main()
{
    int array1[3][4] = {{0, 1, 2, 3},{4, 5, 6, 7},{8, 9, 10, 11}};//这行代码定义并初始化了一个3行4列的二维数组
    int array2[2][2];
    array2[0] = {{0, 1}};//错误写法
    array2[1][0] = 2, array2[1][1] = 3;//正确写法
    int array3[2][];//错误写法,列数不明确
    //下面是正确写法,定义二维数组时行数可以不明确列数必须明确,这样计算机就可以根据每行的个数(即列数)动态分配存储空间产生行数从而生成二维数组
    int array4[][2] = {0, 1, 2, 3, 4, 5}; 
}

示例10介绍了二维数组的正确定义及初始化的方法。
3> 多维数组:存储多维数列数据的集合就是多维数组。多维数组的声明和二维数组相同只是下标更多。
4> 字符串数组:存储一组字符数据的数组就叫字符串数组,可以直接称为字符串。字符数组定义时最后一个字符通常是结束符’\0’,如果不写数组就会没有明确的边界,会越界。我们在取一个数组的值时,从第一个字符开始一直到结束符结束,如果不加结束符某些情况下会多取出别的字符数组的字符。
示例11:

int main()
{
    char string1[3] = {'a', 'b', '\0'};//正确写法
    char string2[3] = {'c', 'd', 'e'};//编译器不会报错,程序员所添加的字符已经被数组完全容纳,没有地方添加结束符,它会在内存中与string1连在一起
    char string3[] = {'a', 'b', 'c'};//正确写法,编译器会在程序员输入的最后一个字符后面自动添加一个结束'\0'
    char string4[] = "abc";//正确写法,这样生成的字符串编译器也会在最后自动添加一个结束符'\0',在存储的字符长度不明确的情况下这样定义比较好
    char *string5 = "abc";//用指针定义字符串
    char *string5 = string2;//将string2赋值给字符串string5,因为string2最后没加'\0',系统会多赋字符给string5,本例中string5 == "cdeab";
}

示例11介绍了字符串的正确定义及存储方式。
2. 结构体:结构体由若干“成员”组成,“成员”可以是不同的数据类型。结构体所占内存空间等于结构体中占用内存字节最大的”成员”乘以其”成员”个数。
结构体的定义方式:

struct 结构体名
{
       成员列表
}变量名;

示例12:

struct Birtyday{
       int year;
       int month;
       int day; 
};
int main()
{
    struct Person{
           char name[5];//这里要注意,在结构体内定义字符数组下标数值必须明确
           char *sex;
           int  age;
           struct Birtyday birtyday;
    };
    struct Person person = {"liyi", "man", 36, {1979620}};
    return 0;
}

从示例12的展示来看,结构体既可以定义为全局变量也可以定义为局部变量,既可以是相同的数据类型也可以是不同的数据类型,而且结构体可以嵌套定义。使用结构体可以用不同的数据类型组合出一个有新的含义的数据类型。
3. 共用体:它使几种不同类型的变量存放到同一段内存中,在同一时刻共用体只能有一个值,它属于某一个数据成员。共用体的大小等于最大成员的的大小。
定义共用体的一般形式为:

union 共用体名
{
      成员列表;
}变量名;

示例13:

union Button{
      char *on;
      char *off;
}button;

int main()
{
    button.on = "on";//此刻打开“开关”
    button.off = "off";//此刻关闭“开关”
    return 0;    
}

示例13展示了共用体的定义及使用。
4. 枚举类型:枚举类型包含一组相关的标识符,每一个标识符都代表一个整数值,称为枚举常量。枚举变量的取值范围只能是定义时的那几个枚举常量。
示例14:

1> 第一种定义方式
enum Colors{
     Red,//这里注意不同于结构体和共用体与数组相同,其不同“成员”之间用逗号(,)而非分号(;)隔开
     Green,
     Blue
};
在使用时Red等于0,Green等于1Blue等于22> 第二种定义方式
enum Colors{
     Red = 1,
     Green,
     Blue
};
这样定义,Green等于2Blue等于33> 第三种定义方式
enum Colors{
     Red = 1,
     Green = 3,
     Blue = 2
};
这样的话各个成员所代表的数值完全自定义。
4> 枚举类型的使用
enum Colors{
     Red,
     Green,
     Blue
}colors;
int main()
{
    colors = Blue;//这个时候colors变量被赋值为Blue,那么此时colors的数值为1
    colors = 0;//给colors赋值为0,那么此时变量colors的含义就是红色(Red)
}

示例14展示了枚举变量的定义方式及使用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值