首页 > 其他分享 >C语言(指针数组和数组指针)

C语言(指针数组和数组指针)

时间:2024-12-11 15:58:49浏览次数:8  
标签:arr int C语言 数组 printf sizeof 指针

变量指针与指针变量

指针变量指向数组

通过指针引用数组元素

引用一个数组元素,可以用:

  1. 下标法:如a[i]形式。
  2. 指针法:如*(a+i) *(p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值:p=a;
案例

需求:有一个整型数组a,有10个元素。输出数组中的全部元素。

分析:要输出各元素的值,有三种方法

  • 下标法:改变下标输出所有元素
 #include <stdio.h>
 void main()
 {
 int arr[10];
 int i;
 // 给数组元素赋值
for(i = 0; i < 10; i++)
 scanf("%d",&arr[i]);
 // 遍历数组元素
for(i = 0; i < 10; i++)
 printf("%-4d%",arr[i]);
 printf("\n");
 }

指针法(地址):通过数组名计算出数组元素的地址,找出数组元素值

 #include <stdio.h>
 void main()
 {
 int arr[10];
 int i;
 // 给数组元素赋值
for(i = 0; i < 10; i++)
 scanf("%d",&arr[i]);
 // 遍历数组元素
for(i = 0; i < 10; i++)
 printf("%-4d%",*(arr+i));
 printf("\n");        
}

指针法(指针变量):用指针变量指向数组元素

#include <stdio.h>
 void main()
 {
 int arr[10];
 int *p,i;
 // 给数组元素赋值
for(i = 0; i < 10; i++)
 scanf("%d",&arr[i]);
 // 遍历数组元素
for(p = arr;p < (arr + 10); p++)
 printf("%-4d%",*p);
 printf("\n");      
}

以上3种写法比较:
第①种写法和第②种写法执行效率相同。系统是将arr[i]转换为*(arr+i)处理的,即先计算出地
址,因此比较费时。
第③种方法比第①②种方法快。用指针变量直接指向数组元素,不必每次都重新计算地址。
(p++)能大大提高执行效率。
用第①种写法比较直观,而用地址法或者指针变量的方法难以很快判断出当前处理的元素。

使用指针变量指向数组元素时(上面第③种写法),注意以下三点:

(p–) 相当于arr[i–],先p,再p-
(++p)
相当于arr[++i],先++p,再

(–p)
相当于arr[–i],先–p,再

数组名作函数参数

表现形式:

  1. 形参和实参都是数组名
 void fun(int arr[],int len){..}
 void main()
 {
 int arr[] = {11,22,33};
 fun(arr,sizeof(arr)/sizeof(arr[0]));
 }
  1. 实参用数组名,形参用指针变量
void fun(int *p,int len){..}
 void main()
 {
 int arr[] = {11,22,33};
 fun(arr,sizeof(arr)/sizeof(arr[0]));
 }
  1. 实参形参都用指针变量
 void fun(int *p,int len){..}
 void main()
 {
 int arr[] = {11,22,33};
 int *p = arr;
 fun(p,sizeof(arr)/sizeof(arr[0]));
 }
  1. 实参为指针变量,形参为数组名
 void fun(int arr[],int len){..}
 void main()
 {
 int arr[] = {11,22,33};
 int *p = arr;
 fun(p,sizeof(arr)/sizeof(arr[0]));
 }

案例

需求:将数组a中n个整数按相反顺序存放
在这里插入图片描述
代码:

 #include <stdio.h>
 /**
 * 数组的反转:数组实现
*/ 
void inv(int arr[],int len)
 {
 // 反转思路:将第0个和n-1个进行对调,将第1个和n-2个对调
// 定义循环变量
int i = 0, temp;
 // 遍历数组
for(;i < len / 2; i++)
 {
 // 交换
temp = arr[i];
 arr[i] = arr[len-1-i];
 arr[len-1-i] = temp;
 }
 }
 /**
 * 数组的反转:指针实现
* const 给变量的数据类型前面添加const,代表这个变量是只读变量,无法对此作出修改
*/ 
void inv2(int *p,const int len)
 {
 // 定义循环变量
int *i = p,*j = &p[len -1],temp;
 // 遍历数组
for(;i < j;i++,j--)
 {
 temp = *i;
 *i = *j;
 *j = temp;
 }
 }
 /**
 * 遍历数组
*/ 
void get(const int arr[],int len)
 {
 for(int i = 0; i < len; i++)
 {
 printf("%-3d",arr[i]);
 }
 printf("\n");
 }
 int main(int argc,char *argv[])
 {
 int arr[] = {11,22,33,44,55,66};
 get(arr,sizeof(arr)/sizeof(arr[0]));
 inv2(arr,sizeof(arr)/sizeof(arr[0]));
 get(arr,sizeof(arr)/sizeof(arr[0]));
 // 执行遍历
return 0;
 }

数组指针与指针数组

数组指针

概念:数组指针是指向数组的指针,本质上还是指针
特点:
先有数组,后有指针
它指向的是一个完整的数组
一维数组指针:
语法:

数据类型 (*指针变量名)[容量];

案例:

#include <stdio.h>
 int main(int argc,char *argv[])
 {
 // 一维数组指针
// 现有数组,再有指针
int arr[] = {100,200,300};
 // 获取数组的元素个数
int len = sizeof(arr) / sizeof(arr[0]);
 // 定义一个数组指针,指向arr这个数组
 int (*p)[3] = &arr; // 此时p不是指向arr数组的第一个元素,而是指向arr这个数组本身
printf("%p\n",p);
 // p++; // 此时p++会跳出整个数组,访问到一块未知的内存,程序中尽量避免这种写法
// printf("%p\n",p);
 // 如何访问访问数组指针
printf("%d\n",(*p)[2]);// 300
 // 遍历
for(int i = 0;i < len;i++)
 {
 printf("%d\n",(*p)[i]);
 }
 printf("\n");
 }

我们之前所学的是指向数组元素的指针,本质上还是指针变量;现在我们学的是指向数组的指针,叫作数组指针.
二维数组指针:
语法:

数据类型 (*指针变量名)[行容量][列容量];

案例:
写法1:

 #include <stdio.h>
 int main(int argc,char *argv[])
 {
 // 创建一个普通的二维数组
int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};

 // 创建一个二维数组指针
    // 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
    int (*p)[3][3] = &arr;
    printf("%d\n",(*p)[1][0]);
    // 遍历
    for(int i = 0; i < sizeof(arr)/sizeof(arr[0]);i++)
    {
        int len = sizeof(arr[i])/sizeof(int);
        for(int j = 0; j < len; j++)
        {
            printf("%-4d",(*p)[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    return 0;
 }

写法2:

 #include <stdio.h>
 int main(int argc,char *argv[])
 {
    // 创建一个普通的二维数组
    int arr[][3] = {10,20,30,100,200,300,1000,2000,3000};
    // 创建一个二维数组指针
    // 一个二维数组本质上还是一个一维数组,只不过它的元素也是数组
    int (*p)[3] = arr; // 取二维数组的第一个元素 {10,20,30}  数组名本身就代表数组首元素(地址)
    printf("%d\n",(*p)[0]);// 10
    // 获取元素2000
    printf("2000-%d,%d,%d",*(*(p+2)+1),*(p[2]+1),p[2][1];// *(*(p+1)+2) 300
    return 0;
 }

指针和数组中符号优先级:() > [] > *
通过指针引用多维数组
在这里插入图片描述
案例1
需求:用指向元素的指针变量输出二维数组元素的值

 #include <stdio.h>
 int main(int argc,char *argv[])
 {
    // 定义一个普通的二维数组
    int arr[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23};
    // 定义一个指针变量,用来接收二维数组的元素值
    int *p = arr[0];// &arr[0][0]
    // 循环遍历
    for(;p < arr[0]+12;p++)
    {
        // 每4个换行
        if((p - arr[0]) % 4 == 0)
        {
            printf("\n");
        }
        printf("%-4d",*p);
    }
    printf("\n");
    return 0;
 }

案例2
需求:数组指针-输出二维数组任一行任一列元素的值

 #include <stdio.h>
 /**
 * 需求:数组指针-输出二维数组任一行任一列元素的值
 */
 void arr_fun2()
 {
    // 定义一个二维数组
    int arr[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23};
    
    // 创建一个一维的数组指针指向一个二维的数组
    int (*p)[4] = arr;// 等价于 &arr[0],p代表我们这个二维数组
    // 创建两个变量,代表我们对应数据的行和列
int row,col;
 // 通过控制台来输入
printf("请输入行号和列号:\n");
 scanf("%d,%d",&row,&col);
 printf("arr[%d][%d]=%d\n",row,col,*(*(p+row)+col));// *(*(p+row)+col) | *(p[row]+col) | 
p[row][col]
 }
 int main(int argc,char *argv[])
 {
 arr_fun2();
 return 0;

指针数组

概念:指针数组是一个数组,数组中的每一个元素都是一个指针
特点:先有指针,后有数组
指针数组的本质是一个数组,只是数组中的元素类型为指针
语法:

数据类型 *数组名[容量];

案例:

 #include <stdio.h>
 int main(int argc,char *argv[])
 {
    // 定义三个变量
    int a = 10,b = 20,c = 30;
    // 定义指针数组,指针数组用来存放指针的
    int *arr[3] = {&a,&b,&c};
    // 获取数组大小
    int len = sizeof arr / sizeof arr[0];
    // 遍历数组
    for(int i = 0; i < len; i++)
        printf("%-3d",*arr[i]);// 输出每个指针指向的值,需要解引用
    
    printf("\n");
    return(0);
 }

建议:我们一般使用指针数组处理字符串

标签:arr,int,C语言,数组,printf,sizeof,指针
From: https://blog.csdn.net/weixin_69851948/article/details/144377937

相关文章

  • (nice!!!)(LeetCode 热题 100) 76. 最小覆盖子串(哈希表、滑动窗口、双指针)
    题目:76.最小覆盖子串思路:用哈希表来记录字符串t中字符出现的情况。然后用双指针来实现滑动窗口,找到最小的字符串即可。时间复杂度为0(m+n),细节看注释。classSolution{public:stringminWindow(strings,stringt){ //哈希表unordered_map<char......
  • Go指针进阶:从入门到被虐,90%开发者都踩过这些坑
    Go指针进阶:从入门到被虐,90%开发者都踩过这些坑!原创 瀛洲在线编程之道 黑客编程之道  2024年11月17日21:10 吉林 听全文黑客编程之道分享黑客编程技术,Go、Python、Rust、Java等编程技术166篇原创内容公众号指针是Go语言中最强大但也最容易出错的特......
  • C语言:define定义常量和定义宏(详解)
    本篇博客给大家带来的是#define定义常量和#define定义宏的方法......
  • cpp智能指针
      普通指针的不足new和new[]的内存需要用delete和deletel]释放。程序员的主观失误,忘了或漏了释放。程序员也不确定何时释放。普通指针的释放类内的指针,在析构函数中释放。C++内置数据类型,如何释放?new出来的类,本身如何释放?C++11新增三个智能指针类型uniqu......
  • leetcode面试经典 150 题第三题(26. 删除有序数组中的重复项)#更适合新手学习
     题目:26.删除有序数组中的重复项-力扣(LeetCode)给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。考虑 nums 的唯......
  • 基于Objective-C和C语言的蜂巢爆料组件设计源码-Z5yUlJ1u
    基于Objective-C和C语言的蜂巢爆料组件设计源码地址该项目是基于Objective-C和C语言的蜂巢爆料组件设计源码,包含312个文件,其中包括292个PNG图片文件、4个头文件(.h)、3个属性列表文件(.plist)、1个模块映射文件(modulemap)以及一系列框架和签名文件。该组件适用于需要高效信息收集......
  • 代码随想录算法训练营第四十三天|LeetCode300.最长递增子序列、LeetCode674.最长连续
    前言打卡代码随想录算法训练营第49期第四十三天 (๑ˉ∀ˉ๑)首先十分推荐学算法的同学可以先了解一下代码随想录,可以在B站卡哥B站账号、代码随想录官方网站代码随想录了解,卡哥清晰易懂的算法教学让我直接果断关注,也十分有缘和第49期的训练营大家庭一起进步。LeetCode300......
  • Perl 数组
    Perl数组一个是存储标量值的列表变量,变量可以是不同类型。数组变量以@开头。访问数组元素使用 $+变量名称+[索引值] 格式来读取,实例如下:实例#!/usr/bin/perl@hits=(25,30,40);@names=("google","runoob","taobao");print"\$hits[0]=$hits[0]\n";pri......
  • 数组元素全倒排列并去重
    functionreverseAndDedup(arr){//ReversethearrayconstreversedArr=arr.slice().reverse();//DeduplicatethereversedarrayconstuniqueArr=[];constseen=newSet();for(constelementofreversedArr){if(!seen.has(element))......
  • 善于运用指针--通过指针引用数组
    一个数组包含若干个元素,每个元素在内存中占用储存单元,它们都有相应的地址,指针变量能指向变量,也可以指向地址。所谓数组元素的地址,也就是数组元素的指针。文章目录前言一、在引用数组元素时指针的运算二、通过指针引用数组元素三、用数组名作函数参数1用指针打印数组2.指......