资讯专栏INFORMATION COLUMN

C语言中的指针初阶

jubincn / 3427人阅读

摘要:语言中的指针初阶指针是什么指针和指针类型野指针指针的运算指针和数组二级指针指针数组指针是什么指针是什么初学者都有一个疑问,那就是指针是什么简单的说,就是通过它能找到以它为地址的内存单元。是用来存放地址指针,所以是指针变量。

C语言中的指针初阶

1.指针是什么
2. 指针和指针类型
3. 野指针
4. 指针的运算
5. 指针和数组
6. 二级指针
7. 指针数组

1.指针是什么

​ 初学者都有一个疑问,那就是指针是什么?简单的说,就是通过它能找到以它为地址的内存单元

地址指向了一个确定的内存空间,所以地址形象的被称为指针。

int main(){	int a = 10;	int* pa = &a;        return 0;}//pa是用来存放地址(指针),所以pa是指针变量。

总结:指针就是变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)。

​ 地址是唯一标识一块空间的。

​ 指针的大小在32位平台是4个字节,在64位平台是8个字节。

2.指针和指针类型

​ 我们知道变量有不同的类型(整型、浮点型、字符型等),其实指针也是有不同类型的。

​ 指针类型的意义1:
指针类型决定了指针解引用操作的时候,一次访问几个字节(访问内存的大小)
char* 指针解引用访问1个字节
int* 指针解引用访问四个字节

int main(){	char* pc = &a;	*pc = 0;    	return 0;}

​ 指针类型的意义2:
指针类型决定了,指针±整数的时候的步长(指针±整数的时候,跳过几个字节)
int* 指针+1 跳过四个字节
char* 指针+1 跳过一个字节

int main(){	int a = 10;	int* pa = &a;	char* pc = &a;	printf("%p/n", pa);	printf("%p/n", pc);	printf("%p/n", pa+1);	printf("%p/n", pc+1);	return 0;}

3.野指针

​ 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)。

3.1野指针成因

  1. 指针未初始化
