📜  用作数据结构的 C 编程概念是什么

📅  最后修改于: 2021-09-06 05:35:17             🧑  作者: Mango

数据类型

简单来说,数据类型为我们提供了有关数据类型的信息。
例如,整数、字符等。
C 语言中的数据类型是变量的声明。数据类型分为:

原始或内置数据类型

一些原始数据类型的例子如下

名为ch 的变量指的是内存地址 100,已占用 1 个字节的内存,其中保存了 char 数据类型 ‘A’ 的值。

num是指内存地址 200 的整数类型,已占用 4 个字节的内存,并保存值 123456。

标记是双精度型,指的是内存位置300,已经占用了8个字节的内存,保存的值为97.123456。

注意:这些地址(100、200 和 300)仅用于理解目的,实际地址是大的十六进制数。

数组

数组是可以存储相同数据类型的多个值的变量。数组是一个连续的内存段。

例子:

如果要存储 100 个整数,可以使用一个数组而不是使用 100 个不同的整数变量。

数组声明的语法:

data_type   array_name[array_size];

分配的空间量 = sizeof(data_type) * array_size

例子:
声明一个可以容纳 4 个整数值的数组

int arr[4];

在这种情况下,sizeof(int) = 4。因此,为数组保留了 4*4 = 16字节的内存。

数组声明和初始化示例:

int arr[5] = {10, 20, 30, 40, 50};

可以使用索引访问数组元素,索引范围从 0 到 (array_size-1)。

下面是在 C 中使用数组的示例代码:

C
// C implementation to demonstrate
// the usage of arrays
  
#include 
  
int main()
{
    // Array Indexs-0   1   2   3   4
    int arr[5] = { 10, 20, 30, 40, 50 };
  
    int size = sizeof(arr);
  
    printf("Size of array is %d\n", size);
  
    printf("Data at index 2 is %d\n", arr[2]);
}


C
// C implementation to demonstrate
// the usage of structures
  
#include 
#include 
  
// Structure Defination
struct student {
    // data members
    int roll_no; // 4 bytes
    char name[20]; // 20 bytes
};
  
int main()
{
    // Stucture variable Declaration
    struct student stu;
  
    stu.roll_no = 64;
    strcpy(stu.name, "Saurabh");
  
    printf("Structure Data\n");
    printf("Roll No: %d\n", stu.roll_no);
    printf("Name: %s\n", stu.name);
  
    int size = sizeof(stu);
  
    printf("Size of Structure student");
    printf("is %d", size);
}


C
// C implementation to demonstrate
// pointers in C
  
#include 
  
int main()
{
    int* ptr;
    int num = 5;
  
    ptr = #
  
    // This gives address of num
    printf("Value at ptr is %p\n", ptr);
  
    // This gives value at num
    printf("Value at *ptr is %d\n", *ptr);
}


C
// C implementation to illustrate
// the code of the structures
  
#include 
#include 
  
// Structure Defination
struct student {
    int roll_no;
    char name[20];
};
  
int main()
{
    struct student* p;
  
    p = (struct student*)
        malloc(sizeof(struct student));
  
    // Arrow operator
    p->roll_no = 99;
  
    printf("The value at roll");
    printf("number is %d", p->roll_no);
  
    return 0;
}


C
// C implementation to
// illustrate functions in C
  
#include 
  
// program to demonstrate functions
// function defination
// function to print something
  
void print()
{
    printf("GeeksforGeeks\n");
}
  
// Function to add two numbers
int add(int a, int b)
{
    int sum;
    sum = a + b;
    return sum;
}
  
// Main Function
int main()
{
    int res;
  
    // Function call
    print();
  
    res = add(5, 7);
  
    printf("Sum is %d", res);
}


C
// C implementation for the
// function call by passing value
  
#include 
  
// Function pass by value
void increase_by_one(int x)
{
    x++;
}
  
