文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言中的指针 初阶

2024-04-02 19:55

关注

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野指针成因

指针未初始化


int main()
{
    int* p;//局部变量指针未初始化,默认为随机值
    *p = 20;//通过p中存的随机值作为地址,找到一个空间,这个空间不属于我们当前的程序
    //就造成了非法访问,p就是野指针
    
    return 0;
}

指针越界访问


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;
}

指针指向的空间释放


int* test()
{
    int a = 10;
    return &a;
}

int main()
{
    int* p = test();
    printf("%d\n",*p);
    
    return 0;
}

3.2如何规避野指针


int main()
{
    int a = 10;
    int* p = &a;//明确地初始化,确定指向
    
    int* p2 = NULL;//不知道一个指针当前应该指向哪里时,可以初始化为NULL
    
    return 0;
}

4.指针的运算

4.1指针±整数


#define N_VALUES 5
float 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 5
float 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

数组名确实是首元素地址

但是有两个例外:


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语言中的指针内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