1.利用指针变量将一个数组中的数据反向输出。
声明:
void work1(int *, int); // 声明反向遍历
void work1_1(int *, int); // 声明正向遍历
实现:
// 利用指针变量将一个数组中的数据反向输出,反向遍历
void work1( int *p,int len)
{
p += (len - 1);
for(int i = 0; i < len; i++)
{
if(i%4 == 0 && i != 0) printf("\n");
printf("arr[%d]=%d \t", len - i, *(p-i));
}
printf("\n");
}
// 利用指针变量将一个数组中的数据正向输出,正向遍历
void work1_1( int *p,int len)
{
for(int i = 0; i < len; i++)
{
if(i%4 == 0 && i != 0) printf("\n");
printf("arr[%d]=%d \t", i, *(p+i));
}
printf("\n");
}
调用:
// 定义并初始化一个一维数组
int arr[10] = {90,98,87,76,65,54,43,32,21,10};
int len = sizeof(arr)/sizeof(arr[0]);
printf("正向输出:\n");
work1_1(arr, len);
printf("反向输出:\n");
work1(arr,len);
运行截图
2.利用指针变量计算下标为奇数的数组的和;
声明
int work2(int *,int); // 声明下标奇数之和
实现
// 下标奇数之和
int work2(int *p, int len)
{
int sum = 0;
for(int i = 0; i < len; i++)
{
if(i%2 != 0 && i != 0)
sum += *(p + i);
}
return sum;
}
调用
// 定义并初始化一个一维数组
int arr[10] = {90,98,87,76,65,54,43,32,21,10};
int len = sizeof(arr)/sizeof(arr[0]);
printf("数组下标是奇数的和:%d\n", work2(arr,len));
运行截图
3.确认整型,字符型,浮点型指针变量的大小;
int *a;
float *b;
char c;
printf("整型:%ld,浮点型:%ld,字符型:%ld\n", sizeof(a), sizeof(b), sizeof(c));
运行截图:
4.利用指针变量输出字符数组中的所有字符。
函数实现:
void work4(char *p, int len)
{
for(int i = 0; i < len; i++)
{
if(*(p + i) == '\0') break;
printf("%c", p[i]);
}
printf("\n");
}
函数调用
char crr[20] = "iaofgaeuu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
work4(crr,len4);
运行截图
5.浮点型数组的平均值
实现
// 求浮点型数组元素的平均值
double work5(double *p, int len)
{
double sum = 0.0;
for(int i = 0; i < len; i++)
{
sum += *(p + i);
}
return sum/len;
}
调用
double drr[5] = {12.3,1.2,5.5,3.3,6.6};
int len5 = sizeof(drr)/sizeof(drr[0]);
printf("%lf\n", work5(drr,len5));
运行截图
6.编写函数,要求用指针做形参,分别实现以下功能:
(1)求一个字符串长度
实现
// 求字符串长度
int work6_1(char *p,int len)
{
int i = 0;
while(i < len )
{
if(p[i] != '\0')
{
i++;
}
else
{
break;
}
}
return i;
}
调用
char crr[40] = "iaofgaKUDu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
printf("字符串的长度是:%d\n", work6_1(crr,len4));
(2)在一个字符串中统计大写字母的个数
实现
// 统计大写字母个数
int work6_2(char *p,int len)
{
int n = 0, i = 0;
while(i < work6_1(p,len) )
{
if(*(p+i) >= 'A' && *(p+i) <= 'Z') n++;
i++;
}
return n;
}
调用
char crr[40] = "iaofgaKUDu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
printf("字符串大写字母个数是:%d\n", work6_2(crr,len4));
(3)在一个字符串中统计数字字符的个数
实现
// 统计数字字符
int work6_3(char *p, int len)
{
int n = 0,i = 0;
while(i < work6_1(p,len))
{
if(*(p+i) >= 48 && p[i] <= '9' ) n++;
i++;
}
return n;
}
调用
char crr[40] = "iaofgaKUDu932578";
int len4 = sizeof(crr)/sizeof(crr[0]);
printf("字符串数字字符个数是:%d\n", work6_3(crr,len4));
运行截图
7编写函数,要求用指针做形参,实现将二维数组(行列相同)的进行转置(行列数据互换): int(*p)[N]
函数实现:
// 行列转置(行列相同)
void work7(int (*p)[3], int len)
{
int a[len][len];
for(int i = 0; i < len; i++)
{
for(int j = 0; j < len; j++ )
{
a[j][i] = p[i][j];
}
printf("\n");
}
for(int i = 0; i < len; i++ )
{
for(int j = 0; j < len; j++)
{
p[i][j] = a[i][j];
}
}
printf("数组已转置\n");
}
函数调用
int arr7[3][3] = {11,12,13,
21,22,23,
31,32,33};
int len7 = sizeof(arr7)/sizeof(arr7[0]);
int (*p)[len7] = arr7;
work7(p,len7);
for(int i = 0; i < len7*len7; i++)
{
if(i != 0 && i%3 == 0) printf("\n");
printf("%d ",*(*arr7 + i));
}
printf("\n");
运行截图
8.上三角0的个数
实现
// 指针做形参,实现统计二维数组上三角中的0的数量
int work8(int* p,int row, int col)
{
int n = 0;
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col - i; j++)
{
if(!*(p + j + i*col)) n++;
}
}
return n;
}
调用
int arr8[4][4] = {1,1,1,0,
0,0,1,1,
0,1,0,1,
0,1,1,0};
int row = sizeof(arr8)/sizeof(arr8[0]), col = sizeof(arr8[0])/sizeof(arr8[0][0]);
printf("遍历数组:\n");
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
printf("%3d\t", arr8[i][j]);
}
printf("\n");
}
printf("\n上半角0的个数是:%d\n", work8(&arr8[0][0], row, col));
运行截图
9.返回二维数组的最大值元素的地址。
实现
// 返回最大值地址
int* work9(int* p, int len)
{
int *max = p;
for(int i = 0; i < len; i++)
{
if(*max < *(p+i)) max = p+i;
}
return max;
}
调用
int arr9[4][4] = {1,2,3,4,
5,6,7,999,
8,9,11,23,
44,55,66,77};
int row = sizeof(arr9)/sizeof(arr9[0]), col = sizeof(arr9[0])/sizeof(arr9[0][0]);
int *max = &arr9[0][0];
printf("遍历数组:\n");
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
if(*max < arr9[i][j]) max = &arr9[i][j];
printf("%3d\t", arr9[i][j]);
}
printf("\n");
}
printf("\n最大值的地址是%p,%p\n", work9(&arr9[0][0], row * col), max);
运行截图
10.面试题
1)定义整形变量i; // int i;
2)p为指向整形变量的指针变量;// int* p = &i;
3)定义整形一维数组p,它有n 个整形元素; // int n = 10, p[n];
4)定义一维指针数组p,它有n个指向整形变量的指针元素;// int *p[n];
6)p为返回整形函数值的函数; // int p(){}
7)p为返回一个指针的函数,该指针指向整形数据;// int* p(){}
8)p为指向函数的指针变量,该函数返回一个整形值;// int (*p)(int);
9)p是一个指向整形指针变量的指针变量;// int** p;
11.找出第一次出现 12.35 的下标位置,并输出。
实现
// 查找12.35的下标
int work11(float* p, int len, float n)
{
int i = 0;
for(;i < len; i++)
{
if(*(p+i) - n == 0) return i;
}
return -1;
}
调用
float a11[10] = {1.1,2.2,3.3,4.4,5.5,12.35,6.6,7.7,8.8,9.9};
float* p11 = (float*)calloc(10,sizeof(float));
if(!p11)
{
perror("内存申请失败!");
return 0;
}
memcpy(p11,a11, 10 * sizeof(float));
printf("遍历复制数据后的数组:");
for(int i = 0; i < 10; i++ )
{
printf("%.2f ", *(p11+i));
}
printf("\n");
printf("12.35的下标位置是:a11[%d]\n", work11(p11,10,12.35));
free(p11);
p11 = NULL;
运行截图
12.动态申请一个整型数组,并给每个元素赋值,要求删除第3个元素;
代码:
int a12[5] = {1,2,3,4,5};
int* p12 = (int*)calloc(5,sizeof(int));
if(!p12)
{
perror("内存申请失败!");
return -1;
}
// 对申请的堆内存进行初始化
memcpy(p12, a12, 5*4);
// 遍历申请的堆内存
for(int i = 0; i < 5; i++)
{
printf("%d ", *(p12+i));
}
printf("\n");
memset(p12+2, 0, 1*4);
// 再次遍历
for(int i = 0; i < 5; i++)
{
printf("%d ", *(p12+i));
}
printf("\n");
free(p12);
p12 = NULL;
运行截图:
13.动态申请一个整型数组,并给每个元素赋值,要求在第4个元素后插入100;
代码:
int* p13 = (int*)malloc(40);
if(!p13)
{
perror("内存申请失败!");
return -1;
}
memset(p13, 0, 40);
// 遍历
for(int i = 0; i < 10; i++)
{
printf("%d ", *(p13 + i));
}
printf("\n");
// 再次遍历
for(int i = 0; i < 10; i++)
{
if(i > 3) p13[i] = 100;
printf("%d ", *(p13+i));
}
printf("\n");
free(p13);
p13 = NULL;
运行截图
14.控制台输入一个n,要求创建一个n行n列的数列,求对角线上元素的和,要求使用指针实现
代码:
int n;
printf("请输入行列的大小:\n");
scanf("%d", &n);
int *p = (int*)calloc(n*n,sizeof(int));
if(!p)
{
perror("内存申请失败!");
return -1;
}
// 给数组赋值
printf("请输入数组元素\n");
for(int i = 0; i < n*n; i++ )
{
scanf("%d", p+i);
}
// 遍历数组
printf("赋值后的数组:\n");
for(int i = 0; i < n*n; i++)
{
if(i != 0 && i % n == 0) printf("\n");
printf("%d\t", *(p+i));
}
printf("\n");
int sum = 0, sum2 = 0;
for(int i = 0; i < n; i++)
{
//printf("%d ", *(p + i*n + i));
sum += *(p+i*n + i);
sum2 += *(p + n*i + n - 1 - i);
}
printf("主对角线之和是:%d\n", sum);
printf("辅对角线之和是:%d\n", sum2);
free(p); // 释放堆内存
p = NULL; // 指针悬空
运行截图
15.附加题【选做】: 编写一个函数,实现 memmove 的功能。
实现
// 实现memmove的功能
void* work15(void* to, const void* from, unsigned long count)
{
for(int i = 0; i < count; i++)
{
*(char*)(to + i) = *(char*)(from + i);
}
return to;
}
调用
char a15_1[10] = "123456789";
char a15_2[5];
work15(a15_2,a15_1+2, 5 );
printf("原数组:%s\n", a15_1);
printf("目标数组:%s\n", a15_2);
运行截图