int main()
{
    int num = 5;
  
    printf("Value before function");
    printf(" call %d\n", num);
  
    increase_by_one(num);
  
    printf("Value after function");
    printf(" call %d\n", num);
}


C
// C implementation to demonstrate
// the usage of function call by
// passing reference
  
#include 
  
// function to demonstarte
// call by value
void increase_by_one(int* x)
{
    (*x)++;
}
  
int main()
{
    int num = 5;
  
    printf("Value before function");
    printf(" call %d\n", num);
  
    increase_by_one(&num);
  
    printf("Value after function");
    printf(" call %d\n", num);
}


C
// C implementation to demonstrate
// the example of the passing as
// parameter in the function
  
#include 
  
// Function to print the array
void print_array(int arr[], int n)
{
    // N is size of array
    int i;
  
    for (i = 0; i < n; i++)
        printf("%d ", arr[i]);
}
  
int main()
{
    int arr[5] = { 10, 20, 30, 40, 50 };
  
    // Function Call
    print_array(arr, 5);
}


C
// C implementation to demonstrate
// the code the Dynamic Memory
// Allocation
  
#include 
#include 
  
int main()
{
    int* ptr;
    int n = 5, i;
  
    ptr = (int*)malloc(n * sizeof(int));
  
    for (i = 0; i < n; i++)
        ptr[i] = i;
  
    printf("\nArray Elements are\n");
  
    for (i = 0; i < n; i++)
        printf("%d ", ptr[i]);
  
    free(ptr);
}


输出
Size of array is 20
Data at index 2 is 30

结构

我们已经使用原始数据类型来存储数据。但是如果我们要存储的数据更复杂呢?

让我们考虑一个例子,我们想将班级学生的信息存储在单个变量中。所以,一个学生有:

  • 卷号
  • 名称

这里,Roll number 是整数类型,Name 是字符串(字符数组)类型。

这是解决方案:结构

  • 结构是一个变量的集合(可以是不同的数据类型),在一个名称下。
  • 它也是一个类似数组的连续内存段,但它允许不同数据类型的数据成员。

定义结构的语法:

struct structure_name
{
   datatype member1_name;
   datatype member2_name;
   ..
   datatype membern_name;
};

例子:

struct student
{
   int roll_number;
   char name[20];
};

现在我们有了新定义的数据类型struct student。我们可以创建它的变量。

变量声明的语法:

struct structure_name variable_name;

例子:

struct  student  ram;

// Members of structures can
// be accessed using "." operator
stu.roll_number = 64;
stu.name = “Saurabh”;

当我们定义一个结构时,没有分配内存。

结构的大小等于每个数据成员消耗的空间总量。

例子:

在学生结构的情况下,它是 4 + 20 = 24 个字节

下面是借助代码对结构的说明:

C

// C implementation to demonstrate
// the usage of structures
  
#include 
#include 
  
// Structure Defination
struct student {
    // data members
    int roll_no; // 4 bytes
    char name[20]; // 20 bytes
};
  
int main()
{
    // Stucture variable Declaration
    struct student stu;
  
    stu.roll_no = 64;
    strcpy(stu.name, "Saurabh");
  
    printf("Structure Data\n");
    printf("Roll No: %d\n", stu.roll_no);
    printf("Name: %s\n", stu.name);
  
    int size = sizeof(stu);
  
    printf("Size of Structure student");
    printf("is %d", size);
}
输出
Structure Data
Roll No: 64
Name: Saurabh
Size of Structure studentis 24

指针

  • 指针是一种特殊类型的变量,用于存储地址,而不是变量的值。
  • 它们用于间接访问变量。
  • 如果VAR是变量的名字,然后和VAR给出了VAR的地址。

记住了 scanf函数使用的&符号(&)

scanf(“%d”, &var);

这是因为我们将扫描的值分配给var的内存位置。

我们对地址不感兴趣,但对存储在该地址的值感兴趣。

