C语言中常见的几种数据存储方式包括:变量、数组、结构体、文件操作、指针。其中,指针是C语言中最具特色和强大的工具。指针不仅能用于动态内存分配,还能通过指针实现复杂的数据结构,如链表、树、图等。通过指针,程序可以更灵活、高效地管理内存。
一、变量
1.1 基本数据类型变量
在C语言中,变量是最基本的数据存储单位。变量用于存储数据,并且可以在程序运行过程中改变其值。C语言支持多种基本数据类型,如整型(int)、字符型(char)、浮点型(float)、双精度浮点型(double)等。
int main() {
int a = 10;
float b = 20.5;
char c = 'A';
double d = 30.123456;
return 0;
}
1.2 作用域和生命周期
变量的作用域决定了它在哪些部分的代码中可以被访问。局部变量只在定义它的函数内部有效,而全局变量在整个程序中都有效。变量的生命周期决定了它在内存中存活的时间。局部变量的生命周期从声明开始到函数结束,全局变量则在整个程序的生命周期内有效。
int globalVar = 100; // 全局变量
void func() {
int localVar = 50; // 局部变量
}
二、数组
2.1 一维数组
数组是一组相同类型数据的集合。在C语言中,数组用于存储一组相关的数据。最常见的是一维数组,它存储一系列相同类型的元素。
int main() {
int arr[5] = {1, 2, 3, 4, 5};
return 0;
}
2.2 多维数组
多维数组用于存储更复杂的数据结构,如矩阵或表格。二维数组是最常见的多维数组形式。
int main() {
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
return 0;
}
三、结构体
3.1 定义和使用结构体
结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起。它允许我们将相关的数据存储在一个单一的数据结构中。
#include <stdio.h>
struct Person {
char name[50];
int age;
float height;
};
int main() {
struct Person person1;
person1.age = 30;
person1.height = 5.9;
snprintf(person1.name, sizeof(person1.name), "John Doe");
printf("Name: %s, Age: %d, Height: %.1fn", person1.name, person1.age, person1.height);
return 0;
}
3.2 嵌套结构体
结构体可以嵌套在另一个结构体中,以更好地组织复杂的数据。
#include <stdio.h>
struct Date {
int day;
int month;
int year;
};
struct Person {
char name[50];
int age;
struct Date birthdate;
};
int main() {
struct Person person1;
person1.age = 30;
person1.birthdate.day = 15;
person1.birthdate.month = 6;
person1.birthdate.year = 1990;
snprintf(person1.name, sizeof(person1.name), "John Doe");
printf("Name: %s, Age: %d, Birthdate: %02d/%02d/%04dn", person1.name, person1.age, person1.birthdate.day, person1.birthdate.month, person1.birthdate.year);
return 0;
}
四、文件操作
4.1 读写文件
文件操作是将数据存储在外部文件中的一种方法,这使得数据可以在程序执行结束后仍然保留。C语言提供了多种文件操作函数,如 fopen
、fclose
、fread
、fwrite
、fprintf
、fscanf
等。
#include <stdio.h>
int main() {
FILE *file = fopen("data.txt", "w");
if (file != NULL) {
fprintf(file, "Hello, World!n");
fclose(file);
}
file = fopen("data.txt", "r");
if (file != NULL) {
char line[100];
while (fgets(line, sizeof(line), file)) {
printf("%s", line);
}
fclose(file);
}
return 0;
}
4.2 二进制文件操作
除了文本文件,C语言还支持二进制文件操作。使用 fread
和 fwrite
函数可以读写二进制数据。
#include <stdio.h>
int main() {
FILE *file = fopen("data.bin", "wb");
if (file != NULL) {
int data = 12345;
fwrite(&data, sizeof(int), 1, file);
fclose(file);
}
file = fopen("data.bin", "rb");
if (file != NULL) {
int data;
fread(&data, sizeof(int), 1, file);
printf("Read data: %dn", data);
fclose(file);
}
return 0;
}
五、指针
5.1 指针基础
指针是C语言中非常重要的概念。它们用于存储变量的内存地址。指针不仅能用于动态内存分配,还能用于实现复杂的数据结构,如链表、树、图等。
#include <stdio.h>
int main() {
int a = 10;
int *p = &a;
printf("Value of a: %dn", a);
printf("Address of a: %pn", &a);
printf("Value of p: %pn", p);
printf("Value pointed by p: %dn", *p);
return 0;
}
5.2 动态内存分配
动态内存分配允许程序在运行时动态地分配和释放内存。C语言提供了 malloc
、calloc
、realloc
和 free
函数来进行动态内存管理。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int size = 5;
arr = (int*)malloc(size * sizeof(int));
if (arr == NULL) {
fprintf(stderr, "Memory allocation failedn");
return 1;
}
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("n");
free(arr);
return 0;
}
5.3 指针数组和多级指针
指针数组和多级指针是指针的高级用法。指针数组是存储指针的数组,而多级指针是指向指针的指针。
#include <stdio.h>
int main() {
int a = 10, b = 20, c = 30;
int *arr[3] = {&a, &b, &c};
for (int i = 0; i < 3; i++) {
printf("Value of arr[%d]: %dn", i, *arr[i]);
}
int pp = &arr[0];
printf("Value pointed by pp: %dn", pp);
return 0;
}
六、链表
6.1 单链表
链表是一种动态数据结构,由节点构成,每个节点包含数据和指向下一个节点的指针。单链表是最基本的链表形式。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
void printList(struct Node *n) {
while (n != NULL) {
printf("%d ", n->data);
n = n->next;
}
printf("n");
}
int main() {
struct Node *head = NULL;
struct Node *second = NULL;
struct Node *third = NULL;
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
head->data = 1;
head->next = second;
second->data = 2;
second->next = third;
third->data = 3;
third->next = NULL;
printList(head);
free(head);
free(second);
free(third);
return 0;
}
6.2 双链表
双链表每个节点包含两个指针,一个指向前驱节点,一个指向后继节点。这样可以更方便地在链表中进行插入和删除操作。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
struct Node *prev;
};
void printList(struct Node *n) {
while (n != NULL) {
printf("%d ", n->data);
n = n->next;
}
printf("n");
}
int main() {
struct Node *head = NULL;
struct Node *second = NULL;
struct Node *third = NULL;
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
head->data = 1;
head->next = second;
head->prev = NULL;
second->data = 2;
second->next = third;
second->prev = head;
third->data = 3;
third->next = NULL;
third->prev = second;
printList(head);
free(head);
free(second);
free(third);
return 0;
}
七、栈和队列
7.1 栈
栈是一种后进先出(LIFO)的数据结构。在C语言中,可以使用数组或链表实现栈。
#include <stdio.h>
#include <stdlib.h>
struct StackNode {
int data;
struct StackNode *next;
};
struct StackNode* newNode(int data) {
struct StackNode* stackNode = (struct StackNode*)malloc(sizeof(struct StackNode));
stackNode->data = data;
stackNode->next = NULL;
return stackNode;
}
int isEmpty(struct StackNode *root) {
return !root;
}
void push(struct StackNode root, int data) {
struct StackNode* stackNode = newNode(data);
stackNode->next = *root;
*root = stackNode;
printf("%d pushed to stackn", data);
}
int pop(struct StackNode root) {
if (isEmpty(*root))
return -1;
struct StackNode* temp = *root;
*root = (*root)->next;
int popped = temp->data;
free(temp);
return popped;
}
int main() {
struct StackNode* root = NULL;
push(&root, 10);
push(&root, 20);
push(&root, 30);
printf("%d popped from stackn", pop(&root));
printf("%d popped from stackn", pop(&root));
return 0;
}
7.2 队列
队列是一种先进先出(FIFO)的数据结构。在C语言中,可以使用数组或链表实现队列。
#include <stdio.h>
#include <stdlib.h>
struct QNode {
int data;
struct QNode* next;
};
struct Queue {
struct QNode *front, *rear;
};
struct QNode* newNode(int data) {
struct QNode* temp = (struct QNode*)malloc(sizeof(struct QNode));
temp->data = data;
temp->next = NULL;
return temp;
}
struct Queue* createQueue() {
struct Queue* q = (struct Queue*)malloc(sizeof(struct Queue));
q->front = q->rear = NULL;
return q;
}
void enQueue(struct Queue* q, int data) {
struct QNode* temp = newNode(data);
if (q->rear == NULL) {
q->front = q->rear = temp;
return;
}
q->rear->next = temp;
q->rear = temp;
}
int deQueue(struct Queue* q) {
if (q->front == NULL)
return -1;
struct QNode* temp = q->front;
q->front = q->front->next;
if (q->front == NULL)
q->rear = NULL;
int data = temp->data;
free(temp);
return data;
}
int main() {
struct Queue* q = createQueue();
enQueue(q, 10);
enQueue(q, 20);
enQueue(q, 30);
printf("%d dequeued from queuen", deQueue(q));
printf("%d dequeued from queuen", deQueue(q));
return 0;
}
八、树和图
8.1 二叉树
二叉树是一种每个节点最多有两个子节点的数据结构。在C语言中,可以使用结构体和指针来实现二叉树。
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
struct Node* newNode(int data) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
void inorderTraversal(struct Node* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d ", root->data);
inorderTraversal(root->right);
}
}
int main() {
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
printf("Inorder traversal: ");
inorderTraversal(root);
printf("n");
return 0;
}
8.2 图
图是一种由节点和边构成的数据结构。在C语言中,可以使用邻接矩阵或邻接表来表示图。
#include <stdio.h>
#include <stdlib.h>
struct AdjListNode {
int dest;
struct AdjListNode* next;
};
struct AdjList {
struct AdjListNode *head;
};
struct Graph {
int V;
struct AdjList* array;
};
struct AdjListNode* newAdjListNode(int dest) {
struct AdjListNode* newNode = (struct AdjListNode*)malloc(sizeof(struct AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
struct Graph* createGraph(int V) {
struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
graph->V = V;
graph->array = (struct AdjList*)malloc(V * sizeof(struct AdjList));
for (int i = 0; i < V; ++i)
graph->array[i].head = NULL;
return graph;
}
void addEdge(struct Graph* graph, int src, int dest) {
struct AdjListNode* newNode = newAdjListNode(dest);
newNode->next = graph->array[src].head;
graph->array[src].head = newNode;
newNode = newAdjListNode(src);
newNode->next = graph->array[dest].head;
graph->array[dest].head = newNode;
}
void printGraph(struct Graph* graph) {
for (int v = 0; v < graph->V; ++v) {
struct AdjListNode* pCrawl = graph->array[v].head;
printf("n Adjacency list of vertex %dn head ", v);
while (pCrawl) {
printf("-> %d", pCrawl->dest);
pCrawl = pCrawl->next;
}
printf("n");
}
}
int main() {
int V = 5;
struct Graph* graph = createGraph(V);
addEdge(graph, 0, 1);
addEdge(graph, 0, 4);
addEdge(graph, 1, 2);
addEdge(graph, 1, 3);
addEdge(graph, 1, 4);
addEdge(graph, 2, 3);
addEdge(graph, 3, 4);
printGraph(graph);
return 0;
}
九、动态内存管理
9.1 malloc
和 free
malloc
函数用于在堆中分配指定字节数的内存,并返回一个指向该内存的指针。free
函数用于释放先前分配的内存。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) {
fprintf(stderr, "Memory allocation failedn");
return 1;
}
for (int i = 0; i < 5; i++) {
ptr[i] = i + 1;
}
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("n");
free
相关问答FAQs:
1. 如何在C语言中将数据存储到文件中?
在C语言中,可以使用标准库函数中的fopen
函数打开一个文件,并使用fprintf
函数将数据写入文件。首先,使用fopen
函数打开一个文件,并指定文件的路径和打开方式(如w
表示写入模式)。然后,使用fprintf
函数将数据写入文件,格式类似于fprintf(file, "%s", data)
,其中file
为文件指针,data
为要写入的数据。最后,使用fclose
函数关闭文件。
2. 如何在C语言中将数据存储到数组中?
在C语言中,可以使用数组来存储数据。首先,定义一个合适大小的数组来存储数据,例如int data[10]
表示定义一个可以存储10个整数的数组。然后,使用循环结构(如for
循环)来逐个输入或赋值数据到数组中。例如,可以使用scanf
函数从用户输入中获取数据,然后使用data[i] = input_data
将数据存储到数组的第i
个位置。最后,可以使用循环遍历数组并输出数据。
3. 如何在C语言中将数据存储到数据库中?
在C语言中,可以通过数据库操作库(如MySQL Connector/C或SQLite)来将数据存储到数据库中。首先,需要安装和配置相应的数据库操作库。然后,使用库提供的函数来连接数据库、创建表格和插入数据。例如,可以使用库提供的函数来连接到数据库,然后使用SQL语句来创建表格(如CREATE TABLE
),接着使用插入语句(如INSERT INTO
)将数据插入到表格中。最后,关闭数据库连接并释放资源。
原创文章,作者:Edit2,如若转载,请注明出处:https://docs.pingcode.com/baike/1308323