[1]指针以及一维数组操作
语法:数据类型 *变量名
int a; int *p=a; int **q=p;
- 一级指针变量保存普通变量的地址
- 用于普通变量之间的地址传参
- 二级指针变量保存一级指针变量的地址
- 用于一级指针变量之间的地址传参
- 用于一级指针变量之间的地址传参
- int a[10]; int *p=a;
- &a[0] &a[1] … &a[i] ------>每个元素的起始地址
- a a+1 … a+i ------>每个元素的起始地址
- &a ---->表示数组的起始地址
- &a+1 ---->偏移一个数组的大小
- 数组名的含义: 表示数组首元素的起始地址,并且是一个常量,不能被改变!
1>练习一
- 1,定义一个double 类型的指针变量,打印变量的数据、地址以及指针变量本身的地址
- 2,求两个浮点数的平均值,数据键盘输入,指针操作
- 3,通过指针交换两个整型变量的
- 4,有三个整型变量a,b,c, 通过指针实现 a最大值,b中间值,c最小值
#include <stdio.h>
int main(){
double n = 22.13;
double* p = &n;
printf("*p = %f\np = %p\n&p = %p\n",*p,p,&p);
printf("----------------------------------\n");
float t1,t2;
printf("input two float value:\n");
scanf("%f%f",&t1,&t2);
float *f1 = &t1;
float *f2 = &t2;
printf("avg = %f\n",(*f1+*f2)/2);
printf("----------------------------------\n");
int i = 5,j = 9;
printf("交换前:i = %d,j = %d\n",i,j);
int *p1 = &i;
int *p2 = &j;
int temp = *p1;
*p1 = *p2;
*p2 = temp;
printf("交换后:i = %d,j = %d\n",i,j);
printf("----------------------------------\n");
int arr[3];
printf("input three int value:\n");
for(int i = 0; i < 3;i++){
scanf("%d",&arr[i]);
}
printf("原 来:a = %d,b = %d,c = %d\n",arr[0],arr[1],arr[2]);
/*bubble sort*/
int *t = arr;
for(int i = 0;i < 2;i++){
for(int j = 0;j <2-i;j++){
if(*(t+j) < *(t+j+1)){
int temp = *(t+j);
*(t+j) = *(t+j+1);
*(t+j+1) = temp;
}
}
}
printf("排序后:a = %d,b = %d,c = %d\n",arr[0],arr[1],arr[2]);
return 0;
}
运行结果:
2>练习二
- 1、定义一个浮点类型的数组,通过指针从键盘获取数据,并打印结果(使用指针自增、指针加上一个整数,指针和下标的组合三种方法)
- 2、从键盘获取一行字符序列(通过循环的方式,一个字符一个字符的获取),通过指针将获取的字符序列反转
- 3、从键盘获取一行字符序列, 判断是否是回文字符,如 abcba abba 类似这样的都是回文字符
#include <stdio.h>
int main01(){
float arr[5];
float *p = arr;
printf("input five float value:\n");
for(int i = 0;i < 5;i++){
scanf("%f",p+i);
}
/*指针自增打印*/
while(p < arr+5){
printf("%.2f ",*p);
p++;
}
putchar('\n');
p = arr;
/*指针加上一个整数打印*/
for(int i = 0;i < 5;i++){
printf("%.2f ",*(p+i));
}
putchar('\n');
/*指针和下标的组合的方法打印*/
for(int i = 0;i < 5;i++){
printf("%.2f ",p[i]);
}
putchar('\n');
return 0;
}
int main02(){
char str[100];
int n = 0;
while(1){
int temp = getchar();
if(temp == '\n'){
break;
}
str[n] = temp;
n++;
}
/*定义字符指针指向首个元素*/
char *p = str;
/*字符变量保存数组首地址的元素*/
char pVal;
for(int j = 0;j <n;j++){
/*每次循环保存首地址的元素*/
pVal = *p;
for(int i = 0;i < n-1-j;i++){
/*第一个元素取出后,后面n-1-j个元素挨个前移*/
*(p+i) = *(p+i+1);
}
/*将保存的第一个元素,放到n-1-j的位置上*/
*(p+n-1-j) = pVal;
}
for(int i = 0;i < n;i++){
printf("%c",p[i]);
}
putchar('\n');
return 0;
}
int main(){
char str[100];
int n = 0,temp;
/*从键盘获取一行字符到回车停止*/
while((temp = getchar()) != '\n'){
str[n] = temp;
n++;
}
/*定义两指针,分别指向获取的字符串的开头和结尾*/
char *begin = str,*end = str+n-1;
for(;begin < end;begin++,end--){
if(*begin != *end){
printf("不是回文序列\n");
break;
}
}
if(begin >= end){
printf("是回文序列\n");
}
return 0;
}
运行结果:
3>练习三
#if 0
设有一个数列,包含10个数,已按升序排好。
现要求编写程序,把从指定位置开始的n个数按逆序重新排列并输出新的完整数列。
进行逆序处理时要求使用指针方法。试编程。
(例如:原数列为2,4,6,8,10,12,14,16,18,20,
若要求把从第4个数开始的5个数按逆序重新排列,
则得到新数列 2,4,6,16,14,12,10,8,18,20)
#endif
#include <stdio.h>
void print_arr(int arr[],int N){
for(int i = 0;i < N;i++){
printf(" %d ",arr[i]);
}
printf("\n");
}
void desendArray(int arr[],int beginIndex,int n){
/*beginIndex-1是因为传过来的值是第几个元素,对应下标要-1*/
if(beginIndex-1+n > 10){
printf("Error:越界\n");
}
else{
/*定义指针始终指向要反转序列的第一个元素*/
int *p = &arr[beginIndex-1];
for(int i = 0;i < n;i++){
/*每次循环把第一个位置的元素保存*/
int value = *p;
/*将后面n-1-i个元素依次左移一个位置*/
for(int j = 0;j < n-1-i;j++){
*(p+j) = *(p+j+1);
}
/*将保存的第一个位置元素,放到n-1-i的位置*/
*(p+n-1-i) = value;
}
print_arr(arr,10);
}
}
int main(){
int arr[10] = {2,4,6,8,10,12,14,16,18,20};
print_arr(arr,10);
int begin,n;
printf("input begin :");
scanf("%d",&begin);
printf("input num :");
scanf("%d",&n);
desendArray(arr,begin,n);
return 0;
}
运行结果;
[2]数组指针
-
数组指针: 本质是一个指针变量,保存数组的起始地址
-
数组指针语法: 类型 (*p)[元素个数]
-
int (*p)[8]
: 表示p是一个指针变量,保存有8个元素,每个元素是整型的数组的起始地址
1>指针操作二维数组
-
p
: 是一个数组指针,保存二维数组第一行的起始地址 -
p+i
: 第i+1行的起始地址 -
*(p+i)
:每一行第一个元素的起始地址 -
*(p+i)+j
:每一行每一个元素的起始地址 -
*(*(p+i)+j)
:每一行的每一个元素
2>练习
- 1、编写程序完成功能:输入一个3行四列的二维数组,输出其最大数组元素并输出其行号与列号(要求使用数组指针)
- 2、编写程序,从键盘输入十二个整数,存入到一个3行4列的二维数组中,输出其每一列的平均值(要求使用数组指针)
#include <stdio.h>
int main(){
int arr[3][4];
int (*p)[4] = arr;
printf("input 12 int value:\n");
for(int i = 0;i < 3;i++){
for(int j = 0;j < 4;j++){
scanf("%d",*(p+i)+j);
}
}
printf("-------------------------------------\n");
printf("arr[3][4]:\n");
for(int i = 0;i < 3;i++){
for(int j = 0;j < 4;j++){
printf("%d\t",*(*(p+i)+j));
}
putchar('\n');
}
printf("---------------第一题----------------\n");
int maxVal = **p;
for(int i = 0;i < 3;i++){
for(int j = 0;j < 4;j++){
if(maxVal < *(*(p+i)+j)){
maxVal = *(*(p+i)+j);
}
}
}
for(int i = 0;i < 3;i++){
for(int j = 0;j < 4;j++){
if(maxVal == *(*(p+i)+j)){
printf("最大元素为a[%d][%d] = %d\n",i,j,*(*(p+i)+j));
}
}
}
printf("---------------第二题----------------\n");
for(int j = 0,sum;j < 4;j++){
sum = 0;
for(int i = 0;i < 3;i++){
sum += *(*(p+i)+j);
}
printf("第%d列平均值 = %.2f\n",j+1,(float)sum/3);
}
return 0;
}
运行结果:
[3]指针数组
指针数组: 本质就是一个数组,每一个元素都是指针类型!!!
#include <stdio.h>
int main()
{
int x=1, y=2, z=3, w=4, u=5;
int* a[5] = {&x, &y, &z, &w, &u};
for(int i=0; i<5; i++)
{
printf("a[%d] = %p\n", i, a[i]);
}
for(int i=0; i<5; i++)
{
printf("*(a[%d]) = %d\n", i, *(a[i]));
}
return 0;
}
运行结果: