C语言:指针和数组(看完拿捏指针和数组)

这篇具有很好参考价值的文章主要介绍了C语言:指针和数组(看完拿捏指针和数组)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

目录

数组名的理解:

一维数组:

 解析:

 字符数组:

 解析: 

 解析:

字符串数组:

 解析: 

 解析: 

一级指针: 

 解析: 

 解析: 

二维数组:

 解析: 

指针笔试题:

题一:一维数组

题二: 结构体指针

题三: 一维数组

题四: 二维数组

题五: 二维数组

题六: 二维数组

题七:指针数组

题八: 指针数组(多级)

以上就是个人学习见解和学习的解析,欢迎各位大佬在评论区探讨!

感谢大佬们的一键三连! 感谢大佬们的一键三连! 感谢大佬们的一键三连!


数组名的理解:

数组名是数组首元素的地址;
但是有2个例外
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节;
2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。

代码中的4/8指的是在32位或者X86环境下位4个字节,在X64环境下是8个字节。 

一维数组:

#include <stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };

	printf("%d\n", sizeof(a));//16
	printf("%d\n", sizeof(a + 0));//4/8
	printf("%d\n", sizeof(*a));//4
	printf("%d\n", sizeof(a + 1));//4/8
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4/8
	printf("%d\n", sizeof(*&a));//16
	printf("%d\n", sizeof(&a + 1));//4/8
	printf("%d\n", sizeof(&a[0]));//4/8
	printf("%d\n", sizeof(&a[0] + 1));//4/8

	return 0;
}

 解析:

1、sizeof(数组名),数组名表示整个数组,计算的是整个数组的大小,单位是字节。

2、a不是单独放在sizeof()内部,也没有取地址,所以a就是首元素的地址,a+0还是首元素的地址,是地址大小就是4/8个字节。

3、*a中的a是数组首元素的地址,*a就是对首元素的地址解引用,找到的就是首元素,首元素的大小就是4个字节。

4、这里的a是数组首元素的地址,a+1是第二个元素的地址,sizeof(a+1)就是地址的大小

5、计算的是第二个元素的大小。

6、&a取出的数组的地址,数组的地址也就是个地址。

7、&a----> int( * )[ 4 ],   *&a----->int [ 4 ]。

8、&a取出的是数组的地址,&a--> int( * )[ 4 ],&a+1是从数组a的地址向后跳过一个(4个整型元素)数组的大小,&a+1还是地址,是地址就是4/8个字节。

9、&a[ 0 ]就是第一个元素的地址,计算的是地址的大小,是地址就是4/8个字节。

10、&a[ 0 ]+1就是第二个元素的地址,大小是4/8个字节,&a[ 0 ]+1---> &a[ 1 ] 。

 字符数组:

#include <stdio.h>

int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", sizeof(arr));//6
    printf("%d\n", sizeof(arr+0));//4/8
    printf("%d\n", sizeof(*arr));//1
    printf("%d\n", sizeof(arr[1]));//1
    printf("%d\n", sizeof(&arr));//4/8
    printf("%d\n", sizeof(&arr+1));//4/8
    printf("%d\n", sizeof(&arr[0]+1));//4/8

    return 0;
}

 解析: 

1、//数组名单独放在sizeof内部,这里的arr表示整个数组,计算的是整个数组的大小,单位是字节,总共6个字节类型是char [6]。

2、//arr表示数组首元素的地址,arr+0还是数组首元素的地址,是地址就是4/8个字节,类型是char*。

3、//arr表示数组首元素的地址,*arr就是首元素,大小1个字节,类型是char。

4、//arr[1]就是第二个元素,大小是1个字节。

5、//&arr是数组的地址,但是数组的地址也是地址,是地址就是4/8。

6、//&arr + 1是跳过整个数组后的地址,是地址就是4/8个字节。

7、//第二个元素的地址,是4/8个字节。

#include <stdio.h>

int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", strlen(arr));//随机值
    printf("%d\n", strlen(arr+0));//随机值
    printf("%d\n", strlen(*arr));//错误
    printf("%d\n", strlen(arr[1]));//错误
    printf("%d\n", strlen(&arr));//随机值
    printf("%d\n", strlen(&arr+1));//随机值
    printf("%d\n", strlen(&arr[0]+1));//随机值

    return 0;
}

 解析:

1、因为字符数组arr中没有‘ \0 ’,所以在求字符串长度的时候,会一直往后找,产生的结构就是随机值。

2、arr + 0是首元素的地址,和第一个一样,也是随机值。

