C语言的数据类型及输入输出方式

👁️ 358 ❤️ 649
C语言的数据类型及输入输出方式

一、基本数据类型

基本数据类型包括整型(int)、短整型(short)、长整型(long)、字符型(char)、浮点型(float)和双精度浮点型(double)。

类型定义方式(示例)取值范围整型(int)int a = 10;-2,147,483,648 ~ 2,147,483,647(4字节)短整型(short)short b = 20;-32,768 ~ 32,767(2字节)长整型(long)long c = 1723710; -2,147,483,648 ~ 2,147,483,647(4字节)字符型(char)char s = 'b';-128~127(1字节)浮点型(float)

float a = 10.1882;

1.2E-38 ~ 3.4E+38(4字节,精确小数点后六位)双精度浮点型(double)

double b = 298.18828323241;

2.3E-308 ~ 1.7E+308(8字节,小数点后15位)

二、构造数据类型

2.1.数组

数组是一种用于存储多个同类型数据元素的线性数据结构,以下是C语言数组的一些基本特点和用法:

2.1.1定义数组:

一般格式:data_type array_name[array_size];

其中data_type是基本数据类型,array_size是所需要构造的数组容量,如定义一个长度为三且全是整形的数组:

int arr1[3]; //当未指定初始值时,默认的初始值是0,即{0, 0, 0}。

2.1.2 初始化数组

数组可以在定义时进行初始化,也可以在后续赋值。初始化时可以在大括号内列出元素:

int numbers[5] = {1, 2, 3, 4, 5};

也可以部分初始化,未初始化的元素会被设置为0:

int numbers[5] = {1, 2}; // numbers[2]、numbers[3]、numbers[4] 被初始化为0

2.1.3 访问和修改数组元素

数组的元素通过索引访问,索引从0开始。例如:

int first = numbers[0]; // 访问第一个元素

numbers[1] = 10; // 修改第二个元素

2.1.4 数组的大小

在C语言中,数组的大小是固定的。一旦定义,大小就是不可改变的。可以通过使用sizeof运算符来获取数组所占的字节数:

int size = sizeof(numbers) / sizeof(numbers[0]); // 计算数组元素个数

但是当你传递一个二维数组到函数时,sizeof(arr) 在计算时将返回数组指针的大小,而不是数组的实际元素数量。

2.1.5 多维数组

C语言支持多维数组,最常用的是二维数组。定义方式如下:

data_type array_name[size1][size2];

2.1.6简单示例

#include

int main(){

int numbers[5] = {1, 2, 3, 4, 5};

int arr[3][3] = {

{1, 2, 3},

{4, 5, 6},

{7, 8, 9}

}; // 定义数组

// 输出数组元素

for (int i = 0; i < 5; i++) {

printf("%d ", numbers[i]);

}

printf("\n");

// 修改数组元素

numbers[2] = 10;

// 输出修改后的数组

for (int i = 0; i < 5; i++) {

printf("%d ", numbers[i]);

}

printf("\n");

for (int i = 0; i < 3; i++){

for (int j = 0; j < 3; j++){

printf("%d\n", arr[i][j]); // 循环打印二维数组的内容

}

}

return 0;

}

2.2结构体

C语言中的结构体(struct)是用户定义的数据类型,可以将不同类型的数据组合成一个单一的类型。类似于python中的类、java中的对象。结构体使得程序员可以以更实用的方式组织和管理数据,尤其是在处理复杂数据时。

2.2.1 定义结构体

结构体的定义使用struct关键字,基本语法如下:

struct struct_name {

data_type member1;

data_type member2;

// ...

};

例如,定义一个表示学生的结构体:

struct student{

char name[20];

int age;

float score;

};

2.2.2. 声明结构体变量

定义结构体后,可以声明结构体变量。可以使用定义的结构体类型来创建新的变量:

struct Student Jake;

2.2.3. 初始化结构体

可以在声明结构体变量时进行初始化:

struct Student Jake = {"Jake", 20, 89.5};

或者可以在之后逐个成员地赋值:

struct Student stu1;

strcpy(stu1.name, "Bob"); // 需要包含

stu1.age = 21;

stu1.score = 90.0;

2.2.4. 访问结构体成员

使用点运算符(.)来访问结构体的成员:

