【C语言】“指针的运算”、“指针与数组

简介: 一、指针运算指针可以进行±整数,指针-指针,还有关系运算,其他的运算会被编译器阻止。1.指针 + - 整数对指针进行±的时候一定要注意不要越界访问,不然会产生野指针。

一、指针运算

指针可以进行±整数,指针-指针,还有关系运算,其他的运算会被编译器阻止。

一、指针运算

指针可以进行±整数,指针-指针,还有关系运算,其他的运算会被编译器阻止。

void print(int* arr)
{
    for (int* i = arr; i < &arr[arr_lenght];)
    {
        printf("%d", *i++); //对指针进行++达到遍历数组的效果
    }
}
int main()
{
    int arr[arr_lenght] = { 1,2,3,4,5,6,7,8,9,0 };
    print(arr);
}

acb8424842c74588942e87b799c3f63f.png

int* i = arr(数组名为首地址),此时i = 0xffee0000 对int*类型进行±整数就是对地址进行±一个int类型大小,+1之后为0xffee0004,也就是arr[1]的地址,再+1就是arr[2]的地址,依次类推,再在 i 的前面加上 * 号,就可以用指针做到遍历数组。

2.指针-指针

指针+整数为地址,所以指针-指针也是一个整数

  • 应用场景举例:我们可以在求字符串长度的时候,用字符串结尾地址-字符串首地址,得到字符串长度。
int my_strlen(char *str)    
{ 
  char *pstr = str;     //先将字符串首地址进行存储
  while(*pstr != '\0' )   //strlen不应计算\0,所以遇到\0停止
    {
        pstr++;         //将字符串地址进行++
    }
  return pstr-str;      //用\0位置的地址减去首地址则为字符串长度。
}

3.指针关系运算

指针还可以进行关系运算,但是标准规定:允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

95e682f823ea40a79cd5cc3e0bf60470.png

正确

void print(int* arr)
{
    for (int* i = arr; i < &arr[arr_lenght];)
    {
        printf("%d", *i++); //对指针进行++达到遍历数组的效果
    }
}
int main()
{
    int arr[arr_lenght] = { 1,2,3,4,5,6,7,8,9,0 };
    print(arr);
}

错误

  • 此种办法在一些编译器下可以运行,但是我们要避免这么写!
void print(int* arr)
{
    for (int* i = &arr[arr_lenght-1]; i >= &arr[0];)
    {
        printf("%d", *i--);
    }
}
int main()
{
    int arr[arr_lenght] = { 1,2,3,4,5,6,7,8,9,0 };
    print(arr);
}

二、指针与数组

代码示例:

#include <stdio.h>
int main()
{
  int arr[10] = {1,2,3,4,5,6,7,8,9,0};
  printf("%p\n", arr);
  printf("%p\n", &arr[0]);
  return 0;
}


d2f03bc07d0a49bc8b54a7fac2ec174f.png

我们看到数组名的地址与首元素的地址相等,那么数组名就是首元素的地址,这是在大多数情况,不过也有例外

  • 两种特殊情况,数组名代表整个数组

(1)当sizeof(数组名)

#include <stdio.h>
int main()
{
  int arr[10] = {1,2,3,4,5,6,7,8,9,0};
  int sz = sizeof(arr);
    printf("%d",sz);      //输出40
}

数组大小为40,40就是整个数组的大小

(2)当 &数组名 时

#include <stdio.h>
int main()
{
  int arr[10] = {1,2,3,4,5,6,7,8,9,0};
  printf("%p\n", arr);
  printf("%p\n", &arr);
  printf("%d\n", arr + 1);
  printf("%d\n", &arr + 1);
}


618aceec08b944ca99bf44c42d85f657.png

我们看到&arr+1加了28(10进制的40),加的其实就是整数数组的大小

三、二级指针

我们知道指针存放的其实就是变量的地址,但实质上指针也是一个变量,那么就需要一个可以用来存储指针的变量,我们称它为二级指针。(存放二级指针还可以用三级指针,存放三级指针还可以….)。

代码示例

