正文
1、什么是地址?
C语言中,地址是指内存中数据存储位置的唯一标识。每个数据在内存中都有一个唯一的地址,可以通过该地址来访问和操作数据。了解地址的概念对于理解指针、数组和函数等在C语言中的应用至关重要。
在C语言中,可以使用取地址运算符&
来获取变量的地址。
例如,对于一个整型变量X,可以通过&X
来获取其地址。这个地址通常以十六进制的形式表示,如0x7fffa91b0a54
。
int num = 0;
scanf(“%d” ,&num);//& 取地址符;
//地址对应的格式控制符: %p 打印的是首地址
int num = 0;
printf(“num 的地址是: %p\n” ,&num);
2、地址在C语言中的应用:
- 指针:指针是一种特殊的变量,它存储了某个数据的地址。
- 通过指针,可以直接访问和操作存储在该地址处的数据。
- 数组:在C语言中,数组名被解释为指向数组第一个元素的指针。
- 通过数组名可以访问数组中的元素,也可以将数组作为指针来使用。
- 函数:在C语言中,函数参数的传递是通过值传递,但如果参数是指针类型,则可以通过地址来传递数据,实现对参数的直接修改。
3、数组
目的:批量定义若干个类型相同的元素;
定义:C语言中,数组是一种用来存储相同类型的多个元素的数据结构。数组提供了一种方便的方式来存储和访问一组相似类型的数据,数组中的元素通过索引来访问,从0开始递增。
格式:
数据类型 变量名[元素个数];(如下例子中的numbers[5])
数据类型: 元素的数据类型;
变量的类型:去掉变量名, 剩下的所有就是该变量的数据类型;
元素个数必须是常量;
#include <stdio.h>
int main() {
// 声明一个包含5个整数的数组
int numbers[5];
// 初始化数组元素的值
numbers[0] = 1;
numbers[1] = 3;
numbers[2] = 5;
numbers[3] = 7;
numbers[4] = 9;
// 访问数组元素并输出
printf("数组中的元素: %d, %d, %d, %d, %d\n", numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]);
return 0;
}
特点:
- 定义若干个类型相同的元素
- 数组的元素地址空间连续
- 数组名是数组的首元素地址, 也是整个数组的首地址;
num -- %p -->地址
&num[0] -- %p -->地址
&num -- %p -->地址
3、查看数组大小
整个数组的大小=元素的数据类型大小*元素个数;
= sizeof (数据类型 [元素个数]);
= sizeof (变量名);
元素个数=整个数组的大小/元素的大小;
4、数组类型
1、整型数组:
int num[5];
for(i=0;i<5;i++)
{
scanf("%d",&num[i]);
}
sizeof(int num[5])//4*5=20
printf("%d\n",num[0]);
2、字符型数组:
char num[5];
for(i=0;i<5;i++)
{
scanf("%c",&num[i]);
}
sizeof(char num[5])//1*5=5 5个字节大小
printf("%c\n",num[0]);
3、浮点型数组:
double num[5];
for(i=0;i<5;i++)
{
scanf("%lf",&num[i]);
}
sizeof(dpuble num[5])//8*5=40
printf("%.lf\n",num[0]);
int--%d char--%c double/float -- %lf/%f
5、字符型数组
字符型数组是一种用来存储字符序列的数据结构,通常用于存储字符串。以下是字符型数组的定义和使用示例:
格式:char buf[32] = {“hello_ ” };
scanf("%s",buf);
变量是一个个字符串组成,末尾是0--‘\0’就是上面的下划线位置
scanf不能接收空格,接受空格只能用gets(),gets()对应的输出格式有puts(),puts()打印时遇到‘\0’时停止。
5.1定义字符型数组:
// 声明并初始化一个包含12个字符的数组
char greeting[12] = "Hello, world!";
// 声明一个包含20个字符的数组
char name[20];
5.2访问和修改字符型数组:
// 访问和输出字符型数组中的元素
printf("打印字符型数组中的每个字符:");
for (int i = 0; i < 12; i++)
{
printf("%c ", greeting[i]);
}
// 修改数组中的元素值
greeting[7] = 'W'; // 修改数组中索引为7的字符为大写的W
5.3将字符型数组作为字符串打印:
// 使用printf函数打印字符型数组作为字符串
printf("使用printf打印字符串:%s\n", greeting);
5.4使用scanf
接收字符型数组的输入:
// 使用scanf接收输入到字符型数组
printf("请输入你的名字:");
scanf("%s", name);
printf("你的名字是:%s\n", name);
字符型数组通常用于存储和操作字符串,可以通过索引来访问和修改数组中的每个字符。对于字符型数组作为字符串的处理,可以使用printf
函数来打印整个字符串,使用scanf
函数来接收输入并存储到字符型数组中。
6、数组的使用
6.1声明和初始化数组:
// 初始化为0,部分初始化
int numbers[5] = {0};
// 完全初始化,
int numbers[] = {1, 2, 3, 4, 5};
6.2访问数组元素:
// 访问数组元素并输出
for (int i = 0; i < 5; i++) {
printf("数组中第 %d 个元素的值是 %d\n", i, numbers[i]);
}
6.3修改数组元素:
// 修改数组中的元素值
numbers[2] = 10;
6.4使用指针访问数组元素:
int *ptr = numbers; // 将指针指向数组第一个元素的地址
for (int i = 0; i < 5; i++) {
printf("数组中的元素:%d\n", *(ptr + i));
}
6.5传递数组给函数:
// 定义函数,计算数组中所有元素的和
int calculateSum(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
// 在主函数中调用函数
int total = calculateSum(numbers, 5);
printf("数组中所有元素的和为:%d\n", total);
7、数组的应用--排序算法
排序算法是一种重要的算法,它用于将一组元素按照特定的顺序进行排列。常见的数组排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。以下是对其中一些常用的排序算法的简要介绍:
-
冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法,它重复地遍历要排序的数组,一次比较两个元素,并且如果它们的顺序错误就交换它们。
-
void bubbleSort(int arr[], int n) { for (int i = 0; i < n-1; i++) { for (int j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } }
-
快速排序(Quick Sort): 快速排序是一种分治的排序算法,它通过选择一个基准元素,然后将数组分割为左右两部分,左边的元素都小于基准,右边的元素都大于等于基准,然后递归地对左右两部分进行排序
void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } }
-
归并排序(Merge Sort): 归并排序是一种稳定的排序算法,它采用分治策略,将数组分割成较小的数组,然后进行排序和合并。其核心思想是先通过递归将数组分解成只有一个元素的小数组,然后不断地合并相邻的有序数组。
void mergeSort(int arr[], int l, int r) { if (l < r) { int m = l + (r - l) / 2; mergeSort(arr, l, m); mergeSort(arr, m + 1, r); merge(arr, l, m, r); } }
初入门掌握冒泡排序即可。
预习: strlen、strcpy、 strcat、strcmp
总结
熟练掌握数组在编程中是非常重要的,因为数组是一种常见且重要的数据结构,用于存储和操作一组数据。在声明、访问、修改、初始化、函数传参、算法的应用提高应用能力。