指针声明的语法:

data_type* pointer_name; // (* = asterisk)          

例子:

int* ptr;

指针可以指向任何数据类型
它可以保存它指向的数据类型的任何变量的地址。
未初始化的指针变量具有 NULL 值。

例子:

int* ptr;
int num = 5;
ptr = #

要获取指针所指向的地址处的值,我们使用星号(*)运算符。

因此,在上面的示例中,ptr 保存地址 250,地址处的值为 5。

因此,*ptr 等于 5。

下面是借助代码对指针的说明:

C

// C implementation to demonstrate
// pointers in C
  
#include 
  
int main()
{
    int* ptr;
    int num = 5;
  
    ptr = #
  
    // This gives address of num
    printf("Value at ptr is %p\n", ptr);
  
    // This gives value at num
    printf("Value at *ptr is %d\n", *ptr);
}
输出
Value at ptr is 0x7ffdff4dca9c
Value at *ptr is 5

指针变量的大小在系统中始终不变,无论它指向的数据类型如何,通常为 8 个字节。

指向结构的指针

  • 指向结构的指针可以声明为普通变量。

例子:

struct student *p;

这里, p是指针, *p是结构

因此,要访问数据成员,我们必须使用

(*p).roll_no
(*p).name

C 提供了一个特殊的运算符,用于通过指针访问数据成员,即 -> 箭头运算符。

注意: (*p).x 等价于 p->x

下面是指向结构的指针的说明:

C

// C implementation to illustrate
// the code of the structures
  
#include 
#include 
  
// Structure Defination
struct student {
    int roll_no;
    char name[20];
};
  
int main()
{
    struct student* p;
  
    p = (struct student*)
        malloc(sizeof(struct student));
  
    // Arrow operator
    p->roll_no = 99;
  
    printf("The value at roll");
    printf("number is %d", p->roll_no);
  
    return 0;
}
输出
The value at rollnumber is 99

职能

  • 函数是执行特定任务的代码块。
  • 一个函数可能有一个输入,执行这样的任务,然后可能提供一些输出。

在上面的示例中,我们将输入作为 2 个数字提供给函数。它正在执行加法函数。然后,它返回两个输入数字的总和。

  • 调用的输入是函数的参数
  • 输出称为返回值

函数可以分为两类:

内置或预定义功能

这些是在 C 语言标准库中定义的。我们不必定义这些函数,只需调用这些函数即可。我们只需要知道正确的语法,就可以轻松使用这些函数。

例子:

printf()、scanf()、main()等是预定义的函数。

用户定义函数

  • 这些是函数,由程序员定义来执行程序中的某些任务。
  • 将复杂的问题分成更小的块使我们的程序易于理解。

要使用用户定义的函数,我们必须执行两个步骤

  1. 定义函数
  2. 调用函数

函数定义的语法:

return_type  function_name()
{
   --tasks/operations--
   return return_value;
}

笔记:

  1. 一个函数可以有 0 个或多个参数。
  2. 一个函数可以有 0 或 1 个返回值。
  3. 不返回任何内容的函数的返回类型为void。

下面是 C 中函数的说明:

C

// C implementation to
// illustrate functions in C
  
#include 
  
// program to demonstrate functions
// function defination
// function to print something
  
void print()
{
    printf("GeeksforGeeks\n");
}
  
// Function to add two numbers
int add(int a, int b)
{
    int sum;
    sum = a + b;
    return sum;
}
  
// Main Function
int main()
{
    int res;
  
    // Function call
    print();
  
    res = add(5, 7);
  
    printf("Sum is %d", res);
}
输出
GeeksforGeeks
Sum is 12

注意:在函数调用中传递的类型应该与函数体作为参数接收到的类型兼容。否则会导致编译错误。

基于调用类型的函数分类:

通过传值调用函数

  • 当我们通过传递值调用函数(如上面的程序),原始变量的值不受影响。
  • 它不是发送原始变量,而是发送变量的副本。

