强化C【C语言笔记】——指针

c

地址指针的基本概念

为了正确地访问这些内存单元,必须为每个内存单元编上号。根据一个内存单元的编号(地址)即可准确地找到该内存单元;所以通常也把内存单元的编号(地址)称为指针

在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。因此,一个指针变量的值就是某个内存单元的地址或称为某内存单元的指针

变量的指针和指向变量的指针变量

变量的指针就是变量的地址。存放变量地址的变量是指针变量;一个指针变量的值就是某个变量的地址或称为某变量的指针

定义一个指针变量

其一般形式为:
类型说明符  *变量名;
类型说明符表示本指针变量所指向的变量的数据类型

指针变量的引用

指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。未经赋值的指针变量不能使用,否则将造成系统混乱,甚至死机

C语言中提供了地址运算符&来表示变量的地址
其一般形式为:   &变量名;

指针变量作为函数参数

 函数的参数不仅可以是整型、实型、字符型等数据,还可以是指针类型。它的作用是将一个变量的地址传送到另一个函数中

指针变量运算

  • 指针运算符

    • 取地址运算符:&

    • 取内容预算符:*

  • 指针变量的赋值运算

    • 指针变量初始化赋值

    • 变量的地址赋予同数据类型的指针变量

    • 指针变量的值赋予相同数据类型的指针变量

    • 数组首地址赋予指向指针变量

    • 字符串的首地址赋予指向字符类型的指针变量

    • 函数的入口地址赋予指向函数的指针变量

  • 指针变量的加减算术运算
    对于指向数组的指针变量,可以加上或减去一个整数n

  • 两个指针变量之间的运算
    只有指向同一数组的两个指针变量之间才能进行运算
    可进行:两指针变量相减、两指针变量进行关系运算

数组指针和指向数组的指针变量

指向数组元素的指针

一个数组元素的首地址也是指它所占有的几个内存单元的首地址

数组指针变量说明的一般形式为:
类型说明符  *指针变量名;

几个注意的问题

  • 指针变量可以实现本身的值的改变,如p++是合法的;而数组名a进行a++是错误的。因为a是数组名,它是数组的首地址,是常量

  • *p++,由于++和*同优先级,结合方向自右而左,等价于*(p++)

  • (*p)++表示p所指向的元素值加1

数组名作函数参数

数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址,形参得到该地址后也指向同一数组;
同样,指针变量的值也是地址,数组指针变量的值即为数组的首地址,当然也可作为函数的参数使用

指向多维数组的指针和指针变量

多维数组的地址

设有整型二维数组a[3][4]如下:
0   1   2   3
4   5   6   7
8   9  10  11
它的定义为:int a[3][4]={{0,1,2,3},{4,5,6,7},{8,9,10,11}}
设数组a的首地址为1000,各下标变量的首地址及其值如图所示

指向多维数组的指针变量

二维数组指针变量说明的一般形式为:
类型说明符  (*指针变量名)[长度]

“*”表示其后的变量是指针类型。“长度”表示二维数组分解为多个一维数组时,一维数组的长度,也就是二维数组的列数

字符串的指针指向字符串的指针变量

字符串的表示形式

  • 用字符数组存放一个字符串,然后输出该字符串

  • 用字符串指针指向一个字符串

使用字符串指针变量与字符数组的区别

两者是有区别的。在使用时应注意以下几个问题

  • 字符串指针变量本身是一个变量,用于存放字符串的首地址。而字符串本身是存放在以该首地址为首的一块连续的内存空间中并以‘\0’作为串的结束。字符数组是由于若干个数组元素组成的,它可用来存放整个字符串

  • 对字符串指针方式
    char *ps="C Language";
    可以写为:
    char *ps;
    ps="C Language";
    而对数组方式:
    static char st[]={"C Language"};
    不能写为:
    char st[20];
    st={"C Language"};
    字符串数组只能对字符数组的各元素逐个赋值

函数指针变量

一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址

函数指针变量定义的一般形式为:
类型说明符  (*指针变量名)();

“类型说明符”表示被指函数的返回值的类型。“(* 指针变量名)”表示“*”后面的变量是定义的指针变量。最后的空括号表示指针变量所指的是一个函数
表示该函数是一个指向函数入口的指针变量

函数指针变量形式调用函数的步骤如下

  • 先定义函数指针变量

  • 把被调函数的入口地址(函数名)赋予该函数指针变量

  • 用函数指针变量形式调用函数

  • 调用函数的一般形式为:
    (*指针变量名) (实参表)

    • 函数指针变量不能进行算术运算

    • 函数调用中"(*指针变量名)"的两边的括号不可少,此处它只是一种表示符号

指针型函数

函数类型是指函数返回值的类型
在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针型函数

定义指针型函数的一般形式为:
类型说明符 *函数名(形参表) 

        ……          /*函数体*

函数名之前加了“*”号表明这是一个指针型函数,即返回值是一个指针

指针数组和指向指针的指针

指针数组

一个数组的元素值为指针则是指针数组;指针数组是一组有序的指针的集合。 指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量

指针数组说明的一般形式为:
类型说明符 *数组名[数组长度]

指向指针的指针

如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的指针变量

通过指针访问变量称为间接访问。由于指针变量直接指向变量,所以称为“单级间址”。而如果通过指向指针的指针变量来访问变量则构成“二级间址“

main函数的参数

实际上,main函数可以带参数,这个参数可以认为是 main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv
main (argc,argv)

C语言还规定argc**(第一个形参)必须是整型变量**,argv**( 第二个形参)必须是指向字符串的指针数组**
main (int argc,char *argv[])

在何处把实参值赋予main函数的形参呢? 实际上,main函数的参数值是从操作系统命令行上获得的

相关文章

【数据结构】——哈夫曼树

速通回忆 这里是完整的代码和运行结果,可以直接选择看下面代码的思路去快速回忆哈夫曼树,或从下面理论部分开始学习 ``` #include "stdio.h" #include "stdlib.h" /* 哈夫曼树结点的结构体 */ typedef struct { int weight; /* 权重 */ int parent; /* 父母结点下标 */ int l...

c

强化C【C语言笔记】——位运算

位运算符C语言提供了六种位运算符 - &:按位与 - !:按位或 - ^:异或 - ~:取反 - <<:左移 - \>>:右移 按位与运算 **其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0** 按位与运算通常用来对某些位清0 按位或运算 **其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就...

c

C语言中规中矩的大树

**没事干,写个树玩玩,真正的“撸树”** 在Ubuntu终端、VScode终端显示 代码 ``` #include "stdio.h" int main(){ int high = 5; //层高 int count = 5; //层数 int start; //每层开始*数 int...

c