C语言-06-复杂数据类型

一、数组

1> 数组的定义和初始化

  1. 定义

    ① 数组定义了同种类型数据的集合
    ② 定义数组时,数组必须有固定的长度
    
  2. 初始化

    ① 如果在定义数组时,初始化数组,数组元素的个数必须是常量
    ② 如果不在定义数组时初始化,数组元素的个数可以是有确定值的变
      量
    ③ 大括号的初始化方式只能在定义时初始化的情况下使用
    

2> 数组的内存存储细节

  • 为数组分配内存时是从内存的高地址到低地址,而数组元素的存储是从低地址到高地址
  • 数组名为该数组元素在内存中的首地址,是一个指针常量,类型与数组类型一致
  • 可以用&符号来取得每个数据元素的首地址
  • 数组在内存中所占内存的大小可以用sizeof(数组名)/数组长度来计算

3> 使用注意

  • 数组元素的下标是从0开始的
  • 若要访问数组中的多个元素,一般用for循环
  • 可以通过sizeof来计算数组的长度
  • 可以通过下标直接访问数组,也可以通过指针间接访问数组元素

4> 数组名作为函数参数

  • 数组名作为函数参数是传址参数,传递的是数组的首地址
  • 不同通过sizeof来计算数组长度,此时通过sizeof(数组名),计算的是该编译器中指针的长度
  • 数组的长度必须通过参数传递

5> 示例

  • 步骤

    • 将整型数据10, 6, 23, 8, 15存放在一个数组中
    • 对数组中的元素进行从小到达排序
    • 输出排序后数组中的元素
  • 代码

    #include <stdio.h>
    //将数组按从小到大排序
    void sortTheArray(int array[], int count);
    //逐个输出数组中的元素
    void printTheArray(int array[], int count);
    
    int main()
    {
    	//定义一个数组并初始化
    	int array[]= {10, 6, 23, 8, 15};
    	//存储数组元素的个数
    	int count;
    
    	//计算数组的个数
    	count = sizeof(array) / sizeof(int);
    
    	//逐个输出排序前数组中的元素
    	printTheArray(array, count);
    
    	//将数组按从小到大排序
    	sortTheArray(array, count);
    
    	//逐个输出排序后数组中的元素
    	printTheArray(array, count);
    
    	return 0;
    }
    
    //将数组按从小到大排序
    void sortTheArray(int array[], int count)
    {
    	//用于循环遍历数组
    	int i,j,k;
    	//中间变量,用于交换数组的两个元素
    	int temp;
    
    	//选择排序
    	for (i = 0; i < count-1; i++)
    	{
        	k = i;
        	for (j = i + 1; j < count; j++)
        	{
            	if (array[j] < array[k])
            	{
                	temp = array[k];
                	array[k] = array[j];
                	array[j] = temp;
            	}
        	}
    	}
    }
    
    //逐个输出数组中的元素
    void printTheArray(int array[], int count)
    {
    	for (int i = 0; i < count; i++)
    	{
        	printf("%d\t", array[i]);
    	}
    	printf("\n");
    }
    

二、字符串

1> 基本使用

  • C语言中用字符数组来表示字符串
  • 字符串用%s格式输出
  • string.h文件中声明了字符串相关的操作函数

2> 字符串的结束标志'\0'

  • 字符串末尾会有'\0'结束标志,其ASCII码值为0
  • 字符串的操作函数是以'\0'为结束符,若没有结束符,这些操作函数可能会操作其他危险的数据
  • 将字符串常量赋值给char类型的指针变量,则该变量存储的是字符串常量的首地址

3> 字符串的输入

  1. scanf函数

    ① scanf函数默认以空格、'\n'和'\t'键作为字符串结束的标志
    ② 可以用格式%[^c]来控制以指定字符c作为字符串结束的标志
    
  2. gets函数

    ① 可以输入包含空格和'\t'的字符串,以'\n'作为字符串结束标志
    ② gets函数不会判断上限,仅遇到'\n'结束
    ③ 用于接收字符串的缓冲区必须足够大,否则会发生溢出,引发bug
    
  3. getchar函数

    ① 可以通过循环使用getchar函数来输入任意的字符,来组成字符串
    ② 要对末尾的'\n'进行处理,将其转化为'\0'
    

三、指针

1> 基本使用

  • 指针变量的内容为内存地址,内存地址是一个机器相关量
  • 指向指针的指针,其内容为所指向指针的地址
  • 通过符号*来访问指针变量所指向地址存储的内容,并可进行修改
  • 指针所指向的内存空间存储变量的类型,与定义指针的类型一致
  • 指针作为函数参数,是一个传址参数
  • 指针可以作为函数参数用于返回函数的执行结果
  • 可以使用指针数组来代替多维数组