3、//错误, arr是数组首元素的地址,*arr就是数组首元素,就是'a'-97;
//strlen函数参数的部分需要传一个地址,当我们传递的是'a'时,'a'的ASCII码值是97,那就是将97作为地址传参。
//strlen就会从97这个地址开始统计字符串长度,这就非法访问内存了。

4、//错误

5、//&arr是数组的地址,数组的地址和数组首元素的地址,值是一样的,那么传递给strlen函数后,依然是从数组的第一个元素的位置开始往后统计。

6、//随机值

7、//&arr[0] + 1是第二个元素的地址。结果也是随机值。

字符串数组:

#include <stdio.h>

int main()
{
    char arr[] = "abcdef";// a b c d e f \0

    printf("%d\n", sizeof(arr));//7
    printf("%d\n", sizeof(arr+0));//4
    printf("%d\n", sizeof(*arr));//1
    printf("%d\n", sizeof(arr[1]));//1
    printf("%d\n", sizeof(&arr));//4/8
    printf("%d\n", sizeof(&arr+1));//4/8
    printf("%d\n", sizeof(&arr[0]+1));//4/8

    return 0;
}

 解析: 

1、//7,类型是char [7]。

2、//arr + 0是首元素的地址。

3、//*arr其实就是首元素,1个字节,理解为*arr--> *(arr+0) -- arr[0]。

4、//arr[1]是第二个元素,1个字节。

5、//&arr是数组的地址,是地址就是4/8个字节。

6、//&arr + 1是跳过一个数组的地址,4/8。

7、//&arr[0] + 1是第二个元素的地址 4/8。

#include <stdio.h>

int main()
{
    char arr[] = "abcdef";

    printf("%d\n", strlen(arr));//6
    printf("%d\n", strlen(arr+0));//6
    printf("%d\n", strlen(*arr));//错误
    printf("%d\n", strlen(arr[1]));//错误
    printf("%d\n", strlen(&arr));//6
    printf("%d\n", strlen(&arr+1));//随机值
    printf("%d\n", strlen(&arr[0]+1));//5

    return 0;
}

 解析: 

由于与上面内容相同,就不做过多解释

1、//6

2、//6

3、//err

4、//err

5、//6

6、//随机值

7、//5

一级指针: 

#include <stdio.h>

int main()
{
    char *p = "abcdef";

    printf("%d\n", sizeof(p));//4/8
    printf("%d\n", sizeof(p+1));//4/8
    printf("%d\n", sizeof(*p));//1
    printf("%d\n", sizeof(p[0]));//1
    printf("%d\n", sizeof(&p));//4/8
    printf("%d\n", sizeof(&p+1));//4/8
    printf("%d\n", sizeof(&p[0]+1));//4/8

    return 0;
}

 解析: 

1、//p是一个指针变量,大小就是4/8。

2、//p+1是'b'的地址,是地址大小就是4/8个字节。

3、//*p 就是'a'元素,就是1个字节。

4、//p[0]--> *(p+0) --> *p  1个字节。

5、//4/8,类型是&p -- char**。

6、//4/8

7、//4/8 , &p[0] + 1得到是'b'的地址 。

#include <stido.h>

int main()
{
    char *p = "abcdef";

    printf("%d\n", strlen(p));//6
    printf("%d\n", strlen(p+1));//5
    printf("%d\n", strlen(*p));//错误
    printf("%d\n", strlen(p[0]));//错误
    printf("%d\n", strlen(&p));//随机值
    printf("%d\n", strlen(&p+1));//随机值
    printf("%d\n", strlen(&p[0]+1));//5

    return 0;
}

 解析: 

由于与上面内容相同,就不做过多解释

1、//6

2、//5

3、//err

4、//err

5、//随机值

6、//随机值

7、//5

二维数组:

#include <stdio.h>

int main()
{
    int a[3][4] = {0};

    printf("%d\n",sizeof(a));//48
    printf("%d\n",sizeof(a[0][0]));//4
    printf("%d\n",sizeof(a[0]));//16
    printf("%d\n",sizeof(a[0]+1));//4/8
    printf("%d\n",sizeof(*(a[0]+1)));//4
    printf("%d\n",sizeof(a+1));//4/8
    printf("%d\n",sizeof(*(a+1)));//16
    printf("%d\n",sizeof(&a[0]+1));//4/8
    printf("%d\n",sizeof(*(&a[0]+1)));//16
    printf("%d\n",sizeof(*a));//16
    printf("%d\n",sizeof(a[3]));//16

    return 0;
}

 解析: 

1、//3*4*4 = 48

2、//4

