C语言--复杂数据类型

文章目录

  • 一、数组
    • [   1、数组的定义](#   1、数组的定义)
    • [   2、数组的初始化](#   2、数组的初始化)
    • [   3、数组的赋值](#   3、数组的赋值)
      • [      1)、直接赋值:](#      1)、直接赋值:)
      • [      2)、循环赋值:](#      2)、循环赋值:)
      • [      3)、字符型数组,可以使用字符中直接赋值。](#      3)、字符型数组,可以使用字符中直接赋值。)
    • [   4、数组的引用](#   4、数组的引用)
    • [   5、多维数组](#   5、多维数组)
      • [      1)、二维数组定义与初始化](#      1)、二维数组定义与初始化)
      • [      2)、访问二维数组元素](#      2)、访问二维数组元素)
      • [      3)、遍历二维数组](#      3)、遍历二维数组)
    • [   6、数组和指针的关系](#   6、数组和指针的关系)
  • 二、字符串
    • [   1、字符串的定义与初始化](#   1、字符串的定义与初始化)
      • [      1)、​​定义字符串​​:](#      1)、定义字符串:)
      • [      2)、​​初始化字符串​​:](#      2)、初始化字符串:)
    • [   2、字符串的输入与输出](#   2、字符串的输入与输出)
      • [      1)、​​输出字符串​​](#      1)、输出字符串)
      • [      2)、​​输入字符串​​](#      2)、输入字符串)
    • [   3、字符串操作函数](#   3、字符串操作函数)
      • [      ​​1)、字符串长度​​](#      1)、字符串长度)
      • [      ​​2)、字符串复制​​](#      2)、字符串复制)
      • [      ​​3)、字符串连接​​](#      3)、字符串连接)
      • [      ​​4)、字符串比较​​](#      4)、字符串比较)
  • 三、结构体
    • [   1、结构体类型](#   1、结构体类型)
    • [   2、结构体变量的定义](#   2、结构体变量的定义)
      • [      先定义类型,再定义变量:](#      先定义类型,再定义变量:)
      • [      定义类型的同时定义变量](#      定义类型的同时定义变量)
      • [      直接定义结构体变量](#      直接定义结构体变量)
    • [   3、结构体变量的初始化。](#   3、结构体变量的初始化。)
    • [   4、结构体变量的引用。](#   4、结构体变量的引用。)
    • [   5、结构体数组](#   5、结构体数组)
  • 四、联合体
  • 五、枚举类型

一、数组

数组是一组相同类型元素的集合,这些元素在内存中是连续存储的。数组中的每个元素可以通过一个索引(下标)来访问,索引从0开始。

1、数组的定义

一维数组定义:类型标识符 数组名[元素个数];

例:int Stack[10];//10个元素

二维数组定义:类型标识符 数组名[元素个数1][元素个数2];

例:int Stack[2][3];//2行3个元素

2、数组的初始化

格式: 类型标识符 数组名[元素个数]={元素值表列};

例:int Stack[3]= {1,2,3};

当数组为整型时,初始化未确定的值为0;

3、数组的赋值

1)、直接赋值:

c 复制代码
			Stack[2] =100;

2)、循环赋值:

c 复制代码
			for(int I =0;i<5;i++)
			{
				Stack[i] = i*2;
			}

3)、字符型数组,可以使用字符中直接赋值。

c 复制代码
			char str1[] = "Hello";      // 自动添加'\0'
			char str2[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

4、数组的引用

C语言规定只能逐个引用数组元素.

格式:数组名[下标];

下标范围从0开始,小于等于元素个数-1;

5、多维数组

C语言支持多维数组,最常见的是二维数组(矩阵)。

1)、二维数组定义与初始化

c 复制代码
			// 定义3行4列的二维数组
			int matrix[3][4] = {
				{1, 2, 3, 4},
				{5, 6, 7, 8},
				{9, 10, 11, 12}
				};// 部分初始化
			int matrix2[3][4] = {
				{1, 2},
				{5},
				{9, 10, 11}
				};  // 未初始化的元素为0

2)、访问二维数组元素

c 复制代码
			int element = matrix[1][2];  // 访问第二行第三列的元素

3)、遍历二维数组

c 复制代码
			使用嵌套循环:
			for(int i = 0; i < 3; i++) {
				for(int j = 0; j < 4; j++) {
					printf("%d ", matrix[i][j]);
				}
				printf("\n");
			}

6、数组和指针的关系

数组名在大多数情况下会被隐式转换为指向数组第一个元素的指针。

c 复制代码
		int numbers[3] = {10, 20, 30};
		int *ptr = numbers;  // ptr指向数组首元素
		printf("%d\n", *(ptr + 1));  // 输出20

二、字符串

字符串是一种非常重要的数据类型,但是C语言不存在显式的字符串类型,C语言中的字符串都以字符串常量的形式出现或存储在字符数组中。

同时,C 语言提供了一系列库函数来对操作字符串,这些库函数都包含在头文件 string.h 中。

1、字符串的定义与初始化

在C语言中,字符串本质上是字符数组,其末尾有一个特殊的空字符 '\0'作为结束标志。

1)、​​定义字符串​​:

字符串可以通过字符数组来定义:

char str1[10]; // 定义一个可以存放最多9个字符的字符串(留一个位置给'\0')

2)、​​初始化字符串​​:

有多种方式可以初始化字符串:

​​使用字符数组初始化​​:

char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};

使用字符串字面量初始化​​(最常用):

char str3[] = "Hello"; // 编译器会自动在末尾添加'\0'

​​使用指针初始化​​:

char *str4 = "Hello"; // 这是一个字符串常量,存储在只读内存区,不可修改

2、字符串的输入与输出

C语言提供了多种输入输出字符串的函数。

1)、​​输出字符串​​

c 复制代码
			​​printf函数​​:使用 %s格式控制符。
			printf("%s", str3);
			​​puts函数​​:输出字符串并自动换行。
			puts(str3);

2)、​​输入字符串​​

c 复制代码
			​​scanf函数​​:使用 %s格式控制符,但遇到空格会停止读取。
			scanf("%s", str1); // 输入 "Hello World",只会读取"Hello"
			​​gets函数​​:读取一行输入,包括空格,但不安全,已被弃用。
			​​fgets函数​​:推荐使用,可以指定最大读取字符数,避免缓冲区溢出。
			fgets(str1, sizeof(str1), stdin); // 从标准输入读取,最多读取sizeof(str1)-1个字符

3、字符串操作函数

C语言在 <string.h>头文件中提供了一系列用于操作字符串的函数。

​​1)、字符串长度​​

c 复制代码
			​​strlen​​:计算字符串的长度(不包含结束符 '\0')。
			int len = strlen("Hello"); // len = 5

​​2)、字符串复制​​

c 复制代码
			​​strcpy​​:将源字符串复制到目标字符串。
			char dest[20];
			strcpy(dest, "Hello");
			​​strncpy​​:更安全的版本,可以指定最大复制字符数。
			strncpy(dest, source, sizeof(dest) - 1);
			dest[sizeof(dest) - 1] = '\0'; // 手动添加结束符

​​3)、字符串连接​​

c 复制代码
			​​strcat​​:将源字符串连接到目标字符串的末尾。
			char str[20] = "Hello";
			strcat(str, " World!");
			​​strncat​​:更安全的版本,可以指定最大连接字符数。

​​4)、字符串比较​​

c 复制代码
			​​strcmp​​:比较两个字符串。如果相等返回0;如果str1 > str2返回正数;否则返回负数。
			if (strcmp(str1, str2) == 0) {
			    printf("Strings are equal.\n");
			}
			​​strncmp​​:比较两个字符串的前n个字符。

三、结构体

1、结构体类型

结构体类型定义的一般形式为:

c 复制代码
			struct 结构体名{
				类型名1   成员名1;
				。。。。。。
				类型名n,成员名n;
			}

struct是结构体类型的标志,结构体名是由用户定义的,标识符它规定了所定义的结构体类型的名称,结构体类型的组成,成分成为成员,成员名的命名规则和变量名相同。

结构体类型定义形式例如:

c 复制代码
				struct person{
					char name[20];
					char sex;
					int age;
					float height;
				};

表示定义了一个结构体类型struct person,它是由name,sex,age,height四个成员组成。

2、结构体变量的定义

定义结构体类型只是说明了该类型的组成情况,编译系统并没有给他分配内存空间,就像系统不为int等类型本身分配空间一样,只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量,结构体变量占用的内存空间是其所成言所占内存之和。

先定义类型,再定义变量:

c 复制代码
					struct person{
						char name[20];
						char sex;
						int age;
					float height;
					};
					struct person stcPer;

表示先定义了结构体struct person,然后定义了一个struct person 类型的结构体变量stcPer;

定义类型的同时定义变量

复制代码
				struct person{
					char name[20];
					char sex;
					int age;
				float height;
				}stcPer;

这种方法定义的效果与前一种相同,也是定义了结构体类型和一个属于类型的结构体变量。

直接定义结构体变量

复制代码
			struct {
				char name[20];
				char sex;
				int age;
			float height;
			}stcPer;

这种形式定义与前两种方法不同,这种电影形式没有说明这种结构体类型的名声,所以这种方法通常在不需要再次定义此类型结构体变量的情况下使用。

3、结构体变量的初始化。

与普通变量一样,结构体类型的变量也可以在定义时进行初始化,将结构体变量各成员的初始顺序,只放在一对大括号中并用逗号分割。

c 复制代码
			struct person{
				char name[20];
				char sex;
				int age;
			float height;
			}stcPer = {"Lin Ping",'M',20,175.5};

对结构体类型变量赋初值时,按每个成员在结构体中的顺序一一对应复制。

4、结构体变量的引用。

结构体变量的引用必须在定义结构体变量后进行,对结构体变量的引用可以分为对结构体变量中成员的引用和对整个结构体变量的引用,一般对结构体变量的操作是以成员为单位进行的,引用的一般形式:

结构体变量名.成员名;

"."是成员运算符,它在所有的运算符中优先级最高。

如果某个成员本身又是结构体变量,则必须连续使用成员运算符,直到最低一级的成员才能进行运算,结构体变量的每个成员都属于某种数据类型,因此都可以像普通变量一样进行其类型允许的各种操作。

c 复制代码
		#include <stdlib.h>
		int _tmain(int argc,_TCHAR* argv[])
		{
			struct person
			{
				char name[20];
				int age;
			}stcPer = {"Mammon",20};
			printf("%s,%d",stcPer.name,stcPer.age);
			system("pause");
			return 0;
		}

5、结构体数组

定义结构体数组的方法和定义结构体变量的方法一样,定义结构体变量的三种方法都可以用来定义结构体数组例如:

c 复制代码
			struct person{
				char name[20];
				char sex;
				int age;
				float height;
			}per[3];

数组的每个元素的初值都放在一对大括号中,括号中依次排列元素各成员的初始值与一般数组的初始化一样,如果给出了全部元素的初值和数组的长度可以不指定,由系统根据初值的数目来确定数组长度。

c 复制代码
			struct person{
				char name[20];
				char sex;
				int age;
				float height;
			}per[3] = {{"Test",'M',20,175},{"Mammon",'F',13,186},{"Message",'M',18,176}};

对结构体数组的引用一般是对数组元素的成员进行引用,引用只要遵循对数组元素的引用规则和对结构体变量成员的研究规则即可例如:

c 复制代码
			#include <stdlib.h>
			struct person
			{
				char name[20];
				int age;
			}stcPer[2] = {{"Mammon",20},{"ABC",19}};
			
			int _tmain(int argc,_TCHAR* argv[])
			{
				printf("%s,%d",stcPer[0].name,stcPer[0].age);
				printf("%s,%d",stcPer[1].name,stcPer[1].age);
				system("pause");
				return 0;
			}

四、联合体

联合体有时也称之为共用体,union是联合体类型的标志,联合体可以由用户自定义,它规定了所定义的联合体类型的名称。联合体也由若干成员组成,其类型定义的一般形式为:

c 复制代码
union 联合体名
{
	类型名1  成员名1;
	......
	类型名n 成员名n;
};
union score
{
	char grabe;
	float point;
};

联合体类型及其变量的定义与结构体的含义是不同的,结构体变量的每个成员分别占有独立的内存区域,而联合体变量的所有成员共占一段内存区域,所以联合体变量所占字节数是其成员中占内存空间最大的成员字节数。

联合体变量必须先定义后使用,不能直接引用联合体变量,只能引用联合体变量的成员,引用的一般形式为:

联合体变量名.成员名

联合体变量的每个成员也可以像普通变量一样进行其类型允许的各种操操作,注意由于联合体类型的成员变量使用的是公用内存空间,因此联合体变量中起作用的总是最后一次存放的成员变量的值。

联合体变量可以作为结构体变量的成员,结构体变量也可以作为联合体变量的成员,并且联合体类型也可以定义数组如:

c 复制代码
		struct student{
			char * name;
			int dept;
			union score{
				char grabe;
				float point;
			}s;
		}stu[2];

五、枚举类型

枚举类型定义的一般形式为:

enum 枚举名{枚举元素1,枚举元素2,。。。。};

enum是枚举类型的标志,枚举名由用户自定义的标识符,它规定了所定义的枚举类型的名称,

例如:

enum season{spring,summer,autumn,winter};

表示定义了一个枚举类型enum season,它包含4个枚举元素。

定义了枚举类型后,就可以用它定义枚举类型变量,

枚举类型变量的定义有两种方法:

先定义枚举类类型再定义变量,例如:

enum season{spring,summer,autumn,winter};

enum season s;

表示定义了一个枚举类型和属于该类型的变量s,

直接定义枚举类型变量,例如:

enum season{spring,summer,autumn,winter} s;

在c编译中将枚举元素作为常量处理称为枚举常量,因此不能对他们进行赋值,例如,"spring=0"或"winter=1"是不合法的,枚举元素是被处理成一个整形常量的,它的值取决于定义时各枚举元素排列的先后顺序,第一个枚举元素的值为0,第2个为1,依次顺序加1,例如在以上的定义中spring的值为0,summer的值为1,autumn的值为2,winter的值为3,

也可以在定义时改变枚举元素的值,例如:

enum season{spring=1,summer,autumn,winter=0};

如果枚举的成员没有被指定值其值为前一元素值加1,因此spring值为1,summer的值为2,autuumn的值为3,winter的值为0;

相关推荐
逐步前行9 小时前
C语言--预处理
软件工程
逐步前行1 天前
C语言--变量常量
软件工程
雾江流1 天前
视频播放器 v12.1.357 | 4K顶级播放器,内置了视频下载器,可下载推特~脸书等国外视频
音视频·软件工程
计算机集成_1 天前
2025年的12大技术栈
软件工程
张较瘦_1 天前
计算机类本科毕业设计论文大纲设计及论文撰写指南
软件工程
郝学胜-神的一滴1 天前
Linux下的阻塞与非阻塞模式详解
linux·服务器·开发语言·c++·程序人生·软件工程
郝学胜-神的一滴3 天前
Effective Python 第44条:用纯属性与修饰器取代旧式的 setter 与 getter 方法
开发语言·python·程序人生·软件工程
张较瘦_3 天前
从零学会绘制系统架构图:目的、思路与实操指南
架构·系统架构·软件工程
破晓之翼4 天前
控制论的定义、工程意义及系统功能整合
设计模式·软件工程·产品经理·学习方法