C讲课笔记:指针

举报
howard2005 发表于 2021/11/19 03:29:56 2021/11/19
【摘要】 文章目录 一、指针二、指针变量(一)概述(二)案例演示1、编写程序 - 演示指针变量用法.c2、运行程序,查看结果 三、指针运算(一)概述(二)案例演示1、编写程序 - 演示指向数组的指...

一、指针

在计算机内存里有很多存储单元(以字节为单位),为了便于存取数据,给每一个存储单元编号,这个编号就叫做地址(address)。在C语言里,变量的地址也叫做指针。

二、指针变量

(一)概述

专门用来存放指针的变量。如果指针是指向整型数据,那么存放该指针的变量也必须是整型的,也就是类型要保持一致。有了指针变量之后,我们访问数据就多了一种方式:间接访问方式。

(二)案例演示

1、编写程序 - 演示指针变量用法.c

/* 
  功能:演示指针变量用法
  作者:华卫
  日期:2014年5月14日  
*/
#include "stdio.h"
void main() {
    // 声明部分
    int i = 100; 
    int j = 200; 
    double x = 5.5;
    double y = 2.4;
    
    /*
      &——取址运算符
      *——取值运算符
      它们是互逆运算
    */
    
    int *p_i = &i; // 定义指向i的指针变量
    int *p_j = &j; // 定义指向j的指针变量
    double *p_x = &x; // 定义指向x的指针变量  
    double *p_y = &y; // 定义指向y的指针变量    
    
    // 输出部分
    printf("i = %d\n", i); // 通过变量名直接访问数据
    printf("j = %d\n", j); // 通过变量名直接访问数据    
    printf("i的地址:%x\n", p_i); // 输出指针变量p_i的值,即i的地址
    printf("j的地址:%x\n", p_j); // 输出指针变量p_j的值,即j的地址   
    printf("i = %d\n", *p_i); // 通过指针变量间接访问数据
    printf("j = %d\n", *p_j); // 通过指针变量间接访问数据
    
    printf("x = %f\n", x); // 通过变量名直接访问数据
    printf("y = %f\n", y); // 通过变量名直接访问数据    
    printf("x的地址:%x\n", p_x); // 输出指针变量p_x的值,即x的地址
    printf("y的地址:%x\n", p_y); // 输出指针变量p_y的值,即y的地址   
    printf("x = %f\n", *p_x); // 通过指针变量间接访问数据
    printf("y = %f\n", *p_y); // 通过指针变量间接访问数据    
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

2、运行程序,查看结果

在这里插入图片描述

三、指针运算

(一)概述

指针可以指向简单变量、数组、函数、结构体和文件,这里我们只讲述指向数组的指针,其中会涉及到指针的运算。

为了简单起见,我们拿整型数组来说明指向数组的指针。

首先,我们定义一个整型数组:int a[10];

因为数组在计算机内存里是连续存放的,所以只要我们知道第一个元素的地址,那么我们可以推算出数组其它元素的地址。首地址:&a[0],其实,数组名a的值就是数组的首地址&a[0]。

现在有一个任务,我们要遍历整个一维数组,当然可以用以前的方法,通过for循环与下表访问元素来访问每一个数组元素,这是直接遍历数组的方式。但现在我们要用一种新方法来完成这个任务。通过指向数组的指针来实现。

int *p_a;

p_a = a; 或 p_a = &a[0];

两句效果完全一样,把数组首地址保存到指针变量p_a里。

p_a —— 第一个元素的地址
p_a + 1 —— 第二个元素的地址
……
p_a + 9 —— 最后一个元素的地址

有了每个数组元素的地址,怎么访问它的数据,很简单,利用*(取值运算符)就可以得到该地址存放的数据,这是一种间接访问数据的方式。

*p_a —— 第一个元素的值
*(p_a + 1) —— 第二个元素的值
……
*(p_a + 9) —— 最后一个元素的值

这样我们可以通过指针运算来间接地遍历数组。

int i;
for (i = 0; i < 10; i++)
{
    printf("%d ", *(p_a + i));   
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

(二)案例演示

1、编写程序 - 演示指向数组的指针.c

/* 
  功能:演示指向数组的指针
  作者:华卫
  日期:2014年5月14日
*/
#include "stdio.h"
void main() {
    // 声明部分
    int i;
    int a[10] = {34, 23, 56, 345, 45, 44, 453, 5, 67, 100};
    int *p_a = a; // 定义指向数组的指针变量
    
    // 输出数组的首地址,也就是第一个元素的地址
    // 方法一:&a[0]
    printf("方法一:数组a的首地址:%x\n", &a[0]);
    // 方法二:a
    printf("方法二:数组a的首地址:%x\n", a);
    
    // 通过下标变量直接遍历数组
    printf("直接方式遍历数组:");
    for (i = 0; i < 10; i++) {
      printf("%d ", a[i]);
    }       
    printf("\n");
    
    // 通过指针变量间接遍历数组
    printf("间接方式遍历数组:");
    for(i = 0; i < 10; i++) {
      printf("%d ", *(p_a + i));
    }          
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

2、运行程序,查看结果

在这里插入图片描述

  • 其实,不定义指针变量p_a也行。
// 通过指针变量间接遍历数组
printf("间接方式遍历数组:");
for (i = 0; i < 10; i++) {
    printf("%d ", *(a + i));
}    

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

(三)课堂练习

  • 任务:利用指针统计数组元素之和。
    在这里插入图片描述

(四)案例演示

1、任务:实现字符串与数字加密

(1)编写fun()函数,该函数的功能是将字符串中字符和数字进行加密。如果是字母,转换成其后第三个,如字母A转换成D,字母X转换成A;如果是数字,转换为其前第二个,如数字3转换成1,数字1转换为9;其余字符保持不变。

(2)编写main()函数,输入一个字符串,并把转换后的字符串输出。

如输入0XAb123Yazy,则程序运行结果如下所示:

输入字符串: 0XAb123Yazy
加密字符串: 8ADe901Bdcb

2、编写程序 - 字符串与数字加密.c

/* 
  功能:字符串与数字加密
  作者:华卫
  日期:2014年5月14日
*/
#include "stdio.h"
#include "string.h"

char* fun(char* s);

void main() {  
    char* s;
 
    printf("输入字符串: ");
    gets(s); 
    printf("加密字符串: %s", fun(s));     
}

char* fun(char* s) {
    int i, len = strlen(s); 
 
    for (i = 0; i < len; i++) {
       char c = s[i];
       if (c >= 'A' && c <= 'W') {
           c = c + 3;
        } else if (c >= 'X' && c <= 'Z') {
            c = c - 23;
        } else if (c >= 'a' && c <= 'w') { 
            c = c + 3;
        } else if (c >= 'x' && c <= 'z') {
            c = c - 23;
        } else if (c >= '2' && c <= '9') {
            c = c - 2;
        } else if (c >= '0' && c <= '1') {
            c = c + 8; 
        }  
        s[i] = c;
     }   
     return s;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

3、运行程序,查看结果

在这里插入图片描述

文章来源: howard2005.blog.csdn.net,作者:howard2005,版权归原作者所有,如需转载,请联系作者。

原文链接:howard2005.blog.csdn.net/article/details/112598913

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。