非标准答案,部分仅供参考,以运行结果为准
- 实验目的1
- 掌握指针的定义与应用编程;
- 掌握指针作为函数参数的编程方法;
- 熟悉C语言中多文件编程的基本方法。
- 实验任务与要求
- 根据实验内容编写C语言程序;
- 写出各个运程序的行结果并分析;
- 总结C语言中多文件编程和指针作为函数参数的程序设计方法和参数传递过程。
- 实验内容与结果
- 请利用main函数的参数输出:hello world 123参数及参数的个数。
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Arguments: ");
// 遍历命令行参数并输出
for (int i = 1; i < argc; ++i) {
printf("%s ", argv[i]);
}
printf("\n");
printf("Number of arguments: %d\n", argc); // argc 包含程序名
return 0;
}
2.请利用main函数的参数编写程序实现计算器的功能。
如:运行程序及结果如下:
tarena@ubuntu:~/test/d1$ ./t1 5 + 8
5 + 8=13.000000
tarena@ubuntu:~/test/d1$ ./t1 9 / 3
9/3=3.000000
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
// 检查命令行参数是否足够
if (argc != 4) {
printf("Usage: %s <num1> <operator> <num2>\n", argv[0]);
return 1;
}
// 将命令行参数转换为相应的数字和操作符
double num1 = atof(argv[1]);
char operator = argv[2][0];
double num2 = atof(argv[3]);
// 执行相应的操作
switch (operator) {
case '+':
printf("%0.0lf + %0.0lf = %lf\n", num1, num2, num1 + num2);
break;
case '-':
printf("%0.0lf + %0.0lf = %lf\n", num1, num2, num1 - num2);
break;
case '*':
printf("%0.0lf + %0.0lf = %lf\n", num1, num2, num1 * num2);
break;
case '/':
// 避免除以零
if (num2 != 0) {
printf("%0.0lf + %0.0lf = %lf\n", num1, num2, num1 / num2);
} else {
printf("Error: Division by zero!\n");
}
break;
default:
printf("Error: Invalid operator %c\n", operator);
return 1;
}
return 0;
}
3.编程实现如下几种指针变量的定义,并给每个指针变量赋值。
- )定义整型、字符型和double型指针变量pa、pc、pd并对这几个变量进行赋值;
- )定义一个整型数组a[5],并进行赋值,定义一个指针变量pt,使pt指向数组a,利用指针pt输出数组a中的每一个元素的值。
- )定义一个结构体,其成员变量为“学号”、“姓名”、“成绩”,再定义一个该结构体的变量s1及一个该结构体变量的数组s[3],定义两个结构体指针p1和p2,分别指向s1和数组s,利用p1和p2输出结构体变量s1和结构体数组s中的成员变量的值。
- )定义一个字符数组a[5],并将字符串“hello world”存入数组a中,再定义一个指针变量p,p指向数组a,利用指针p输出数组a中的字符串“world”。
#include <stdio.h>
// (1) 定义整型、字符型和double型指针变量pa、pc、pd并对这几个变量进行赋值;
void example1() {
int a = 10;
char c = 'A';
double d = 3.14;
int *pa = &a;
char *pc = &c;
double *pd = &d;
printf("(1) Integer: %d, Character: %c, Double: %.2lf\n", *pa, *pc, *pd);
}
// (2) 定义一个整型数组a[5],并进行赋值,定义一个指针变量pt,使pt指向数组a,利用指针pt输出数组a中的每一个元素的值。
void example2() {
int a[5] = {1, 2, 3, 4, 5};
int *pt = a;
printf("(2) Array Elements: ");
for (int i = 0; i < 5; ++i) {
printf("%d ", *(pt + i));
}
printf("\n");
}
// (3) 定义一个结构体,其成员变量为“学号”、“姓名”、“成绩”,再定义一个该结构体的变量s1及一个该结构体变量的数组s[3],定义两个结构体指针p1和p2,分别指向s1和数组s,利用p1和p2输出结构体变量s1和结构体数组s中的成员变量的值。
struct Student {
int id;
char name[20];
double grade;
};
void example3() {
struct Student s1 = {101, "Alice", 85.5};
struct Student s[3] = {{201, "Bob", 78.3}, {301, "Charlie", 92.0}, {401, "David", 88.7}};
struct Student *p1 = &s1;
struct Student *p2 = s;
printf("(3) Student 1: ID: %d, Name: %s, Grade: %.2lf\n", p1->id, p1->name, p1->grade);
printf(" Student Array:\n");
for (int i = 0; i < 3; ++i) {
printf(" ID: %d, Name: %s, Grade: %.2lf\n", (p2 + i)->id, (p2 + i)->name, (p2 + i)->grade);
}
}
// (4) 定义一个字符数组a[12],并将字符串“hello world”存入数组a中,再定义一个指针变量p,p指向数组a,利用指针p输出数组a中的字符串“world”。
void example4() {
char a[12];
const char *str = "hello world";
char *p = a;
// Copy string to array a
while ((*p++ = *str++)) {}
// Print the substring "world"
printf("(4) Substring: %s\n", a + 6);
}
int main() {
example1();
example2();
example3();
example4();
return 0;
}
4.编写一个程序实现两个整数的交换,要求按下列要求完成任务,并分析每一个swap函数的参数传递方式是传值方式还是传址方式:
- 定义一个函数swap(int x, int y),在函数swap中交换x,y的值,利用传值的参数传递方式调用swap( )函数,观察主调函数main( )中的实参值是否交换,并分别输出main( )函数和swap( )函数中的两个整数值。
- 定义一个函数swap1(int *px, int *py),在swap1中实现交换两个指针px和py,观察主调函数main( )中的实参值是否交换,并分别输出main( )函数和swap( )函数中的两个整数值。
- 定义一个函数swap2(int *px, int *py),在swap1中实现交换两个指针指向的变量的值*px和*py,观察主调函数main( )中的实参值是否交换,并分别输出main( )函数和swap2( )函数中的两个整数值。
#include <stdio.h>
// (1) 定义一个函数swap(int x, int y),在函数swap中交换x,y的值,利用传值的参数传递方式调用swap( )函数
void swap(int x, int y) {
int temp = x;
x = y;
y = temp;
printf("(1) Inside swap function: x = %d, y = %d\n", x, y);
}
// (2) 定义一个函数swap1(int *px, int *py),在swap1中实现交换两个指针px和py
void swap1(int *px, int *py) {
int temp = *px;
*px = *py;
*py = temp;
printf("(2) Inside swap1 function: *px = %d, *py = %d\n", *px, *py);
}
// (3) 定义一个函数swap2(int *px, int *py),在swap1中实现交换两个指针指向的变量的值*px和*py
void swap2(int *px, int *py) {
int temp = *px;
*px = *py;
*py = temp;
printf("(3) Inside swap2 function: *px = %d, *py = %d\n", *px, *py);
}
int main() {
int a = 10, b = 20;
// (1) 传值方式调用swap( )函数
swap(a, b);
printf("(1) After swap function: a = %d, b = %d\n", a, b);
// (2) 传址方式调用swap1( )函数
swap1(&a, &b);
printf("(2) After swap1 function: a = %d, b = %d\n", a, b);
// (3) 传址方式调用swap2( )函数
swap2(&a, &b);
printf("(3) After swap2 function: a = %d, b = %d\n", a, b);
return 0;
}
5.以数组名作为函数参数的程序设计:在main函数中定义一个数组a[5]并利用键盘输入的方式给a[5]中的5个元素赋值,再调用函数sort对a[5]中的5个元素进行排序,将排序后的结果在main函数中输出。
#include <stdio.h>
// 函数声明:以数组名作为参数进行排序
void sort(int arr[], int size);
int main() {
int a[5];
// 从键盘输入给数组a[5]中的5个元素赋值
printf("Enter 5 integers:\n");
for (int i = 0; i < 5; ++i) {
scanf("%d", &a[i]);
}
// 调用sort函数对数组a[5]中的元素进行排序
sort(a, 5);
// 输出排序后的结果
printf("Sorted array: ");
for (int i = 0; i < 5; ++i) {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
// 定义函数sort:以数组名作为参数进行排序
void sort(int arr[], int size) {
// 使用冒泡排序算法对数组进行升序排序
for (int i = 0; i < size - 1; ++i) {
for (int j = 0; j < size - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
// 交换arr[j]和arr[j + 1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
6.结构体指针编程:定义一个结构体,其成员变量为“学号”、“姓名”、“成绩”,再定义一个该结构体变量的数组s[5],并给数组s中的每个成员变量赋值,利用多文件编程方法编写源文件和头文件完成下列任务:
- 编写一个文件,要求文件中是main函数用来定义结构体,和结构体数组变量s[5],并给5名学生的成员变量赋值,分别调用下面两个文件中的函数完成成绩排序和显示不及格学生信息。
- 编写一个文件要求文件中的函数实现将s[5]中的成绩按照升序排序,并在main函数中显示排序后的5名学生信息。
- 编写一个文件要求文件中的函数实现将s[5]中的成绩不及格的学生信息在main函数中显示出来。
我们可以分为三个文件:main.c
、sort.c
、display.c
。下面是每个文件的内容:
main.c
// main.c
#include <stdio.h>
#include "student.h"
int main() {
// 定义结构体数组和初始化
struct Student s[5] = {
{101, "Alice", 85.5},
{102, "Bob", 78.3},
{103, "Charlie", 92.0},
{104, "David", 88.7},
{105, "Eva", 75.2}
};
// 调用排序函数
sort(s, 5);
// 调用显示不及格学生信息的函数
displayFailedStudents(s, 5);
// 显示排序后的学生信息
printf("\nSorted Students:\n");
for (int i = 0; i < 5; ++i) {
printf("ID: %d, Name: %s, Grade: %.2lf\n", s[i].id, s[i].name, s[i].grade);
}
return 0;
}
sort.c
// sort.c
#include "student.h"
// 冒泡排序,按成绩升序排序
void sort(struct Student arr[], int size) {
for (int i = 0; i < size - 1; ++i) {
for (int j = 0; j < size - i - 1; ++j) {
if (arr[j].grade > arr[j + 1].grade) {
// 交换 arr[j] 和 arr[j + 1]
struct Student temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
display.c
// display.c
#include <stdio.h>
#include "student.h"
// 显示不及格学生信息
void displayFailedStudents(struct Student arr[], int size) {
printf("Failed Students:\n");
for (int i = 0; i < size; ++i) {
if (arr[i].grade < 60.0) {
printf("ID: %d, Name: %s, Grade: %.2lf\n", arr[i].id, arr[i].name, arr[i].grade);
}
}
}
student.h
// student.h
#ifndef STUDENT_H
#define STUDENT_H
// 结构体声明
struct Student {
int id;
char name[20];
double grade;
};
// 函数声明
void sort(struct Student arr[], int size);
void displayFailedStudents(struct Student arr[], int size);
#endif // STUDENT_H
7.指向指针的指针编程:定义一个指针变量和一个指向指针的指针变量,并分别给这两个变量赋值,并利用两个指针分别显示它们所指向的变量的内容。
#include <stdio.h>
int main() {
int x = 10; // 一个整数变量
int *ptr1 = &x; // 指向整数的指针变量
int **ptr2 = &ptr1; // 指向指针的指针变量
// 输出变量的值和通过指针访问变量的值
printf("Value of x: %d\n", x);
printf("Value pointed by ptr1: %d\n", *ptr1);
printf("Value pointed by ptr2: %d\n", **ptr2);
return 0;
}
8.指向指针的指针与指针数组:
- 定义一个指向指针的指针变量p,整型的指针数组int *a[3],定义3个整型变量x, y, z,使指针数组a中的每一个元素分别指向变量x,y,z,使p指向数组a的每一个元素,编程实现利用p输出x,y,z的值以及其地址。
- 定义一个指向指针的指针变量pt,一个字符指针数组s,并使数组s中的每一个元素分别指向字符串“hello”、“world”,“123”,利用指向指针的pt将指针数组s指向的每个字符串输出。
#include <stdio.h>
int main() {
// (1) 指向指针的指针与整型的指针数组
int x = 5, y = 10, z = 15;
int *a[3] = {&x, &y, &z}; // 整型的指针数组
int **p; // 指向指针的指针
p = a; // 指向指针数组的第一个元素
// 利用p输出x,y,z的值以及地址
for (int i = 0; i < 3; ++i) {
printf("(1) Element %d: Value = %d, Address = %p\n", i + 1, **p, *p);
p++; // 指向下一个指针
}
// (2) 指向指针的指针与字符指针数组
char *strings[] = {"hello", "world", "123"};
char **pt; // 指向指针的指针
pt = strings; // 指向字符指针数组的第一个元素
// 利用pt输出指针数组s指向的每个字符串
printf("\n(2) Strings:\n");
for (int i = 0; i < 3; ++i) {
printf(" %s\n", *pt);
pt++; // 指向下一个指针
}
return 0;
}
9.深入理解数组指针和指针数组的含义,利用数组指针、指针数组以及指向指针的指针分别输出二维数组的值,程序结果如下图所示。
#include <stdio.h>
#include <stdlib.h>
int main() {
int matrix[4][4] = { {0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11},
{12, 13, 14, 15}};
// (1) 使用数组指针输出二维数组的值
int(*ptr)[4] = matrix; // 指向包含4个整数的数组的指针
printf("Using Array Pointer:\n");
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d ", ptr[i][j]);
}
printf("\n");
}
// (2) 使用指针数组输出二维数组的值
int* ptr2[4];
for (int i = 0; i < 4; ++i) {
ptr2[i] = matrix[i];
}
printf("\nUsing Pointer Array:\n");
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d ", ptr2[i][j]);
}
printf("\n");
}
// (3) 使用指向指针的指针输出二维数组的值
int** pptr = malloc(4 * sizeof(int*));
for (int i = 0; i < 4; ++i) {
pptr[i] = matrix[i];
}
printf("\nUsing Pointer to Pointer:\n");
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
printf("%d ", pptr[i][j]);
}
printf("\n");
}
// 释放动态分配的内存
free(pptr);
return 0;
}