printf("Name: %s\n", stu1.name);

printf("Age: %d\n", stu1.age);

printf("score: %.2f\n", stu1.grade);

2.2.5. 数组与结构体结合

可以创建结构体数组,以便存储多个结构体实例。例如,存储多个学生的信息:

struct Student students[3] = {

{"Alice", 20, 89.5},

{"Bob", 21, 90.0},

{"Charlie", 19, 85.0}

};

2.2.6. 结构体嵌套

结构体可以嵌套定义,即一个结构体的成员可以是另一个结构体:

struct Address {

char city[50];

char state[50];

};

struct Student {

char name[50];

int age;

float grade;

struct Address address; // 嵌套结构体

};

2.2.7.与typedef一起用:

可以为结构体定义新的别名,简化结构体的使用:

struct Student {

char name[50];

int age;

float grade;

};

// 使用 typedef 定义结构体的别名

typedef struct Student Student;

int main() {

// 使用 Student 而不是 struct Student

Student student1;

strcpy(student1.name, "Alice");

student1.age = 20;

student1.grade = 89.5;

printf("Name: %s, Age: %d, Grade: %.2f\n", student1.name, student1.age, student1.grade);

return 0;

}

三、指针类型

指针是一个变量,其值是另一变量的地址。简单来说,指针“指向”内存中的某个位置。所有类型的指针都有自己的类型,指针的类型决定了它所指向的数据的类型。3.1 声明指针

指针的声明使用星号(*)符号:

int *a; /* 一个整型的指针 */

double *b; /* 一个 double 型的指针 */

float *c; /* 一个浮点型的指针 */

char *d; /* 一个字符型的指针 */

3.2 初始化指针

可以使用取地址运算符(&)来初始化指针,该运算符用于获取变量的地址:

int a = 10;

int *p = &a; // p 现在指向变量 a 的地址

未初始化的指针会指向随机地址,使用它们会导致未定义行为。

3.3. 指针的基本操作

访问指针指向的值:

int b = *p; // b 现在是 10,*p 解引用 p,得到 a 的值

修改指针指向的值,可通过直接修改指针:

*p = 20; // 现在 a 的值变为 20

3.4. 指针与数组

C语言中,数组名代表数组的首地址,因此可以用指针来访问数组元素:

int arr[3] = {10, 20, 30};

int *p = arr; // 指向数组的第一个元素,数组名为地址,无需使用&即可赋值给*p

printf("%d\n", *(p + 1)); // 访问第二个元素,输出 20

printf("%d\n", p[1]); // 与上面等价,p[1]表示偏移量为1,p为数组的首地址可以看作数组名来调用数组

3.5. 指针与函数

指针可以作为函数参数进行传递,这样可以直接修改函数外部的变量:

void increment(int *p) {

(*p)++; // 解引用并自增

}

int main() {

int a = 5;

increment(&a); // 将 a 的地址传递给函数

printf("%d\n", a); // 输出 6

return 0;

}

3.6. 指向指针的指针

C语言允许指针指向指针,指针也有地址,这被称为“指向指针的指针”。这是多重指针的概念。

int a = 10;

int *p = &a; // 指向整型的指针

int **q = &p; // 指向指针的指针

printf("%d\n", **q); // 输出 10

3.7. 空指针

空指针是指不指向任何有效地址的指针。在C语言中,可以使用 NULL 来表示空指针:

int *p = NULL; // p 是一个空指针

使用空指针可以避免指针指向不确定的内存。

3.8. 动态内存分配

指针在动态内存分配(如使用 malloc)时非常有用。可以在运行时分配内存:

#include

#include

int main() {

int *arr = (int *)malloc(5 * sizeof(int)); // 分配 5 个整数的内存

if (arr == NULL) {

printf("Memory allocation failed!\n");

return 1;

}

for (int i = 0; i < 5; i++) {

arr[i] = i * 2; // 使用指针访问数组元素

}

for (int i = 0; i < 5; i++) {

printf("%d ", arr[i]); // 输出 0 2 4 6 8

}

free(arr); // 释放动态分配的内存

return 0;

}

动态分配的内存必须通过 free() 函数释放,以避免内存泄漏。

四、空类型void

