8.1 指针的基本概念
1. 什么是指针
指针是一个变量,它的值是另一个变量的地址。通过指针,我们可以间接地访问和操作内存中的数据。
声明指针变量:
数据类型 *指针变量名;
示例:
#include <stdio.h>
int main() {
int num = 10;
int *ptr = # // 声明一个指针变量ptr,并将其初始化为num的地址
printf("Value of num: %d\n", num);
printf("Address of num: %p\n", (void*)&num);
printf("Value of ptr: %p\n", (void*)ptr);
printf("Value pointed to by ptr: %d\n", *ptr);
return 0;
}
2. 指针的运算
指针可以进行算术运算(如加法、减法),这些运算基于指针所指向的数据类型的大小。
示例:
#include <stdio.h>
int main() {
int arr[3] = {10, 20, 30};
int *ptr = arr; // 数组名作为指针
printf("Value at ptr: %d\n", *ptr); // 10
ptr++; // 指向下一个元素
printf("Value at ptr after increment: %d\n", *ptr); // 20
return 0;
}
8.2 指针与数组
1. 数组名是指针
在C语言中,数组名表示数组的首地址,因此数组名可以用于指针操作。
示例:
#include <stdio.h>
int main() {
int arr[3] = {1, 2, 3};
int *ptr = arr; // 数组名作为指针
printf("First element: %d\n", *ptr);
printf("Second element: %d\n", *(ptr + 1)); // 指向下一个元素
return 0;
}
2. 指针作为数组参数
指针可以用来传递数组给函数,因为数组的实际参数是指向其首元素的指针。
示例:
#include <stdio.h>
void printArray(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("Element %d: %d\n", i, *(arr + i));
}
}
int main() {
int numbers[] = {10, 20, 30, 40};
int size = sizeof(numbers) / sizeof(numbers[0]);
printArray(numbers, size);
return 0;
}
8.3 指针与函数
1. 指针作为函数参数
函数可以接收指针作为参数,从而能够在函数内部修改实际参数的值。
示例:
#include <stdio.h>
void increment(int *x) {
(*x)++; // 修改指针所指向的值
}
int main() {
int num = 5;
increment(&num); // 传递num的地址
printf("Value after increment: %d\n", num);
return 0;
}
2. 函数返回指针
函数可以返回指针,这在动态内存分配时特别有用。
示例:
#include <stdio.h>
#include <stdlib.h> // 包含malloc和free
int* createArray(int size) {
int *arr = (int*)malloc(size * sizeof(int)); // 动态分配内存
for (int i = 0; i < size; i++) {
arr[i] = i + 1; // 初始化数组
}
return arr;
}
int main() {
int size = 5;
int *arr = createArray(size);
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr); // 释放动态分配的内存
return 0;
}
8.4 指针与动态内存分配
1. malloc
和 calloc
malloc
(memory allocation):分配指定字节数的内存块,返回指向该内存块的指针。calloc
(contiguous allocation):分配指定数量的内存块,每块大小相同,并初始化为0。
示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int*)malloc(5 * sizeof(int)); // 使用malloc分配内存
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// 初始化和使用数组
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr); // 释放内存
return 0;
}
2. realloc
和 free
realloc
:调整已分配内存块的大小。free
:释放已分配的内存块。
示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr = (int*)malloc(3 * sizeof(int)); // 分配初始内存
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// 使用数组
for (int i = 0; i < 3; i++) {
arr[i] = i + 1;
}
// 调整内存大小
arr = (int*)realloc(arr, 5 * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed\n");
return 1;
}
for (int i = 3; i < 5; i++) {
arr[i] = i + 1;
}
// 输出新数组内容
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr); // 释放内存
return 0;
}
练习
- 编写一个程序,创建一个动态分配的整数数组,初始化为用户输入的值,并计算其平均值。
- 编写一个函数,使用指针参数交换两个整数的值。
- 编写一个程序,使用
malloc
分配一个字符串数组,并让用户输入每个字符串,最后打印所有字符串。 - 编写一个程序,使用
realloc
动态调整数组的大小,并在扩展后的数组中填充新数据。 - 编写一个函数,接受一个指向浮点数组的指针,并计算数组中所有元素的总和。
完成这些练习后,你将对指针有深入的理解。