#include <stdio.h>
int main()
{
  int a = 10;
    int *pa = &a;     //int 是指针指向变量的类型 *表示pa是个指针变量。
    int **ppa = &pa;    //int* 是指针指向变量的类型 *表示ppa是个指针。
    printf("%d",a);     //10
    printf("%d",*pa);   //10 要拿到一级指针的值需要解引用一次  
    printf("%d",**pa);    //10 要拿到二级指针的值需要解引用两次
}

77f14982cd29435d881a82c716b074b5.png

  • pa存放的是a的地址,ppa存放的是pa的地址

四、指针数组

指针数组是存放指针的数组,注意要和数组指针区分开,数组指针是指存放数组的指针。

  • 数组不仅可以存储char、short、int等等的基本数据类型,还可以存储指针
#include <stdio.h>
int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
  int* arr[3] = {&a,&b,&c};   //指针数组就是数组的每个位置都存储一个地址
}

完结

创作不易,还请各位小伙伴多多点赞👍关注✨收藏⭐



d89241b7267e47efa46e331647af0e19.gif




















相关文章
|
16天前
|
存储 C语言 数据格式
【C语言基础考研向】03混合运算和printf讲解
本文分为两部分。第一部分介绍了C语言中的混合运算与类型强制转换的重要性,通过实例展示了当整型数进行除法运算且结果为小数时,必须使用类型转换才能正确存储浮点数结果。第二部分详细讲解了`printf`函数的功能与使用方法,包括格式化输出不同类型数据的基本语法,并通过具体示例演示了如何利用字段宽度和对齐方式来控制输出格式,帮助读者更好地理解和掌握输出格式的控制技巧。
26 10
|
16天前
|
存储 C语言
【C语言基础】一篇文章搞懂指针的基本使用
本文介绍了指针的概念及其在编程中的应用。指针本质上是内存地址,通过指针变量存储并间接访问内存中的值。定义指针变量的基本格式为 `基类型 *指针变量名`。取地址操作符`&`用于获取变量地址,取值操作符`*`用于获取地址对应的数据。指针的应用场景包括传递变量地址以实现在函数间修改值,以及通过对指针进行偏移来访问数组元素等。此外,还介绍了如何使用`malloc`动态申请堆内存,并需手动释放。
|
16天前
|
存储 编译器 C语言
【C语言基础考研向】09 一维数组
数组是一种有序集合,用于存储相同类型的数据,便于统一操作与管理。例如,将衣柜底层划分为10个格子存放鞋子,便于快速定位。在C语言中,数组定义格式为 `类型说明符数组名[常量表达式];`,如 `int a[10];` 表示定义了一个包含10个整数的数组。数组初始化时可以直接赋值,也可以部分赋值,且数组长度必须固定。数组在内存中连续存储,访问时需注意下标范围,避免越界导致数据异常。数组作为参数传递时,传递的是首地址,修改会影响原数组。
|
16天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
19天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
19天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
|
24天前
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
1月前
|
搜索推荐 C语言
指针与数组
指针与数组
50 9
|
1月前
|
存储 编译器 数据处理
【编程秘籍】解锁C语言数组的奥秘:从零开始,深入浅出,带你领略数组的魅力与实战技巧!
【8月更文挑战第22天】数组是C语言中存储同类型元素的基本结构。本文从定义出发,详述数组声明、初始化与访问。示例展示如何声明如`int numbers[5];`的数组,并通过下标访问元素。初始化可在声明时进行,如`int numbers[] = {1,2,3,4,5};`,编译器自动计算大小。初始化时未指定的元素默认为0。通过循环可遍历数组,数组名视为指向首元素的指针,方便传递给函数。多维数组表示矩阵,如`int matrix[3][4];`。动态数组利用`malloc()`分配内存,需用`free()`释放以避免内存泄漏。掌握这些技巧是高效数据处理的基础。
55 2
|
1月前
|
存储 编译器 C语言
【C语言篇】深入理解指针2
代码 const char* pstr = "hello world."; 特别容易让初学者以为是把字符串 hello world.放 到字符指针 pstr ⾥了,但是本质是把字符串 hello world. 首字符的地址放到了pstr中。