在C语言中,void 是一个特殊的数据类型,表示“无类型”或“空类型”。它的使用主要包括函数的返回类型、指针类型及其作为不带参数的函数。下面是对 void 类型的详细介绍:

1. void 作为函数的返回类型

当一个函数不需要返回任何值时,可以将其返回类型声明为 void:

void printMessage() {

printf("Hello, World!\n");

}

int main() {

printMessage(); // 调用不返回任何值的函数

return 0;

}

2. void 指针

void 类型也可以用作指针类型,称为“空指针”。void 指针可以指向任何类型的数据,但不能直接解引用,因为编译器无法确定其所指向数据的类型。

void *ptr; // 声明一个 void 指针

int num = 42;

ptr = # // 将 int 类型的地址赋给 void 指针

// 使用 void 指针之前需要转换为具体类型

int value = *(int *)ptr; // 强制类型转换为 int 指针并解引用

printf("%d\n", value); // 输出 42

void指针在动态内存管理中非常常用,例如,malloc函数的返回值就是void*类型。

3. 不带参数的函数

在C语言中,定义不带参数的函数时,可以使用 void 来显式地表示函数不接收参数:

void noParameters(void) {

printf("This function takes no parameters.\n");

}

接下来是输入输出内容:

一、格式化输入输出函数

1.标准输入函数scanf

scanf 是 C 语言中用于从标准输入(通常是键盘)读取数据的函数。它是 C 标准库的一部分,声明在头文件 中。scanf 函数使用格式化字符串来定义输入数据的类型和格式,能够处理多种数据类型的输入。

1.1基本语法

int scanf(const char *format, ...);

format:一个格式字符串,指定输入数据的格式。...:一个可变参数列表,参数的数量和类型根据格式字符串的内容而定。scanf 函数的返回值是成功读取的项数(根据格式字符串中指定的转换说明符的数量)。如果在读取过程中发生错误,或者到达文件末尾(在读取文件时),则返回一个 EOF(通常为 -1)。1.2. 格式字符串

格式字符串包含文本和格式指示符。常见的格式指示符包括:

%d:读取整数(十进制)。%f:读取浮点数(单精度)。%lf:读取双精度浮点数(double)。%c:读取单个字符。%s:读取字符串(空格作为分隔符)。%u:读取无符号整数。%x:读取十六进制整数。格式字符串可以包括多个格式指示符,用空格、换行或其他分隔符分隔。

1.3示例

读取字符串、整数和浮点数:

#include

int main() {

char name[4];

int age;

float height;

printf("Enter your name: ");

scanf("%s", &name); // 读取字符串

printf("Enter your age: ");

scanf("%d", &age); // 读取整数

printf("Enter your height (in meters): ");

scanf("%f", &height); // 读取浮点数

printf("%s are %d years old and %.2f meters tall.\n", name, age, height);

return 0;

}

1.4 注意事项

输入缓冲区问题:scanf 在读取字符串时会在遇到空格、换行等空白字符时停止,因此如果需要读取包含空格的字符串,应使用 fgets 函数。

地址运算符:对于大多数数据类型(如 int、float),需要在变量前加上地址运算符 & 来获取变量的地址。然而,对于数组(字符串)和指针类型的变量,就不需要添加地址运算符,因为数组名本身就是指向其第一个元素的指针。

格式匹配:scanf 在输入时会进行格式匹配,如果用户输入的格式与格式说明符不匹配,scanf 可能会导致未定义行为。在使用 scanf 进行输入时,最好检查返回值来确保输入成功。

2.格式化输出函数printf

printf 是 C 语言中用于向标准输出设备(通常是屏幕)格式化输出数据的函数。它是 C 标准库的一部分,声明在头文件 中。printf 可以输出多种数据类型,并且可以通过格式化字符串定义输出的格式。

2.1.基本语法

printf(String, list ...);

String:一个格式控制字符串,指定输出数据的类型和格式。list:输出列表...:一个可变参数列表,参数的数量和类型根据格式字符串的内容而定。返回值是函数的返回值是成功输出的字符总数。如果输出失败,则返回一个负值。printf("a=%d, b=%f", a, b);

表示a按照整型格式输出,b按照浮点数格式输出。

2.2.格式字符串

