指针与数组

目录

什么是指针

指针知识点

取地址符(&),解引用(*),指针类型

const对指针变量的修饰

assert断⾔

指针运算

什么是野指针,野指针的危害

二级指针

 字符指针变量

《剑指offer》中收录了⼀道和字符串相关的笔试题

指针与数组知识点

指针数组

数组指针

总结


什么是指针

CPU访问内存中的某个字节空间,必须知道这个字节空间在内存的什么位置,⽽因为内存中字节很多,所以需要给内存进⾏编址 ,有了这个内存单元的编 号,CPU就可以快速找到⼀个内存空间。在计算机中我们把内存单元的编号成为地址,这个地址可以理解为指针。

指针知识点

取地址符(&),解引用(*),指针类型

我们可以通过取地址操作符(&)拿到的地址,然后通过*对地址进行解引用。

#include <stdio.h>
int main()
{
 int a = 10;
 int * pa = &a;    //pa是一个变量存的是a的地址,int *的意思是*表明pa是指针变量
                   //int是指pa指向是一个整形类型
 printf("%d",*pa);//*是对指针变量进行解引用
 return 0;
}

 通过上述的解释其实已经很好的初步理解指针是什么和怎么用。

补充:void *  无具体类型的指针(泛型指针),可以接受不同类型的地址,但无法直接进行指针运算,主要使用在函数参数部分,用来接受不同类型数据的地址。   

const对指针变量的修饰

const修饰变量的时候叫常量,被修饰的变量本质还是变量,只是不能被修改。

const修饰指针变量,所修饰的内容不同因此作用也不一样

int const * p;//const 放在*的左边做修饰 

 左边:此时const限制的是*p那么此时所指向的内容是无法进行改变的,但是其指向是可以进行修改(指的是指向的地址)。

int * const p;//const 放在*的右边做修饰

右边:此时const限制的是指针的指向,但是可以通过指针变量修改其所指向的内容。 

assert断⾔

assert.h 头⽂件定义了宏 assert() ,assert() 宏接受⼀个表达式作为参数。如果该表达式为真(返回值⾮零), assert() 不会产⽣ 任何作⽤。如果不符合,就报 错终⽌运⾏,并且给出报错信息提⽰,以及包含这个表达式的⽂件名和⾏号。

assert() 有⼏个好处:它不仅能⾃动标识⽂件和 出问题的⾏号,还有⼀种⽆需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问 题,不需要再做断⾔,就在 #include 语句的前⾯,定义⼀个宏 NDEBUG 。然后,重新编译程序,编译器就会禁⽤⽂件中所有的 assert() 语句。如果程序⼜出现问题,可以移 除这条 #define NDEBUG 指令(或者把它注释掉),再次编译,这样就重新启⽤了 assert() 语 句。

缺点:因为引⼊了额外的检查,增加了程序的运⾏时间。

指针运算

指针的基本运算有三种,分别是:

指针+- 整数 :此时打印的数字是3,因为数组是连续的所以只要找到首元素的地址,通过整数相加叫可以找到所指向的元素。

#include <stdio.h>
//指针+- 整数 
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int *p = arr;//首元素地址 
 int i = 2;
 printf("p1=%d\n", *(p+i));//加整数 
 return 0;
}

指针-指针:前提是两个指针指向的是同一块空间,指针-指针的绝对值是指针与指针之间的元素个数,并不是字节数。

指针的关系运算:指针大小的比较。

什么是野指针,野指针的危害

野指针通常是因为指针变量未被正确初始化、指针释放后未被置空等原因产生的。

野指针的危害主要体现在以下几个方面:

(1)指向不可访问的地址:这种情况下,如果试图访问这个地址,可能会导致程序崩溃。

(2)指向一个可用的,但是没有明确意义的空间:这种情况下,程序可能可以正常运行,但是由于指针指向的是一个没有明确意义的空间,这可能会掩盖程序中的错误,使得错误难以发现和调试。

(3)指向一个正在被使用的空间:这是最危险的情况。如果对一个这样的指针进行解引用,并对其所指向的空间内容进行了修改,那么可能会破坏正在使用的数据,导致程序崩溃或数据损坏。

二级指针

二级指针变量是用来存放一级指针变量的地址,二级指针与二维数组没有对应的关系。

#include<stdio.h>
int main()
{
int a=10;
int *pa=&a;//pa是一级指针变量
int**ppa=&pa;//ppa是二级指针变量*ppa说明ppa是指针变量,int *是pa的类型
return 0;
}

 字符指针变量

字符指针的形式:char *p

#include<stdio.h>
int main()
{
const char *p="abcdef";//const会对内容进行限制,修改系统会进行提示
printf("%c\n",*p);//打印是首个字母
printf("%s\n",p);//打印字符串时只提供首字符的地址即可
*p='q';//无法修改,字符串的内容是无法修改的
return 0;
}

《剑指offer》中收录了⼀道和字符串相关的笔试题

#include <stdio.h>
int main()
{
 char str1[] = "hello bit.";
 char str2[] = "hello bit.";
 const char *str3 = "hello bit.";
 const char *str4 = "hello bit.";
 if(str1 ==str2)
 printf("str1 and str2 are same\n");
 else
 printf("str1 and str2 are not same\n");
 
 if(str3 ==str4)
 printf("str3 and str4 are same\n");
 else
 printf("str3 and str4 are not same\n");
 
 return 0;
}

 这个例题的答案是:

str1 and str2 are not same 

str3 and str4 are  same,为什么会这样是因为str1和str2是两个数组因此指向的地址是不一样的,str3和str4指向的是⼀个同⼀个常量字符串。C/C++会把常量字符串存储到单独的⼀个内存区域, 当⼏个指针指向同⼀个字符串的时候,他们实际会指向同⼀块内存。

指针与数组知识点

指针数组

存放指针的数组,数组的每个元素都是指针类型。例如int *p[5]就是一个含有5个指针变量的数组

#include <stdio.h>
//指针数组模拟二维数组
//指针数组 
int main()
{
	int arr[3]={1,2,3};
	int arr2[3]={4,5,6};
	int arr3[3]={7,8,9};
	int * arr4[3]={arr,arr2,arr3};//对三个数组进行存放 
	int i=0,j=0;
	for(i=0;i<3;i++)
	{
		for(j=0;j<3;j++)
		{
			printf("%d ",arr4[i][j]);
		}
		printf("\n");
	}
	return 0;
} 

数组指针

数组指针是一个指针它指向一个数组(一般是二维数组)。它的定义形式通常是 类型(*指针名)[大小]这个指针可以用来访问整个数组,而不是单个元素

#include <stdio.h>
//二维数组传参本质
void test(int(*p)[4],int a,int b)//数组指针的书写形式
{
	int i=0,j=0;
	for(i=0;i<a;i++)
	{
		for(j=0;j<b;j++)
		{
			printf("%3d",*(*(p+i)+j));//二维数组中*(p+i)==p[i]
		}
		printf("\n");
	}
	
}
int main()
{
 int arr[3][4] = {{1,2,3,4}, {5,6,7,8},{9,10,11,12}};
 test(arr, 3, 4);
 return 0;
 } 

总结

以上是最近这段时间的学习,主要涉及到指针的初识,指针与数组的联系,数组指针,指针数组之间的区别以及应用,指针是C语言的一个重要的内容因此一定要多加的练习与领悟。

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值