C语言-实验8-指针
本系列将以一个学习者的眼光,从零基础一步一步学会最基础的C语言编程,本文将讲解C语言第八个板块:指针。
指针是C语言的灵魂,也是初学者最容易困惑的知识点。简单来说,指针就是“指向内存地址的变量”,掌握指针能让你更灵活地操作内存、提升程序效率。这篇博客会从零基础视角,用通俗的比喻和可直接运行的示例代码,帮你彻底理解指针的核心概念和用法。
指针的认识
你可以把内存想象成一排有编号的储物柜,每个储物柜都有唯一的编号(内存地址),里面可以存放物品(数据)。指针变量:就像你手里拿着一张纸条,上面写着储物柜的编号(007),关注的是柜子的地址,通过这个编号能快速找到并操作柜子里的东西。
在C语言中,函数的核心价值:
- 高效访问数组、字符串
- 实现函数的“传址调用”,修改主调函数的变量
- 动态分配内存(后续进阶内容)
- 简化复杂数据结构(如链表、树)的操作
指针的定义
1.指针变量的定义
数据类型 *指针变量名;数据类型:指针指向的变量的类型(如int、char、float)*:表示这是一个指针变量指针变量名:符合C语言命名规则的名称
2.关键运算符
&(取地址符):获取变量的内存地址*(解引用符):通过指针地址访问/修改对应内存的值
示例
1.指针的基础使用
#include <stdio.h>
int main() { int num = 100; int *p; p = # printf("变量num的值:%d\n", num); printf("变量num的地址:%p\n", &num); printf("指针p存储的地址:%p\n", p); printf("通过指针p访问num的值:%d\n", *p); *p = 200; printf("修改后num的值:%d\n", num); return 0;}输出:
变量num的值:100变量num的地址:0x7ffeefbff5c4指针p存储的地址:0x7ffeefbff5c4通过指针p访问num的值:100修改后num的值:200
2.指针实现函数传址调用
#include <stdio.h>
void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp;}
int main() { int x = 5, y = 10; printf("交换前:x=%d, y=%d\n", x, y); swap(&x, &y); printf("交换后:x=%d, y=%d\n", x, y); return 0;}输出:
交换前:x=5, y=10交换后:x=10, y=5
3.指针操作数组
#include <stdio.h>
int main() { int arr[5] = {10, 20, 30, 40, 50}; int *p = arr; printf("通过指针遍历数组:"); for (int i = 0; i < 5; i++) { printf("%d ", *(p + i)); } printf("\n"); *p = 100; *(p + 2) = 300; printf("修改后数组:"); for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } return 0;}输出:
通过指针遍历数组:10 20 30 40 50修改后数组:100 20 300 40 50
应用
6-1 sdut-C语言- n个数的排序
Qiao当上了体育委员,现在老师让他去给班级里的人排队,Qiao刚学了排序,所以他想以这种方式给班级里的人排队(从矮到高),他想知道排序完成后的结果。
函数接口定义:
void sort(int *p,int n);其中 p 和 n 都是用户传入的参数。 p 的值为传递过来的地址; n 的为正整数(1<=n<=100)。函数不需要返回数据。
裁判测试程序样例:
#include <stdio.h>void sort(int *p,int n);int main(){int a[100];int n,i;int *p1;while(scanf("%d",&n)!=EOF){for(p1=a; p1<a+n; p1++)scanf("%d",p1);sort(a,n);for(i=0; i<n-1; i++)printf("%d ",a[i]);printf("%d\n",a[n-1]);}return 0;}/* 请在这里填写答案 */输入示例:
多组输入,每组的第一行是一个正数n(1<=n<=100),第二行是n个数,表示每一个人的高度。比如:
3176 175 174输出示例:
174 175 176
6-1 解答:
void sort(int *p, int n) { int i, j; int temp; for (i = 0; i < n - 1; i++) { for (j = 0; j < n - 1 - i; j++) { if (*(p + j) > *(p + j + 1)) { temp = *(p + j); *(p + j) = *(p + j + 1); *(p + j + 1) = temp; } } }}6-2 sdut- C语言实验——矩阵下三角元素之和
输入一个正整数n(1<=n<=10),再输入n*n的矩阵,要求求该矩阵的下三角元素之和。
函数接口定义:
int f(int (*p)[10],int n);其中 p 和 n 都是用户传入的参数。 p 的值为地址; n 是[1, 10]区间内的个位数。函数需要返回求和后的数据。
裁判测试程序样例:
#include<stdio.h>int f(int (*p)[10],int n);int main(){int n,i,j,sum;int a[10][10];scanf("%d",&n);for(i=0; i<n; i++){for(j=0; j<n; j++){scanf("%d",&a[i][j]);}}sum=f(a,n);printf("%d",sum);return 0;}/* 请在这里填写答案 */输出示例:
51 2 3 4 52 3 4 5 63 4 5 6 74 5 6 7 85 6 7 8 9输入示例:
75
6-2 解答:
int f(int (*p)[10],int n){ int result = 0; for(int k=0;k<n;k++){ for(int l=0;l<n;l++){ if(k>=l){ result += p[k][l]; } } } return result;}6-3 在数组中查找指定元素
本题要求实现一个在数组中查找指定元素的简单函数。
函数接口定义:
long long int f(long long int n);int search( int list[], int n, int x );
裁判测试程序样例:
#include <stdio.h>#define MAXN 10int search( int list[], int n, int x );int main(){int i, index, n, x;int a[MAXN];scanf("%d", &n);for( i = 0; i < n; i++ )scanf("%d", &a[i]);scanf("%d", &x);index = search( a, n, x );if( index != -1 )printf("index = %d\n", index);elseprintf("Not found\n");return 0;}/* 你的代码将被嵌在这里 */输入示例1:
51 2 2 5 42输出示例1:
index = 1输入示例2:
51 2 2 5 40输出示例1:
Not found
6-3 解答:
int search(int list[], int n, int x) { for (int i = 0; i < n; i++) { if (list[i] == x) { return i; } } return -1;}6-4 sdut-C语言实验 - 杨辉三角
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
上面的图形熟悉吗?它就是我们中学时候学过的杨辉三角。 输入数据包含多组测试数据。每组测试数据的输入只有一个正整数n(1≤n≤30),表示将要输出的杨辉三角的层数。输入以0结束。 对应于每一个输入,请输出相应层数的杨辉三角,每一层的整数之间用一个空格隔开,每一个杨辉三角后面加一个空行。
函数接口定义:
void yh_tri(int (*a)[30],int n);void yh_output(int (*a)[30],int n);例如:其中 a 和 n 都是用户传入的参数。 a 的值为二维数组的首地址; n 是[1, 30]区间内的个位数。函数无返回。
裁判测试程序样例:
include <stdio.h>oid yh_tri(int (*a)[30],int n);oid yh_output(int (*a)[30],int n);nt main()int a[30][30],n;while(~scanf("%d",&n)&&n){yh_tri(a,n);yh_output(a,n);}return 0;* 请在这里填写答案 */输入示例:
230输出示例:
11 111 11 2 1
6-4 解答:
void yh_tri(int (*a)[30], int n) { int i, j; for (i = 0; i < n; i++) { a[i][0] = 1; a[i][i] = 1; for (j = 1; j < i; j++) { a[i][j] = a[i-1][j-1] + a[i-1][j]; } }}
void yh_output(int (*a)[30], int n) { int i, j; for (i = 0; i < n; i++) { for (j = 0; j <= i; j++) { if (j == i) { printf("%d\n", a[i][j]); } else { printf("%d ", a[i][j]); } } }}7-1 利用指针返回多个函数值
读入n个整数,调用max_min()函数求这n个数中的最大值和最小值。
输入格式:输入有两行:
第一行是n值;
第二行是n个数。
输出格式:输出最大值和最小值。
输入示例:
58 9 12 0 3输出示例:
max = 12min = 0
7-1 解答:
#include <stdio.h>
void max_min(int *arr, int n, int *max, int *min);
int main() { int n; scanf("%d", &n); int numbers[1000]; for (int i = 0; i < n; i++) { scanf("%d", &numbers[i]); } int max_val, min_val; max_min(numbers, n, &max_val, &min_val); printf("max = %d\nmin = %d\n", max_val, min_val); return 0;}
void max_min(int *arr, int n, int *max, int *min) { *max = arr[0]; *min = arr[0]; for (int i = 1; i < n; i++) { if (arr[i] > *max) { *max = arr[i]; } if (arr[i] < *min) { *min = arr[i]; } }}7-2 逆置一维数组
编写程序,以指针的方式,就地逆置一维数组。
输入格式:首先输入一个正整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据先输入数据个数n,然后输入n个整数。
输出格式:对于每组测试,在一行上输出逆置之后的结果。数据之间以一个空格分隔。
输入示例:
24 1 2 5 35 4 3 5 1 2输出示例:
3 5 2 12 1 5 3 4
7-2 解答:
#include <stdio.h>
void reverse(int *arr, int n);
int main() { int T; scanf("%d", &T); while (T--) { int n; scanf("%d", &n); int arr[1000]; for (int i = 0; i < n; i++) { scanf("%d", &arr[i]); } reverse(arr, n); for (int i = 0; i < n; i++) { if (i > 0) { printf(" "); } printf("%d", arr[i]); } printf("\n"); } return 0;}
void reverse(int *arr, int n){ int *left = arr; int *right = arr + n - 1; while (left < right) { int temp = *left; *left = *right; *right = temp; left++; right--; }}7-3 两数的互换
从键盘任意输入两个整数,用指针作函数参数,编程实现将其交换后再重新输出。
函数接口:
void swap(int *x, int *y)输入格式:从键盘输入两个整数。
输出格式:按输出样例的形式输出交换后的两个整数。
输入示例:
11 22输出示例:
After swap:22,11
7-3 解答:
#include <stdio.h>
void swap(int *x,int *y);
int main(){ int a,b; scanf("%d %d",&a,&b); swap(&a,&b); printf("After swap:%d,%d",a,b); return 0;}
void swap(int *x,int *y){ int temp = *x; *x = *y; *y = temp;}7-4 sdut-C语言实验-虎子的难题
稷下英才实验班有个同学叫虎子,有一天虎子刷到了一道编程题:给M(M<=100)组数据,每组数据有N个正整数(N<=100),要求把每组的N个数按升序排成一行。虎子觉得应该用指针和函数实现比较高效,但总是调试不出来,你能帮帮他吗?
输入格式:输入包括M+1行,第一行是两个正整数M、N;M表示总共多少组数据,下面M行每行包含N个正整数。(输入数据之间会用空格隔开)
输出格式:输出包括M行,每行分别对应输入中M组数据的升序序列,数与数之间用一个空格隔开。
输入示例:
2 31 3 24 2 6输出示例:
1 2 32 4 6
7-4 解答:
#include <stdio.h>
void sort(int *arr, int n);void printArray(int *arr, int n);
int main() { int M, N; scanf("%d %d", &M, &N); for (int i = 0; i < M; i++) { int arr[100]; for (int j = 0; j < N; j++) { scanf("%d", &arr[j]); } sort(arr, N); printArray(arr, N); } return 0;}
void sort(int *arr, int n){ for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (*(arr + j) > *(arr + j + 1)) { int temp = *(arr + j); *(arr + j) = *(arr + j + 1); *(arr + j + 1) = temp; } } }}
void printArray(int *arr, int n){ for (int i = 0; i < n; i++) { if (i > 0) { printf(" "); } printf("%d", *(arr + i)); } printf("\n");}总结
OK了,今天你学会了C语言程序的指针、函数中的指针、数组的指针及其相关知识点!一起加油吧!
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!