格式字符串包含文本和格式指示符。常见的格式指示符包括:

%d:输出整数(十进制)。

%f:输出浮点数(单精度)。

%lf:输出双精度浮点数(double)。

%c:输出单个字符。

%s:输出字符串(空格作为分隔符)。

%u:输出无符号整数。

%o:输出八进制整数。

%x:输出十六进制整数。

%%:输出一个百分号字符。浮点数输出时可以控制数据长度和精度:%m.nf,其中m表示数据长度,n表示小数点后保留几位。

例子:

#include

int main() {

int age = 25;

float height = 1.75;

printf("Age: %d years\n", age); // 输出整数

printf("Height: %2.1f meters\n", height); // 输出浮点数,保留一位小数

return 0;

}

2.3. 格式控制

printf 的格式字符串可以包含额外的控制选项:

对齐:默认为右对齐,可以通过在宽度前加 - 来实现左对齐。例如:%-10d 表示一个宽度为 10 的整数,左对齐。

宽度:可以指定输出的最小宽度。例如,%5d 表示至少 5 个字符宽的输出。

精度:特定于浮点数和字符串。例如,%.2f 表示输出浮点数时保留两位小数,%.5s 表示输出字符串的前 5 个字符。

填充:也可以通过指定宽度时添加 0 来做填充,比如 %05d 表示用 0 填充宽度为 5 的整数。

二、字符串输入输出函数

1. puts 函数

puts 函数用于将字符串输出到标准输出(通常是屏幕),并在输出后自动添加一个换行符。

puts(const char *str);

str:指向要输出的字符串的指针。字符串应以空字符 \0 结尾。返回值为非负整数,表示成功输出的字符数(包括换行符)。如果输出失败,则返回 EOF。例:

#include

int main() {

const char *message = "Hello, World!";

puts(message); // 输出 "Hello, World!" 并换行

return 0;

}

2. gets 函数(不推荐使用)

gets 函数用于从标准输入中读取一行字符串,直到遇到换行符(即用户按下 Enter 键)。然而,由于 gets 没有边界检查,容易导致缓冲区溢出,因此在 C11 标准中被声明为已废弃,不推荐使用。

char *gets(char *str);

str:指向字符数组的指针,用于存储读取的字符串。如果读取成功,返回指向字符串的指针;如果发生读取错误或到达文件结束标志,则返回 NULL。例:

#include

int main() {

char name[100];

puts("Enter your name:");

gets(name); // 从标准输入读取字符串

puts("Hello, ");

puts(name); // 输出读取的字符串

return 0;

}

3. 使用 fgets 作为 gets 的替代

由于 gets 的安全性问题,推荐使用 fgets 函数作为字符串输入的替代方法。fgets 可以指定读取的最大字符数,从而避免缓冲区溢出。

char *fgets(char *str, int n, FILE *stream);

str:指向字符数组的指针,用于存储读取的字符串。n:要读取的最大字符数,包括末尾的空字符。stream:输入流,通常是 stdin,表示从标准输入(通常是键盘)读取数据。成功时返回 str,失败时返回 NULL。例:

#include

int main() {

char name[100];

puts("Enter your name:");

fgets(name, sizeof(name), stdin); // 安全地从标准输入读取字符串

puts("Hello, ");

puts(name); // 输出读取的字符串

return 0;

}

三、字符输入输出函数

1. getchar 函数

getchar 用于从标准输入流中读取一个字符。

getchar(void);

返回读取到的字符(作为 int 类型)。如果到达文件末尾(EOF)或发生错误,则返回 EOF(通常为 -1)。2. putchar 函数

putchar 用于向标准输出流写入一个字符。

putchar(int ch);

ch:要输出的字符,虽然参数类型为 int,但其对应一个字符。返回输出的字符。如果发生错误,则返回 EOF。

例:

#include

int main() {

char ch;

printf("请输入一个字符: ");

ch = getchar(); // 从标准输入读取一个字符

printf("您输入的字符是: ");

putchar(ch); // 输出读取的字符

putchar('\n'); // 换行

printf("输出字符: ");

putchar(ch); // 输出字符 'A'

putchar('\n'); // 换行

return 0;

}

← 晨曦1-48章全集TXT下载 vue为什么保存视频这么慢 →