int main(){    int* p;//局部变量指针未初始化,默认为随机值    *p = 20;//通过p中存的随机值作为地址,找到一个空间,这个空间不属于我们当前的程序    //就造成了非法访问,p就是野指针        return 0;}
  1. 指针越界访问
int main(){    int arr[10] = 0;    int i = 0;    int* p = arr;        for(i =0; i <= 10; i++)    {        *p = i;        p++;//当指针指向的范围超出数组arr的范围时,p就是野指针    }        return 0;}
  1. 指针指向的空间释放
int* test(){    int a = 10;    return &a;}int main(){    int* p = test();    printf("%d/n",*p);        return 0;}

3.2如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放即使置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性
int main(){    int a = 10;    int* p = &a;//明确地初始化,确定指向        int* p2 = NULL;//不知道一个指针当前应该指向哪里时,可以初始化为NULL        return 0;}

4.指针的运算

4.1指针±整数

#define N_VALUES 5float values[N_VALUES];float* vp;for(vp = &values[0]; vp < &values[N_VALUES];){    *vp++ = 0;}
int main(){    int arr[10] = {1,2,3,4,5,6,7,8,9,0};    int* p = &arr[9];        printf("%p/n",p);    printf("%p/n",p-2);        return 0;}

4.2指针-指针

​ 指针-指针 得到的数字的绝对值是指针和指针之间元素的个数

int main(){	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };	printf("%d/n", &arr[9] - &arr[0]);	printf("%d/n", &arr[0] - &arr[9]);    	return 0;}

指针-指针 的前提是两个指针指向同一块区域

int main(){    int arr[10] = {1,2,3,4,5,6,7,8,9,0};    char ch[5] = {0};    printf("%d/n",&arr[9] - &ch[0]);//err        return 0;}

应用 求字符串长度

int my_strlen(char* s){	int count = 0;	char* start = s;	while(*s!="/0")	{		s++;	}	return s - start;}int main(){	char arr[] = "abcdef";	int len = my_strlen(arr);	printf("%d/n", len);    	return 0;}

4.3指针的关系运算

#define N_VALUES 5float values[N_VALUES];float *vp;for(vp = &values[N_VALUES]; vp > &values[0];){    *--vp = 0;}

上述程序也可以写成这样

for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--){    *vp = 0;}

实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这么写,因为标准并不保证它可行。

标准规定

​ 允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。

5.指针和数组

数组 - 是一块连续的空间,放的是相同类型的元素

数组大小和元素类型,元素个数有关系

指针(变量) - 是一个变量,放地址

指针变量的大小 是4(32bit)/8(64bit)个byte

数组名确实是首元素地址
但是有两个例外

  1. sizeof(数组名) - 这里的数组名不是首元素的地址,是表示整个数组的,这里计算的是整个数组的大小,单位还是字节。
  2. &数组名 - 这里的数组名不是首元素的地址,是表示整个数组的,拿到的是整个数组的地址
int main(){	int arr[10] = { 0 };	int sz = sizeof(arr);	printf("%d/n", sz);	return 0;}
int main(){	int arr[10] = { 0 };	int* p = arr;	int i = 0;	int sz = sizeof(arr) / sizeof(arr[0]);	for (i = 0;i < sz;i++)	{		*(p + i) = i;	}	for (i = 0;i < sz;i++)	{		printf("%d ", *(p + i));	}	return 0;}

6.二级指针

​ 我们都知道,指针变量是变量,是变量就有地址,那么指针变量的地址存放在哪里呢?

这就是我们要了解的二级指针。

int main(){    int a = 10;    int* p = &a;    int** pp = &p;//pp就是二级指针    **pp = 20;    printf("%d/n", a);//a = 20    return 0;}

7.指针数组

​ 从名字上来看,大家觉得指针数组是指针还是数组?

答案是数组,是存放指针的数组。

整型数组 - 存放整型的数组就是整型数组
字符数组 - 存放字符的数组就是字符数组
指针数组 - 存放指针的数组就是指针数组
int* 整型指针的数组
char* 字符指针的数组

int main(){	int arr[10];	char ch[5];    	int* parr[5];	char* pc[6];	return 0;}
int main(){	int a = 10;	int b = 20;	int c = 30;	int* parr[3] = { &a,&b,&c };	for (int i = 0;i < 3;i++)	{		printf("%d/n", *(parr[i]));	}	return 0;}

​ 以上就是我们初始C语言指针的全部内容了,后续我还会更新C语言指针的进阶版本,希望大家能够对C语言的指针能够有更深层次的了解。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/121797.html

相关文章

  • C语言学习笔记—P15(指针初阶>+图解+题例)

    摘要:变量占用个字节的空间,这里是将的个字节的第一个字节的地址存放在变量中,就是一个之指针变量。是指针变量作者新晓故知总结指针变量,用来存放地址的变量。 目录 前言:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!                           ...

    weknow619 评论0 收藏0
  • 详细讲解 —— 数组(C语言初阶

    摘要:也可以理解成二维数组有三个元素,每个元素是一个一维数组我们可以把二维数组想象成一个几行几列的数组但是本质上的二维数组是一列的。数组名,计算整个数组的大小,内部单独放一个数组名,数组名表示整个数组。数组名,数组名表示整个数组。 目录 1. 一维数组 1.1 数组的创建和初始化 数组的创建: 数...

    Backache 评论0 收藏0
  • C语言初阶】❤️ 教你使用C语言中的各种操作符(熟练运用+必须收藏)❤️

    本章目录 温馨提示本章重点正文开始1. 操作符分类2.算数操作符2.1 `/`操作符2.2 `%`操作符 3. 位移操作符3.1 ``左移操作符 4. 位操作符4.1 `&`按位与操作符4.2 `|`按位或操作符4.3 `^`按位异或操作符 5. 赋值操作符6. 单目操作符6.1 各种单目操作符6.2 sizeof 和 数组 7. 关系操作符(后面的操作符不单独出现在目录中)8. ...

    source 评论0 收藏0
  • 【数据结构初阶之二叉树】:二叉树相关的性质和经典的习题(用C语言实现,附图详解)

    摘要:当集合为空时,称该二叉树为空二叉树。也就是说,如果一个二叉树的层数为,且结点总数是,则它就是满二叉树。完全二叉树完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。 ...

    Martin91 评论0 收藏0
  • 初阶数据结构——二叉树

    摘要:想快速入门数据结构,推荐订阅作者的初阶数据结构专栏此专栏预计更新顺序表,链表,栈,队列,二叉树,排序算法等等初阶数据结构我们通过语言实现,所以此专栏也可以帮助大家巩固大家的语言知识源代码已上传至我的码云前言我们在 ...

    lushan 评论0 收藏0

发表评论

0条评论

jubincn

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<