c语言指针学习初步

指针,英文名pointer,从名字看出指针大概是指向什么东西。

在计算机科学中,指针(pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中的另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,讲地址形象化的称为"指针"。意思是通过它能找到以它为地址的内存单元。

我们可以提取出来:
指针是用来存放地址的,指针大小在32位平台上占4个字节,在64位平台上占8个字节,因为地址是由地址线产生的,在32位平台上有32条地址线产生32个1或者0的正负电信号,这个正负电信号每个占一位,构成4个字节,所以地址在32位平台共有2^32种可能。

综上,我们可以把指针看做是一个变量,该变量存放的是某个元素的地址。
在这里插入图片描述

指针使用的示例

#include <stdio.h>
int main()
{
    int a = 10;
    //声明了一个名字为p的int类型的指针
    int *p = &a; //指针变量p存放a的地址,通过地址可以找到内存单元
    return 0;
}

证明指针在64位平台都是8个字节

#include <stdio.h>
int main()
{
    printf("%d\n",sizeof(char*));
    printf("%d\n",sizeof(short*));
    printf("%d\n",sizeof(int*));
    printf("%d\n",sizeof(double*)); 
	//通过sizeof()函数探究每种指针所占空间大小,单位是字节
	return 0;

在这里插入图片描述
打印出的数字全是8,说明了全是8个字节。

现在我们来讨论指针的类型,那指针有没有类型呢,答案是

当有以下的代码

int n = 10;
p = &n;

我们想把n的地址存起来,就必须这样写

int n = 10;
int *p = &n;

那能不能这样写呢?

int n = 10;
char *p = &n;

看看底下的例子

#include <stdio.h>
int main()
{
    int a = 0x11223344;
    int *pa = &a;
    char *pb = &a;
    printf("%p\n", pa);
    printf("%p\n", pb);
    return 0;
}

打印结果如下
在这里插入图片描述
这就有疑问了,既然打印的结果都是一样的,为什么要把指针分成各种类型呢。

指针的类型决定了解应用操作时,能访问的空间大小
首先来说什么是解应用,"*"是解应用符号,这个符号能够把指针的地址解开,得到变量里面装的东西,这就是解应用的过程。

回到刚才的例子

	int n = 10;
	int *pa = &n;
	char *pb = &n;
	int x = *pa;
	int y = *pb;

虽然int型和char型的指针都能得到n的地址,但是解应用时,
x能得到完整的n,而y只能访问到n其中一个字节

指针±整数

#include <stdio.h>
int main()
{
    int n = 10;
    char *pc = (char *)&n;
    int *pi = &n;

    printf("%p\n", &n);
    printf("%p\n", pc);
    printf("%p\n", pc + 1);
    printf("%p\n", pi);
    printf("%p\n", pi + 1);
    return 0;
}

输出结果如下:
在这里插入图片描述
第二第三组差一个字节,第四第五组差4个字节
总结:指针的类型决定了指针向前走一步或者向后走一步有多大距离。

野指针

野指针就是指针指向的位置是不可知的。
比如给定数组int arr[5];
而int *parr = &arr[6];
这时的parr指针就是野指针。

野指针成因
1.指针未初始化
2.指针越界访问,向上面那个数组
3.指针指向的空间释放

如果规避野指针
1.指针初始化为NULL或者其他
2.小心指针越界
3.指针指向空间释放及时置NULL
4.检查检查检查

指针运算

指针±整数

//指针运算
//用指针的加减法运算打印数组元素
int main()
{
    int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int sz = sizeof(arr) / sizeof(arr[0]);
    int *p = &arr[9];//arr是首元素地址,不需要取地址,而arr[9]需要&
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        printf("%d ", *p);
        p--;
    }
    return 0;
}

指针-指针

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

打印结果
在这里插入图片描述
指针-指针表示了两个元素之间的距离

二级指针

指针既然也是变量,那它也有它的地址,那它的地址需要二级指针存起来。

int n = 10;
int *p = &n;//p存放n的地址
int **pp = &p//pp存放p的地址

那这个时候想要找到n的值并打印出来,要这样

printf("%d\n",**n);//对n进行两次解应用操作

指针数组

众所周知,好孩子是孩子,中国人是人,女朋友是朋友,那么,指针数组是一个数组
指针数组 - 数组 - 存放指针的数组

#include <stdio.h>
int main()
{
    int *p1, p2, p3, p4;
    p1 = p2 = p3 = p4 = NULL;
    int *parr[4] = {p1, p2, p3, p4};
    return 0;
}

用指针实现strlen()

#include <stdio.h>
int MyStrlen(char arr[])
{
    int cnt = 0;
    char *p = arr;  //数组名arr是数组首元素地址
    while (*p != 0) //当p不等于0时出循环
    {
        cnt++;
        p++;
    }
    return cnt;
}
int main()
{
    char arr[20] = {"xiaowu"};
    int str = MyStrlen(arr);

    printf("%d\n", str);
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值