3、//a[0]是第一行这个一维数组的数组名,数组名算是单独放在sizeof内部了,计算的是整个数组的大小,大小是16个字节。

4、//a[0]作为第一行的数组名,没有单独放在sizeo内部,没有&,a[0]表示数组首元素的地址,也就是a[0][0]的地址,所以a[0]+1是第一行第二个元素的地址,是地址就是4/8个字节。

5、//4,计算的是就是第一行第2个元素的大小。

6、//4 / 8,a是数组首元素的地址,是第一行的地址 int(*)[4],a+1 就是第二行的地址。

7、//16,*(a+1) --> a[1] -> sizeof(*(a+1))->sizeof(a[1]) 计算的是第二行的大小,a+1 --> 是第二行的地址,int(*)[4],*(a+1) 访问的第二行的数组。

8、//4/8,&a[0]是第一行的地址 int(*)[4],&a[0]+1 是第二行的地址 int(*)[4]。

9、//16 计算的是第二行的大小。

10、//计算的是第一行的大小-16,a是数组首元素的地址,就是第一行的地址,*a 就是第一行,*a --> *(a+0) --> a[0]。

11、//16,类型是a[3]--> int [4]。

指针笔试题:

题一:一维数组

#include <stdio.h>

int main()
{
     int a[5] = { 1, 2, 3, 4, 5 };

     int *ptr = (int *)(&a + 1);
     printf( "%d,%d", *(a + 1), *(ptr - 1));

     return 0;
}

注意:&a+1的类型为int( * )[ 5 ],强制转换为int( * ).此时每次移动的就是4个字节,而不是20个字节了!

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题二: 结构体指针

#include <stdio.h>
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
     printf("%p\n", p + 0x1);
     printf("%p\n", (unsigned long)p + 0x1);
     printf("%p\n", (unsigned int*)p + 0x1);

     return 0;
}

注意:整型就是正常的加减运算指针类型就需要加减n*类型的大小。 

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题三: 一维数组

#include <stdio.h>

int main()
{
     int a[4] = { 1, 2, 3, 4 };

     int *ptr1 = (int *)(&a + 1);
     int *ptr2 = (int *)((int)a + 1);
     printf( "%x,%x", ptr1[-1], *ptr2);

     return 0;
}

注意: a强制转换成int类型+1就是正常加减,最后转换为指针int计算机会向后查找四个字节。

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题四: 二维数组

#include <stdio.h>

int main()
{
     int a[3][2] = { (0, 1), (2, 3), (4, 5) };

     int *p;
     p = a[0];
     printf( "%d", p[0]);

     return 0;
}

注意: 注意二维数组中没有用{ }把数值包含,这里用的是( )是逗号表达式取最后一个值为元素a[ 0 ]可以看做&a[ 0 ][ 0 ].

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题五: 二维数组

#include <stdio.h>

int main()
{
     int a[5][5];

     int(*p)[4];
     p = a;
     printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);

     return 0;
}

注意地址相减为相差的元素个数 ,此题为-4因为求的是地址,所以需要将-4转换成补码输出。

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题六: 二维数组

#include <stdio.h>

int main()
{
     int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

     int *ptr1 = (int *)(&aa + 1);
     int *ptr2 = (int *)(*(aa + 1));
     printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));

     return 0;
}

注意:*(aa+1) = a[1] = &a[1][0]

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题七:指针数组

#include <stdio.h>

int main()
{
     char *a[] = {"work","at","alibaba"};

     char**pa = a;
     pa++;
     printf("%s\n", *pa);

     return 0;
}

注意:这里的a是指针数组,数组中每个位置的类型为char*。

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

题八: 指针数组(多级)

#include <stdio.h>

int main()
{
     char *c[] = {"ENTER","NEW","POINT","FIRST"};

     char**cp[] = {c+3,c+2,c+1,c};
     char***cpp = cp;
     printf("%s\n", **++cpp);
     printf("%s\n", *--*++cpp+3);
     printf("%s\n", *cpp[-2]+3);
     printf("%s\n", cpp[-1][-1]+1);

     return 0;
}

注意:有了上面的基础,这道题一步一步来,你们也可以解释清楚!!!

C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法

以上就是个人学习见解和学习的解析,欢迎各位大佬在评论区探讨!

感谢大佬们的一键三连! 感谢大佬们的一键三连! 感谢大佬们的一键三连!

                                              C语言:指针和数组(看完拿捏指针和数组),C语言基础整理,c语言,算法,开发语言,c++,笔记,深度学习,学习方法文章来源地址https://www.toymoban.com/news/detail-675501.html