2> 使用注意

  • 定义指针变量时的符号*只是一个符号,没有任何实际的意义
  • 定义指针变量时用常量将其初始化,此指针变量的内容将不能被修改
  • 不能间接访问没有初始化的指针变量
  • 若使用一阶指针,不要将地址存储到指针变量所指向的内容
  • 若指针指向的变量类型与定义的类型不一致,可能会影响间接访问的内容
  • sizeof函数的返回值为unsigned long类型,输出格式为%zd
  • 若返回值类型为指针类型,返回值是一个地址

3> 指向函数的指针

  • 定义格式 void (*p)(int ),这是定义一个无返回值,有一个整型参数的指向函数的指针变量

  • 通常用函数名为指向函数的指针变量赋值,函数名表示函数在内存中存储的首地址

  • 通过指针变量调用函数的两种方式

     ① p( );
     ② (*p)();
    

四、指针与数组

1> 基本使用

  1. 通常定义一个与数组同类型的指针变量来指向数组的首地址
  2. 通过指针的自增自减运算来间接访问数组元素
  3. 可以用指针变量加上下表来访问数组元素

2> 使用注意

  1. 指针运算是以定义指针类型在内存中所占存储空间的字节数为单位的
  2. 下标绝不会比指针更有效率,但指针有时可能比下标更有效率
  3. 数组名和指针不能等同

四、结构体

1> 基本使用

  • 结构体定义了多个不同类型数据的集合,是构造类型的一种
  • 结构体可以将某个对象的一组属性组合在一起
  • 结构体的成员可以是基本数据类型,也可以是其他构造类型,如结构体
  • 可以在定义结构体时用大括号为其初始化,用点语法可以实现机构提成员的乱序赋值
  • 结构体数组用于定义具有多个属性的多个同种类型的对象

2> 使用注意

  • 定义结构体不会分配内存空间,只有定义结构体变量时才会为变量分配内存空间
  • 结构体变量所占内存空间的大小为所有成员变量中占内存空间最大的变量所占内存空间的整数倍
  • 结构体变量之间可以赋值,实际上是全部成员变量之间的赋值
  • 结构体变量的名字是该结构体在内存中的首地址
  • 不能定义同名结构体
  • 尽量不要再代码块内定义结构体,避免造成作用域问题

3> 定义结构体变量的三种方式

  • 在定义结构体的同时定义结构体变量,重用性差
  • 先定义结构体,在用这种类型定义结构体变量
  • 用typedef为结构体定义一个新的类型名,用这个新类型名定义这种类型的结构体变量

4> 指向结构体的指针

  • 可以定义一个结构体类型的指针来指向该种类型的结构体变量

  • 通过指针间接访问结构体指针变量的两种方式

     ① (*p).name,(p为指向结构体变量的指针,name为结构体变量的成
     员变量的名字)
     ② p->name
    

五、枚举

1> 基本使用

  • 用于定义一个具有固定取值的变量
  • 枚举类型变量的定义与结构体类型变量的定义相似

2> 使用注意

  • 枚举类型的成员变量实际上存储的是整型常量,默认从0开始编号
  • 可以指定枚举类型的成员变量的编号规则

六、综合示例

  • 步骤

    • 定义一个Person结构体,属性包含:名字、性别
    • 名字用字符串表示
    • 性别用枚举表示
    • 定义一个函数输出结构体变量的信息
  • 代码

    #include <stdio.h>
    #include <string.h>
    //定义一个枚举类型,用于存储性别
    typedef enum
    {
    	sexMan, sexWoman, sexUnknown
    } Sex;
    
    //定义一个结构体类型,用于存储某个人的姓名和性别属性
    typedef struct
    {
    	char name[20]; //姓名
    	Sex sex; //性别
    } Person;
    
    //声明一个函数,用于打印某个人的信息
    void printThePerson(Person *p);
    
    int main()
    {
    	//定义一个结构体变量p
    	Person p;
    
    	//输入姓名,存放到结构体的name属性中
    	printf("请输入一个人的姓名\n");
    	//使用%[^\n]控制一'\n'字符作为字符串的结束字符
    	scanf("%[^\n]", p.name);
    
    	//输入性别,存放到结构体的sex属性中
    	printf("请输入一个人得性别(0:Man,1:Woman,2:Unknown)\n");
    	scanf("%d", &p.sex);
    
    	//打印结构体变量p的相关信息
    	printThePerson(&p);
    
    	return 0;
    }
    
    void printThePerson(Person *p)
    {
     	char *str = NULL;
    	//将枚举值sex转换成相应的字符串
    	switch (p->sex)
    	{
        	case 0:
            	str = "Man";
            	break;
        	case 1:
            	str = "Woman";
            	break;
        	case 2:
            	str = "Unknown";
            	break;
            
        	default:
            	break;
    	}
    	printf("这个人的姓名为:%s\t性别为:%s\n", p->name, str);   
    }
    
    
posted @ 2015-08-10 18:21  世俗孤岛  阅读(554)  评论(0编辑  收藏  举报