资料类型
简单来说,数据类型为我们提供了有关数据类型的信息。
例如,整数,字符等。
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
结构体
我们使用原始数据类型来存储数据。但是,如果我们要存储的数据更复杂怎么办?
让我们考虑一个例子,我们想将一个班级中学生的信息存储在一个变量中。因此,一个学生有:
- 卷号
- 名称
在此,卷号是整数类型,名称是字符串(字符数组)类型。
解决方法是:结构
- 结构是以单个名称表示的变量(可以是不同的数据类型)的集合。
- 它也是一个类似数组的连续内存段,但是它允许不同数据类型的数据成员。
定义结构的语法:
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 = #
为了获得指针所指向的地址的值,我们使用asterisk(*)运算符。
因此,在上面的示例中,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()等是预定义的函数。
用户定义的功能
- 这些是函数,由程序员定义为在程序中执行某些任务。
- 将复杂的问题分成较小的块可以使我们的程序易于理解。
要使用用户定义的函数,我们必须执行两个步骤
- 定义函数
- 通话函数
函数定义的语法:
return_type function_name()
{
--tasks/operations--
return return_value;
}
笔记:
- 一个函数可以具有0个或多个参数。
- 一个函数可以有0或1个返回值。
- 不返回任何内容的函数的返回类型为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。然后,将函数x接收到的变量的值增加了1。因此,x的值现在为6。但是,此更改是有限的仅函数范围。 in main的值仍为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变量。
float x = (float)7/5;
要了解有关类型转换的更多信息,请参阅《 C语言中的类型转换》。
动态内存分配
如您所知,数组是固定数量的值的集合。声明数组的大小后,您将无法更改它。
有时,您声明的数组大小可能不足。要解决此问题,可以在运行时动态分配内存。这称为动态内存分配。
动态内存分配中使用的预定义函数:
1. malloc()
- malloc代表内存分配。
- malloc()函数保留指定数量的字节和void *的内存块,可以将其转换为任何形式的指针。
malloc()的语法:
pointer_name = (cast_datatype*)malloc(size);
2. free()
- 使用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语言中的动态内存分配。