初步认识c语言
什么是c语言
- C语言是一种通用的高级编程语言,由Dennis Ritchie于1972年在贝尔实验室开发。
- C语言具有简单、高效、可移植、可靠和灵活的特点,因此被广泛应用于操作系统、编译器、游戏开发、嵌入式系统、科学计算以及其他各种领域的软件开发。
- C语言是一种结构化编程语言,支持面向过程和面向对象编程,提供了丰富的基本数据类型、控制结构、函数库等特性,同时也支持指针和位运算等底层操作。
- C语言的语法简洁明了,易于学习和使用。
数据类型
常见数据类型
C语言中有多种基本数据类型,包括:
-
整型(int):表示整数值,可表示的范围依赖于所用机器的计算能力,一般为-2的31次方到2的31次方-1。
-
字符型(char):表示单个字符,占用一个字节的内存空间,可用于存储ASCII码表中的字符。
-
短整型(short):表示短整数值,可表示的范围为-2的15次方到2的15次方-1。
-
长整型(long):表示长整数值,可表示的范围为-2的31次方到2的31次方-1。
-
浮点型(float):表示浮点数,即带小数点的数值,可表示的范围和精度与所用机器的浮点运算能力有关。
-
双精度型(double):表示双精度浮点数,比浮点型精度更高,可表示的范围也更大。
此外,C语言还支持一些复合数据类型,如数组、结构体和联合体,以及指针类型,可用于处理复杂数据结构和动态内存分配。
变量与常量
变量
- 变量就是变化的量
- 变量分为全局变量与局部变量
//变量与常量
#include <stdio.h>
int n = 10;//全局变量
int main()
{
int age = 20;//局部变量
float weigh = 88.5;
return 0;
}
- 同一作用域用变量不能重复定义;局部变量与全局变量可以重复,以局部变量优先
int n = 100;
int main()
{
//int n = 10;
int n = 10;
printf("a=%d\n",a);//10
return 0;
}
- 变量定义后就要初始化,因为c语言中变量默认值是随机的
练习
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//计算两个数的和
int main()
{
int n1 = 0,n2 = 0;
//输入两个整数
printf("输入两个整数:");//输出函数
scanf("%d %d",&n1,&n2);//输入函数必须取地址
// vs使用scanf函数会报错 ,直接在代码第一行define一个宏,不要使用scanf_s
// 求和
int sum = n1 +n2;
// 输出结果
printf("sum=%d\n",sum);
return 0;
}
常量
- c语言中,常量分为以下几种:
- 字面常量
const
修饰的常变量#define
定义的标识符常量- 枚举常量
#include<stdio.h>
#define N 100
//常量
// 枚举常量
enum Gender
{
F,
M
} ;
int main()
{
// 字面常量
6;
// const修饰的常变量
int a = 1;
a = 6;
const int b = 1;//常变量本质是变量,但是不能被修改,有常量的属性
// b = 6;
// 标识符常量
int c = N;
printf("%d\n",c);
enum Gender m = M;
return 0;
}
字符串+转义字符+注释+命名规范
字符串
-
在C语言中,
字符串字面量
指的是用双引号括起来的一串字符,也就是字符串常量
。例如,"Hello, world!"就是一个字符串字面量。 -
字符串字面量在C语言中是常量,它们在程序运行期间是不能修改的。它们被存储在程序的静态存储区域中,通常是在可执行文件的数据段中。程序在运行时可以通过指向字符串字面量的指针来访问它们。
-
c语言中没育字符串类型,通常使用字符数组保存字符串
#include<stdio.h>
#include<string.h>
int main()
{
// 字符串
char arr1[] = "abcde"; //字符串""以\0为结束标记
printf("%s\n",arr1);
char arr2[] ={'a','b','c','d','e','\0'}; //这种形式没有结束标记
printf("%s\n",arr2);
// strlen():求字符串长度的一个函数,在头文件string.h中
int len = strlen(arr2);
printf("%d\n",len);
return 0;
}
转义字符
在C语言中,转义字符是用反斜杠(\)作为前缀的特殊字符序列。转义字符的作用是用来表示一些无法直接输入的字符,如换行符、制表符、双引号等。
下面是常见的一些转义字符:
- \n:表示换行符(Newline)
- \t:表示制表符(Tab)
- \b:表示退格符(Backspace)
- \r:表示回车符(Carriage return)
- \f:表示换页符(Form feed)
- \v:表示垂直制表符(Vertical tab)
- \:表示反斜杠字符本身
- ':表示单引号字符本身
- ":表示双引号字符本身
#include<stdio.h>
int main()
{
// 转义字符
char arr1[] = "abcden";
printf("%s\n",arr1);
char arr2[] = "abcde\n";
printf("%s\n",arr2);
return 0;
}
注释
在C语言中,有两种注释方式:单行注释和多行注释。
- 单行注释
单行注释以//
开头,后面跟着注释内容。单行注释可以在一行代码的末尾使用,也可以在一行代码的中间使用。单行注释会忽略后面的所有文字,直到行末结束。
int a = 10; // 这是一个单行注释,用于解释变量a的含义
- 多行注释
多行注释以/*
开头,以*/
结尾,中间是注释内容。多行注释可以跨多行使用,可以注释掉一段代码或多个语句。
/*
这是一个多行注释
可以跨多行使用
用于注释掉一段代码或多个语句
*/
int a = 10; // 这行代码被多行注释包围,被注释掉了
- 注释中的内容不会被编译器解释和执行,因此可以用于解释代码、调试、隐藏代码等目的。注释的作用是提高代码的可读性和可维护性。
命名规范
在C语言中,函数名称、参数名称和变量名称需要遵循以下命名规则:
- 只能使用字母、数字和下划线
_
字符。
2.必须以字母或下划线_
字符开头。
3.名称长度不能超过255个字符。
4.区分大小写。
此外,还有一些命名约定应该遵循,以提高代码的可读性和可维护性:- 函数名称应该以动词开头,以表明其执行的操作。例如,
calculate_sum
表示计算总和的函数。- 参数和变量名称应该以名词或形容词开头,以描述它们所代表的内容。例如,
length
表示长度,max_value
表示最大值。- 多个单词组成的名称应该使用下划线
_
字符分隔,而不是使用空格或驼峰命名法(camel case)。例如,max_value
表示最大值,而不是maxValue
或MaxValue
。- 避免使用关键字或保留字作为名称。例如,不能使用
int
或while
作为变量名。- 使用有意义的名称,避免使用无意义或缩写的名称。例如,使用
number_of_students
而不是nos
。
语句
选择语句
在C语言中,选择语句用于根据条件执行不同的代码块。C语言提供了两种选择语句:if语句和switch语句。
if语句
if语句的语法如下:
if (condition) {
// 如果条件为真,执行这里的代码
} else {
// 如果条件为假,执行这里的代码
}
- 其中,condition是一个条件表达式,如果这个表达式的值为真(非0),则执行if语句后面花括号中的代码块,否则执行else语句后面花括号中的代码块(如果有的话)。else语句是可选的,如果没有指定,则条件为假时不执行任何代码。
int a = 10;
if (a > 0) {
printf("a是正数\n");
} else {
printf("a是非正数\n");
}
switch语句
switch语句的语法如下:
switch (expression) {
case value1:
// 如果expression等于value1,执行这里的代码
break;
case value2:
// 如果expression等于value2,执行这里的代码
break;
// ... 可以有多个case分支
default:
// 如果expression和所有case的值都不匹配,执行这里的代码
break;
}
- 其中,expression是一个表达式,case value是一个常量表达式,表示当expression的值等于value时,执行后面花括号中的代码块。default是可选的,表示当expression的值和所有case的值都不匹配时,执行后面花括号中的代码块。
int a = 1;
switch (a) {
case 1:
printf("a等于1\n");
break;
case 2:
printf("a等于2\n");
break;
default:
printf("a不等于1也不等于2\n");
break;
}
循环语句
循环语句用于重复执行一段代码,直到满足某个条件为止。C语言提供了3种循环语句:while循环、do-while循环和for循环。
while循环:
while循环的语法如下:
while (condition) {
// 只要条件为真,就一直执行这里的代码
}
- 其中,condition是一个条件表达式,只要这个表达式的值为真(非0),就会一直执行while循环后面花括号中的代码块。
int i = 0;
while (i < 10) {
printf("%d\n", i);
i++;
}
do-while循环:
do-while循环的语法如下:
do {
// 先执行一遍这里的代码
} while (condition);
- 其中,condition是一个条件表达式,只要这个表达式的值为真(非0),就会继续执行do-while循环后面花括号中的代码块。do-while循环保证会至少执行一次循环体中的代码。
int i = 0;
do {
printf("%d\n", i);
i++;
} while (i < 10);
for循环:
for循环的语法如下:
for (initialization; condition; update) {
// 只要条件为真,就一直执行这里的代码
}
- 其中,initialization是循环变量的初始值;condition是一个条件表达式,只要这个表达式的值为真(非0),就会继续执行for循环后面花括号中的代码块;update是循环变量的更新操作,用于控制循环变量的变化。
for (int i = 0; i < 10; i++) {
printf("%d\n", i);
}
跳转语句
跳转语句用于控制程序的执行流程,可以跳过某些语句、重复执行某些语句或者跳转到程序的其他位置。C语言中提供了3种跳转语句:break语句、continue语句和goto语句。
break语句:
- break语句用于跳出循环语句(for循环、while循环、do-while循环或switch语句),并继续执行循环语句后面的代码。
for (int i = 0; i < 10; i++) {
if (i == 5) {
break;//只要打印到5就跳出循环
}
printf("%d\n", i);
}
continue语句:
- continue语句用于跳过循环语句中的某些语句,继续执行下一次循环。
for (int i = 0; i < 10; i++) {
if (i == 5) {
continue;//打印到5时跳过本次循环,继续打印6、7、8、9
}
printf("%d\n", i);
}
goto语句:
- goto语句用于跳转到程序的其他位置,可以用于实现复杂的控制流程。
- 但由于goto语句容易导致程序的可读性和可维护性变差,因此应该避免过度使用。
int i = 0;
loop:
printf("%d\n", i);
i++;
if (i < 10) {
goto loop;
}
函数
-
在C语言中,
函数
是一段封装了特定功能的代码块,它可以通过函数名和参数列表进行调用。 -
函数可以帮助我们将程序分解成小的、可重用的部分,提高代码的可读性、可维护性和可重用性。
-
C语言中的函数通常包括以下几个部分:函数声明、函数定义、函数调用
函数声明
- 函数声明是告诉编译器函数的名字、返回类型和参数列表等信息,以便在函数被调用时进行类型检查和参数匹配。
- 函数声明通常放在源文件的开头或头文件中。
函数声明的语法如下:
返回类型 函数名(参数列表);
- 其中,返回类型表示函数的返回值类型,函数名是一个标识符,用于唯一标识函数,参数列表是一组用逗号分隔的参数类型和参数名。
int max(int a, int b);
函数定义
- 函数定义是实现函数功能的实际代码,包括函数名、参数列表、返回类型和函数体等部分。函数定义通常放在源文件中。
函数定义的语法如下:
返回类型 函数名(参数列表) {
// 函数体
}
其中,返回类型、函数名和参数列表与函数声明相同,函数体是一段实现函数功能的代码块。
int max(int a, int b) {//这个函数定义实现了找出两个整数中的最大值功能。
if (a > b) {
return a;
} else {
return b;
}
}
函数调用
- 函数调用是使用函数名和参数列表来执行函数代码的过程。在函数调用时,需要提供与函数声明或定义中参数列表匹配的参数值。
函数调用的语法如下:
函数名(参数列表);
int a = 10, b = 20;
int max_value = max(a, b);//使用max函数来找出a和b中的最大值,并将结果赋值给max_value变量。
- C语言中的函数可以有返回值,也可以没有返回值。如果函数没有返回值,则返回类型为void。如果函数有返回值,则需要使用return语句来返回一个值。
- 函数可以有多个参数,参数之间使用逗号分隔。
- 如果函数没有参数,则参数列表可以为空,但是圆括号不能省略。
#include<stdio.h>
//函数
// 函数声明
int add(int a,int b);
// 函数定义
int add(int a,int b)
{
return a + b;
} ;
int main()
{
// 函数调用
int a = 10, b = 20;
int res = add(a, b);
printf("%d\n",res);
return 0;
}
数组
- 在C语言中,数组是一种存储相同类型数据的集合,它们按照一定的顺序排列,并可以通过下标来访问其中的元素。数组可以是一维数组、二维数组、多维数组等。
- 在C语言中,数组是一种非常常用的数据结构,它可以用于存储和处理大量的数据,并可以通过循环等方式进行高效的遍历和操作。
- 但是,数组的大小在编译时就已经确定,因此它的大小不能动态地改变。
- 如果需要动态地增加或减少数组的大小,可以考虑使用动态分配内存的方式,例如使用malloc函数来动态分配数组内存空间。
定义
C语言中的数组定义需要指定数组的类型、名称和元素个数
int a[10]; // 定义一个包含10个int类型元素的数组a
访问
下标访问
- 数组的元素可以通过下标访问
a[0] = 1; // 给数组第一个元素赋值为1
int x = a[1]; // 从数组中获取第二个元素的值
-
数组的下标可以是任何整数类型,包括正整数、负整数和0。
-
如果下标超出了数组的索引范围,则可能会导致运行时错误,例如访问未定义的内存地址。因此,在使用数组时需要特别注意下标的取值范围。
-
C语言中的数组也可以使用初始化列表来初始化数组元素的值
int a[5] = {1, 2, 3, 4, 5}; // 定义一个包含5个int类型元素的数组a,并初始化为1、2、3、4、5
指针操作
除了循环以外,C语言中还有一些其他的方式可以高效地遍历和操作数组,包括指针、函数指针、指针算术等。
- 指针
- 指针是C语言中的一种特殊数据类型,它保存了一个变量的内存地址。
- 在使用指针操作数组时,可以通过指针访问数组中的元素,例如:
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // 将数组a的首地址赋值给指针p
int x = *(p + 1); // 通过指针p访问数组中的第二个元素(即a[1])
这个例子定义了一个名为a的数组,包含5个int类型的元素,然后将数组的首地址赋值给指针p。通过指针p可以访问数组中的元素,例如获取第二个元素的值。
- 函数指针
- 函数指针是指向函数的指针变量,它可以存储函数的地址,并且可以作为参数传递给其他函数或作为返回值返回给调用者。
- 在使用函数指针操作数组时,可以将指针指向一个函数,然后通过指针调用该函数来遍历和操作数组,例如:
void process(int *p, int n, void (*func)(int *)) {
//定义了一个名为process的函数,它接受一个指向数组的指针、数组的长度和一个函数指针作为参数
for (int i = 0; i < n; i++) {
func(p + i);
}
}
void print(int *p) {
printf("%d ", *p);
}
int a[5] = {1, 2, 3, 4, 5};
process(a, 5, print); // 使用函数指针print遍历数组a并打印数组元素
- 指针算术
- 指针算术是指对指针进行加、减、自增、自减等操作的过程。
- 在使用指针算术操作数组时,可以使用指针进行遍历和操作,例如:
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // 将数组a的首地址赋值给指针p
for (int i = 0; i < 5; i++) {
printf("%d ", *p); // 打印指针p指向的数组元素的值
p++; // 将指针p向后移动一个元素
}
需要注意的是,在使用指针操作数组时,需要特别注意指针的取值范围和指针算术的正确性,否则可能会导致未定义的行为或运行时错误。
操作符
- 在C语言中,有很多常用的操作符,包括算术操作符、关系操作符、逻辑操作符、位操作符、赋值操作符、条件操作符、指针操作符等。
下面是常用的一些操作符的介绍:
算术操作符
算术操作符用于执行数学运算,包括加、减、乘、除、取模等。常用的算术操作符包括:
- 加法操作符:+
- 减法操作符:-
- 乘法操作符:*
- 除法操作符:/
- 取模操作符:%
例如,下面的代码演示了如何使用算术操作符进行加、乘、取模运算:
int a = 10, b = 3;
int c = a + b; // c的值为13
int d = a * b; // d的值为30
int e = a % b; // e的值为1
关系操作符
关系操作符用于比较两个值的大小或关系,返回值为真(非0)或假(0)。常用的关系操作符包括:
- 等于操作符:==
- 不等于操作符:!=
- 大于操作符:>
- 小于操作符:<
- 大于等于操作符:>=
- 小于等于操作符:<=
例如,下面的代码演示了如何使用关系操作符进行大小比较:
int a = 10, b = 3;
int c = a > b; // c的值为1,表示a大于b
int d = a < b; // d的值为0,表示a小于b
int e = a == b; // e的值为0,表示a等于b
逻辑操作符
逻辑操作符用于执行逻辑运算,包括与、或、非等。常用的逻辑操作符包括:
- 逻辑与操作符:&&
- 逻辑或操作符:||
- 逻辑非操作符:!
例如,下面的代码演示了如何使用逻辑操作符进行逻辑运算:
int a = 10, b = 3, c = 0;
int d = (a > b) && (c == 0); // d的值为1,表示a大于b并且c等于0
int e = (a < b) || (c != 0); // e的值为1,表示a小于b或者c不等于0
int f = !(a > b); // f的值为0,表示a不大于b
位操作符
位操作符用于对二进制位进行操作,包括按位与、按位或、按位异或等。常用的位操作符包括:
- 按位与操作符:&
- 按位或操作符:|
- 按位异或操作符:^
- 按位取反操作符:~
例如,下面的代码演示了如何使用位操作符进行位运算:
int a = 0b1010, b = 0b1100;
int c = a & b; // c的值为0b1000,表示a和b按位与的结果
int d = a | b; // d的值为0b1110,表示a和b按位或的结果
int e = a ^ b; // e的值为0b0110,表示a和b按位异或的结果
int f = ~a; // f的值为0b0101,表示a按位取反的结果
赋值操作符
赋值操作符用于将一个值赋给一个变量或表达式。常用的赋值操作符包括:
- 等于操作符:=
- 加等于操作符:+=
- 减等于操作符:-=
- 乘等于操作符:
*=
- 除等于操作符:/=
- 取模等于操作符:%=
例如,下面的代码演示了如何使用赋值操作符进行赋值运算:
int a = 10, b = 3;
a += b; // 将a加上b的值,并将结果赋给a
a *= b; // 将a乘以b的值,并将结果赋给a
a %= b; // 将a对b取模的结果赋给a
条件操作符
-
条件操作符也称为
三元操作符
,它是C语言中唯一的一个三元操作符,用于在两个值之间选择一个值。常用的条件操作符包括: -
条件操作符:exp1 ? exp2 : exp3
例如,下面的代码演示了如何使用条件操作符进行条件选择:
int a = 10, b = 3;
int max = (a > b) ? a : b; // 如果a大于b,则将a赋给max,否则将b赋给max
指针操作符
- 指针操作符用于对指针进行操作,包括取地址、取值等。
- 常用的指针操作符包括:
- 取地址操作符:&
- 取值操作符:*
- 自增操作符:++
- 自减操作符:--
例如,下面的代码演示了如何使用指针操作符进行指针操作:
int a = 10;
int *p = &a; // 取变量a的地址,并将地址赋给指针p
int b = *p; // 取指针p指向的变量的值,并将值赋给变量b
int *q = p++; // 将指针p向后移动一个位置,并将移动前的地址赋给指针q
int *r = --p; // 将指针p向前移动一个位置,并将移动后的地址赋给指针r
常见关键字
在C语言中,关键字
是具有特殊含义的保留字,用于表示程序的结构、控制流、数据类型等。下面是C语言中常用的关键字:
数据类型关键字
C语言中的数据类型关键字用于定义变量的数据类型,包括:
- int:整型
- char:字符型
- float:单精度浮点型
- double:双精度浮点型
- void:无类型
例如,下面的代码定义了一个整型变量和一个字符型变量:
int age = 20;
char name = 'John';
流程控制关键字
C语言中的流程控制关键字用于控制程序的流程,包括:
- if、else:条件语句
- switch、case:多分支语句
- while、do、for:循环语句
- break、continue:跳转语句
例如,下面的代码使用了if语句和for循环语句:
int i;
for (i = 1; i <= 10; i++) {
if (i % 2 == 0) {
printf("%d is even\n", i);
} else {
printf("%d is odd\n", i);
}
}
函数关键字
C语言中的函数关键字用于声明和定义函数,包括:
- return:返回语句
- int、char、float、double、void:函数返回值类型
- main:程序入口函数
例如,下面的代码定义了一个返回整型值的函数:
int add(int a, int b) {
return a + b;
}
存储类型关键字
C语言中的存储类型关键字用于指定变量的存储类型,包括:
- auto:自动变量
- static:静态变量
- extern:外部变量
- register:寄存器变量
例如,下面的代码定义了一个静态变量和一个外部变量:
static int count = 0;
extern int sum;
指针关键字
C语言中的指针关键字用于声明和操作指针,包括:
*
:指针声明符号&
:取地址运算符
例如,下面的代码定义了一个指向整型变量的指针:
int a = 10;
int *p = &a;
define定义常量和宏
- 在C语言中,define是用来定义常量和宏的预处理指令,它可以在程序编译之前将代码中的宏和常量替换为指定的值,从而提高程序的效率和可维护性。
定义常量
- 使用define可以定义一个常量,常量的值在程序执行过程中不能被改变。
定义常量的语法如下:
#define 常量名 值
例如,下面的代码定义了一个名为PI的常量,它的值为3.14:
#define PI 3.14
- 在程序中使用常量时,可以直接使用常量名,编译器会将常量名替换为它的值。例如:
double r = 1.0;
double area = PI * r * r;
定义宏
- 使用define可以定义一个宏,宏是一段代码片段,可以在程序中多次使用。
定义宏的语法如下:
#define 宏名 替换文本
- 替换文本可以是一段代码,可以包含变量、运算符、控制语句等。
#define MAX(a, b) ((a) > (b) ? (a) : (b))
//定义了一个名为MAX的宏,它返回两个数中的最大值
- 在程序中使用宏时,可以将宏名作为函数调用的方式使用,编译器会将宏名替换为它的替换文本。例如:
int a = 10, b = 20;
int max = MAX(a, b);
//在这个例子中,MAX被替换为它的替换文本((a) > (b) ? (a) : (b)),最终计算出a和b中的最大值。
- 需要注意的是,使用宏可能会带来一些副作用,例如替换文本中的变量可能会被重复计算、宏定义中的参数不一定会进行类型检查等。因此,在使用宏时需要注意一些细节,以避免出现问题。
指针
- 在C语言中,
指针
是一种特殊的变量,它存储了一个内存地址,这个地址指向计算机内存中的某个位置,可以用来访问和修改该位置的数据。 - 指针在C语言中是非常重要的概念之一,它可以用来实现动态内存分配、数组和字符串的操作、函数的传递等。需要掌握指针的定义、赋值、访问、算术运算等操作。
指针的定义和使用可以分为以下几个方面:
指针的定义
- 在C语言中,可以使用指针类型来定义一个指针变量,指针类型的语法如下:
数据类型 *指针变量名;
- 其中,数据类型表示指针所指向的数据类型,指针变量名是指针变量的名称,
*
表示指针类型。
int *p;//定义一个整型指针变量p
- 在定义指针变量时,需要注意指针变量所指向的数据类型,指针变量只能指向与其类型相同的变量或数据类型。
指针的赋值和访问
- 指针变量存储的是一个内存地址,可以通过赋值操作将其指向一个具体的内存位置。指针变量的赋值语法如下:
指针变量名 = &变量名;
- 其中,
&
表示取地址运算符,可以获取变量在内存中的地址。
int a = 10;
int *p = &a;//将指针变量p指向了整型变量a的地址:
- 指针变量可以通过解引用操作(
*
)来访问指针所指向的内存位置中的数据。
int a = 10;
int *p = &a;//通过指针变量p来访问a的值
//*p表示指针所指向的内存位置中存储的数据,在这里就是a的值。
printf("a = %d\n", *p);
指针的算术运算
- 指针还支持一些算术运算,可以对指针进行加、减、比较等操作。这些算术运算可以用来实现数组、字符串等数据结构的操作。
例如,可以将指针加上一个整数n来访问指针所指向内存位置中的下一个或上一个元素:
int a[5] = {1, 2, 3, 4, 5};
int *p = a;
printf("%d\n", *(p + 1)); // 访问a[1]的值
//在这个例子中,p表示指向数组a的第一个元素的指针,可以使用p + 1来访问a[1]的值。
指针的空指针和野指针
- 空指针是指未被初始化的指针,它的值为NULL。
- 野指针是指指针变量指向的内存位置没有被分配或已经被释放,使用野指针可能会导致程序崩溃或数据损坏
结构体
- 在C语言中,
结构体
是一种自定义数据类型,它可以将多个不同类型的数据组合在一起,形成一个新的复合数据类型。结构体在C语言中被广泛使用,可以用来表示复杂数据结构、数据记录、对象等。 - 结构体在C语言中被广泛使用,需要掌握结构体的定义、声明、初始化、指针和嵌套等操作。
结构体的定义和使用可以分为以下几个方面:
结构体的定义
- 在C语言中,可以使用关键字
struct
来定义一个结构体类型,结构体类型的语法如下:
struct 结构体名 {
数据类型 成员1;
数据类型 成员2;
// ...
};
其中,结构体名是结构体类型的名称,成员1、成员2等是结构体的成员变量,数据类型可以是任意合法的C语言数据类型。
struct Student {//定义一个名为Student的结构体类型,它有两个成员变量name和age
char name[20];
int age;
};
结构体的声明和初始化
- 定义了结构体类型之后,可以声明结构体变量,并对其进行初始化。结构体变量的声明和初始化语法如下:
struct 结构体名 变量名 = {成员1的初始值, 成员2的初始值, ...};
下面的代码声明了一个名为s的结构体变量,并对其进行了初始化:
struct Student s = {"Tom", 20};
- 在程序中使用结构体变量时,可以使用点操作符(.)来访问结构体的成员变量。
例如,下面的代码输出了结构体变量s的成员变量name和age:
printf("name: %s, age: %d\n", s.name, s.age);
结构体的指针
- 结构体变量可以使用指针来进行访问和修改。使用结构体指针的语法如下:
struct 结构体名 *指针变量名;
struct Student *p = &s;//定义一个指向Student结构体的指针变量p,并将它指向结构体变量s的地址:
- 指针变量可以使用箭头操作符(->)来访问结构体成员变量。
printf("name: %s, age: %d\n", p->name, p->age);//下面的代码输出了指针变量p所指向的结构体变量的成员变量name和age
结构体的嵌套
- 结构体可以嵌套在其他结构体中,形成更复杂的数据类型。
struct Course {
//定义了一个名为Course的结构体类型,它包含了一个Student结构体类型的成员变量student和一个整型成员变量score
struct Student student;
int score;
};
- 在程序中使用嵌套结构体时,可以使用点操作符或箭头操作符来访问结构体的成员变量。
struct Course c = {{"Tom", 20}, 90};
printf("name: %s, age: %d\n", c.student.name, c.student.age);
//输出了嵌套结构体变量c的成员变量student的成员变量name和age