到了这里,关于C语言:指针和数组(看完拿捏指针和数组)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C语言基础教程】函数指针与指针大小

    在C语言中,指针是一项强大的工具,用于处理内存中的数据。除了常见的指向变量和数组的指针,C语言还支持函数指针,它是一个指向函数的指针。本文将深入探讨函数指针的概念以及指针的大小在C语言中的重要性。 函数指针 是指向函数的指针变量。它允许我们在运行时

    2024年02月05日
    浏览(30)
  • C语言指针基础

    目录 前言 本期介绍内容: 一、指针是什么? 二、指针和指针类型 指针类型的意义: 三、野指针 3.1什么是野指针? 3.2野指针的成因 1.指针未初始化 2.指针越界访问 3.指针指向的那块空间已经释放(还给操作系统了) 3.3如何规避野指针 四、指针运算 4.1指针加减整数 4.2指针

    2024年02月12日
    浏览(36)
  • C语言基础之——指针(下)

    前言:本篇文章将继续讲解有关指针的剩余基础知识。 学无止境,一起加油叭!! 目录 一.指针运算 1.指针 +- 整数  2.指针的关系运算  3.指针 - 指针 二.指针与数组 三.二级指针 四.指针数组 总结 指针运算包括以下三种: 指针 +- 整数 指针 - 指针 指针的关系运算 我们尝试用

    2024年02月11日
    浏览(27)
  • C语言基础之——指针(上)

    前言:小伙伴们又见面啦!本期内容,博主将展开讲解有关C语言中指针的上半部分基础知识,一起学习起来叭!!! 目录 一.什么是指针 二.指针类型 1.指针的解引用 2.指针+-整数 三.野指针 1.野指针成因 (1)指针未初始化  (2)指针越界访问 2.如何规避野指针 四.总结 指针

    2024年02月11日
    浏览(39)
  • 【C语言基础】:深入理解指针(三)

    指针系列回顾 : 【C语言基础】:深入理解指针(一) 【C语言基础】:深入理解指针(二) 一、冒泡排序 冒泡排序的核心思想就是:两两相邻的元素进行比较。 可以看到,这段代码对arr数组进行了排序,但这个代码还有一些缺陷,那就是无论数组内部的元素是否有序,他都会循

    2024年03月10日
    浏览(32)
  • C语言-基础语法学习-3 二级指针

    当涉及到多级指针时,C语言的灵活性和强大的指针功能可以得到充分的发挥。二级指针是指指向指针的指针,也被称为指向指针的引用。 使用二级指针可以实现以下功能: 动态内存分配:通过二级指针可以动态地分配内存块,并将其地址传递给其他函数或模块进行操作。这

    2024年02月12日
    浏览(35)
  • C语言 指针声明和定义 - C语言零基础入门教程

    目录 [一.指针简介] [1.内存] [2.内存地址] [3.指针声明] [二.指针类型] [三.声明并初始化一个指针] [1.声明指针并直接初始化 – 推荐] [2.先声明指针在初始化 – 不推荐] [四.查看指针地址和指针的值] [五.NULL 指针 – 空指针] [六.重点总结] [七.猜你喜欢] 零基础 C/C++ 学习路线推荐

    2024年03月22日
    浏览(32)
  • 逍遥自在学C语言 | 指针的基础用法

    在C语言中,指针是一项重要的概念,它允许我们直接访问和操作内存地址。 可以说,指针是C语言一大优势。用得好,你写程序如同赵子龙百万军中取上将首级;用得不好,则各种问题层出不穷,有种双拳难敌四手的感觉。 本文将介绍指针的基础知识,包括指针的定义、初始

    2024年02月09日
    浏览(32)
  • C语言基础之——数组

    前言:本篇文章,我们将对一维数组,和二维数组进行展开式的讲解,并进行实际应用。 目录 一.一维数组 1.一维数组的创建和初始化 (1)数组的创建 (2)数组的初始化  2.一维数组的使用 3.一维数组在内存中的存储 二.二维数组 1.二维数组的创建与初始化 (1)数组的创建

    2024年02月11日
    浏览(25)
  • 初学Verilog语言基础笔记整理(实例点灯代码分析)持续更新~

    实例:点灯学习 刚接触 Verilog ,作为一个硬件小白,只能尝试着去理解,文章未完…持续更新。 参考博客文章: Verilog语言入门学习(1) Verilog语法 【 Verilog 】一文带你了解 Verilog 基础语法 - 子墨祭的文章 - 知乎 关于Verilog中的几种赋值语句 这里抄点,那里扣点,整理了一

    2024年02月07日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包