下面是通过在 C 中传递值来调用函数的说明:

C

// C implementation for the
// function call by passing value
  
#include 
  
// Function pass by value
void increase_by_one(int x)
{
    x++;
}
  
int main()
{
    int num = 5;
  
    printf("Value before function");
    printf(" call %d\n", num);
  
    increase_by_one(num);
  
    printf("Value after function");
    printf(" call %d\n", num);
}
输出
Value before function call 5
Value after function call 5

在这个程序中,我们将变量 a 传递给了函数,它的值是 5。然后,我们将函数接收的变量的值增加了 1。所以,现在 x 的值是 6。但是,这种变化是有限的仅函数范围。 main 中 a 的值仍为 5。

通过地址调用函数

  • 如果我们想改变传递的变量的值,我们必须通过地址传递变量。
  • 此方法使用相同的变量而不是创建其新副本。

下面是通过地址调用函数的代码:

C

// C implementation to demonstrate
// the usage of function call by
// passing reference
  
#include 
  
// function to demonstarte
// call by value
void increase_by_one(int* x)
{
    (*x)++;
}
  
int main()
{
    int num = 5;
  
    printf("Value before function");
    printf(" call %d\n", num);
  
    increase_by_one(&num);
  
    printf("Value after function");
    printf(" call %d\n", num);
}
输出
Value before function call 5
Value after function call 6

当我们传递变量的地址时,我们必须将其作为指针变量接收。

函数:将数组作为参数传递

C

// C implementation to demonstrate
// the example of the passing as
// parameter in the function
  
#include 
  
// Function to print the array
void print_array(int arr[], int n)
{
    // N is size of array
    int i;
  
    for (i = 0; i < n; i++)
        printf("%d ", arr[i]);
}
  
int main()
{
    int arr[5] = { 10, 20, 30, 40, 50 };
  
    // Function Call
    print_array(arr, 5);
}
输出
10 20 30 40 50 

类型转换

类型转换基本上是将一种数据类型转换为另一种数据类型。

类型转换的语法:

var2 = (datatype2) var1
where,  
var1 is of datatype1 & var2 is of datatype2

例子:

如果要将整数变量的值转换为浮点变量。

float x = (float)7/5;

要了解有关类型转换的更多信息,请参阅 C 中的类型转换

动态内存分配

如您所知,数组是固定数量值的集合。一旦声明了数组的大小,就不能更改它。

有时,您声明的数组大小可能不够。为了解决这个问题,你可以在运行时动态分配内存。这称为动态内存分配。

动态内存分配中使用的预定义函数:

1. malloc()

  • malloc 代表内存分配。
  • malloc()函数保留指定字节数和 void* 的内存块,可以将其转换为任何形式的指针。

malloc() 的语法:

pointer_name = (cast_datatype*)malloc(size);

2.免费()

  • 使用 malloc() 动态分配的内存不会自行释放。您必须明确使用 free() 来释放此空间。

免费的语法:

free(pointer_name);

注意:这些函数在头文件 stdlib.h 中声明。要使用这些函数,您必须首先包含此标头。

下面是 C 中动态内存分配的说明:

C

// C implementation to demonstrate
// the code the Dynamic Memory
// Allocation
  
#include 
#include 
  
int main()
{
    int* ptr;
    int n = 5, i;
  
    ptr = (int*)malloc(n * sizeof(int));
  
    for (i = 0; i < n; i++)
        ptr[i] = i;
  
    printf("\nArray Elements are\n");
  
    for (i = 0; i < n; i++)
        printf("%d ", ptr[i]);
  
    free(ptr);
}
输出
Array Elements are
0 1 2 3 4 

要了解有关动态内存分配的更多信息,请参阅 C 中的动态内存分配

想要从精选的视频和练习题中学习,请查看C 基础到高级C 基础课程