首页 > 其他分享 >C语言指针(三)

C语言指针(三)

时间:2024-06-22 19:58:00浏览次数:24  
标签:10 arr int C语言 数组名 数组 printf 指针

数组地址

我们知道,数组名即是数组的首地址,因此

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

我们会发现,二者地址相同即

 那么如果数组名是首地址,以下代码该怎么解释呢?

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

该代码的输出为40,如果arr是数组的首地址那么输出结果应为4,

其实:数组名是数组首元素地址是对的,只是有两例外:sizeof(数组名):sizeof中单独放数组名表示整个数组,计算的是整个数组的大小。

&数组名:这里的取的是整个数组的地址。

除此之外,数组名表示首地址。

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

此时,可以试一下这个代码,会发现三者相同,那么&arr和arr有什么区别呢,具体体现在下面

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

结果如下: 

 我们发现arr+1和arr相差四个字节,&arr[0]和&arr[0]+1相差4个字节,恰好为一个int元素的大小而&arr和&arr+1相差40,说明跳过了一整个数组。

用指针访问数组

结合前面的知识我们可以用指针访问数组:

#include <stdio.h>
int main()
{
int arr[10] = {0};
//输⼊
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
//输⼊
int* p = arr;
for(i=0; i<sz; i++)
{
scanf("%d", p+i);
//scanf("%d", arr+i);
//也可以这样写
}
//输出
for(i=0; i<sz; i++)
{
printf("%d ", *(p+i));
}
return 0;
}

因为arr是数组首元素,P指向arr那么p[i]也是可以访问的:

#include <stdio.h>
int main()
{
int arr[10] = {0};
//输⼊
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
//输⼊
int* p = arr;
for(i=0; i<sz; i++)
{
scanf("%d", p+i);
//scanf("%d", arr+i);
//也可以这样写
}
//输出
for(i=0; i<sz; i++)
{
printf("%d ", p[i]);
}
return 0;
}

这里的p[i]和*(p+i)和arr[i]以及*(arr+i)是等价的。

ps:[]其实是一个操作符

int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
//[ ]的两个操作数是arr和9。

其含义为arr+9,当然也可以写成i[arr],不过没有必要。

标签:10,arr,int,C语言,数组名,数组,printf,指针
From: https://blog.csdn.net/2301_80716048/article/details/139886192

相关文章

  • C语言---动态内存管理
    1.为什么要有动态内存分配指针+结构体+动态内存管理是学习数据结构的非常重要的知识intmain(){intn=0;//向内存申请一块空间---一个整型4个字节intarr[10]={0};//向内存中申请一块连续的空间--10个整型--40个字节return0;}这两种但是上述......
  • golang如何使用指针灵活操作内存?unsafe包原理解析
    Hi你好,我是k哥。一个大厂工作6年,还在继续搬砖的后端程序员。我们都知道,C/C++提供了强大的万能指针void*,任何类型的指针都可以和万能指针相互转换。并且指针还可以进行加减等算数操作。那么在Golang中,是否有类似的功能呢?答案是有的,这就是我们今天要探讨的unsafe包。本文将深入探......
  • C语言-运算、输出函数
    学习目标:运算输入输出函数学习内容:位运算:复合运算符条件运算符:?:问号是三目运算符,形式为:<表达式1>?<表达式2>:<表达式3>如:x>y?x+18:y-20;解释:如果x>y,则运行x+18,反之,运行y-20。逗号运算符:运算规则:先计算左侧的表达式,在计算右侧的表达式,最后返回右侧表达式的值(......
  • 数据结构:为什么说链表是顺序表的升级版(c语言实现)
    前言:  我们在之前的几篇文章中详细的讲解了顺序表的特点,增删改查操作和动态顺序表的优点,并使用顺序表的底层结构实现了通讯录项目,似乎顺序表是一个非常完美的数据结构,它可以实现按照需求实现增删查改,对内存的控制也较为合理,空间都是在需要时手动开辟的。但是顺序表真的完......
  • C语言中操作符详解(一)
    众所周知,在我们的C语言中有着各式各样的操作符,并且在此之前呢,我们已经认识并运用了许许多多的操作符,都是诸君的老朋友了昂操作符作为我们使用C语言的一个非常非常非常重要的工具,诸君一定要加以重视,认真理解,学会灵活运用。那么今天,我们就来系统的讲解一下C语言中的各式操作符......
  • C语言数据类型和变量
    ⽬录数据类型介绍signed和unsigned数据类型的取值范围变量算术操作符:+、-、*、/、%赋值操作符:=和复合赋值单⽬操作符:++、–、+、-强制类型转换scanf和printf介绍正文开始数据类型介绍C语言提供了丰富的数据类型来描述生活中的各种数据。......
  • c语言 字符串操作函数
    字符串操作函数1.strlen()函数strlen()函数用于计算字符串的长度,返回字符串的字符数。语法:size_tstrlen(constchar*str)参数:str–要计算长度的字符串。返回值:字符串的字符数。示例:#include<stdio.h>#include<string.h>intmain(){charstr[50]="......
  • C语言 内存操作函数
    内存管理进程空间程序,是经源码编译后的可执行文件,可执行文件可以多次被执行,比如我们可以多次打开office。而进程,是程序加载到内存后开始执行,至执行结束,这样一段时间概念,多次打开的wps,每打开一次都是一个进程,当我们每关闭一个office,则表示该进程结束。程序是静态概......
  • 【C语言】16.动态内存管理
    文章目录1.为什么要有动态内存分配2.malloc和free2.1malloc2.2free3.calloc和realloc3.1calloc3.2realloc4.常见的动态内存的错误4.1对NULL指针的解引⽤操作4.2对动态开辟空间的越界访问4.3对⾮动态开辟内存使⽤free释放4.4使⽤free释放⼀块动态开辟内存的⼀部......
  • 用C语言实现扫雷
    开发工具:VS2022;创建三个文件第一个头文件:game.h游戏的数据类型和函数声明的位置//游戏的数据类型和函数声明#define_CRT_SECURE_NO_WARNINGS#pragma#include<stdio.h>#include<stdlib.h>#include<time.h>#defineEASY_COUNT10#defineROW9#defineCOL9#de......