C/C++,指针的定义和使用

概述

C语言中的指针是专门用来存放内存地址的变量。每个指都有一个与之相关联的数据类型,该类型决定了指针指向的数据的类型。
C语言中使用*把一个标识符声明为一个指针,指针定义的一般形式为:
数据类型 *指针变量名;
例如:

char *pc;
int *pi;
doule *pd = NULL;

第三行定义了一个指针并初始化为NULL,表示该指针不指向任何变量。
注意:第一行和第二行定义的指针未初始化,这是相当危险的。因为未初始化的指针随机指向内存中一个地址,对该地址空间的写操作其后果不能确定,所以应避免使用未初始化的指针,在定义指针时最好将它初始化为NULL。

与指针相关的两个运算符:

&   取地址运算符
*   取指针指向的内存单元的值

指针和数组

数组名实际上就是指向数组第一个元素的指针。
例1:以不同方式输出数组所有元素的值

#include <stdio.h> 

int main() 
{ 
    int a[10], i, *p = NULL; 

    for (i = 0; i < 10; i++) 
        a[i] = i; 
    for (i = 0; i < 10; i++) 
        printf("%d ", a[i]);
    printf("\n"); 

    for (i = 0; i < 10; i++) 
        printf("%d ", *(a + i)); 
    printf("\n"); 

    for (p = a; p < a +10; ) 
            printf("%d ", *p++); 
    printf("\n"); 

    return 0; 
} 

说明:表达式p++,++和的优先级相同,结合方式为自左向右,因此等价于*(p++)。
注意:不能对数组名执行++、–操作,比如a++是不合法的,因为a是数组的首地址,它的值在程序运行过程中是固定不变的,是常量。

数组元素也可以是指针类型,这种数组称为指针数组。
指针数组定义的一般形式为:
数据类型 *数组名[数组长度];
说明:*的优先级低于[]。

例2:指针数组和二级指针

#include <stdio.h>

int main() 
{ 
    int a[5] = {1, 3, 5, 7, 9}; 
    /*int *pi[5] = {NULL, NULL, NULL, NULL, NULL}, i;*/ 
    int *pi[5], i; 
    int **pp = pi; 

    for (i = 0; i < 5; i++){ 
        pi[i] = &a[i]; 
        printf("%d ", *pi[i]); 
    } 
    printf("\n"); 

    for (i = 0; i < 5; i++, pp++) 
        printf("%d ", **pp); 
    printf("\n"); 

    return 0; 
} 

例3:数组指针

#include <stdio.h> 

void print_arr(int (*p)[]) 
{ 
    int i; 
    for (i = 0; i < 5; i++) 
        printf("%d ", (*p)[i]); 
    printf("\n"); 
} 

int main() 
{ 
    int a[2][5] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0}; 
    int (*p)[5] = a; 

    print_arr(p); 
    p++; 
    print_arr(p); 

    return 0; 
} 

注意:区别int (*p)[5]和int *p[5],前者是一个指针,指向包含5个元素的数组。后者是一个数组,长度为5,数组中每个元素指向一个整形变量。

指针和函数

指向函数的指针

指向函数的指针是一个指针变量,它指向一个函数。一个函数的函数名就是一个指针,它指向函数的代码。
指向函数的指针的一般定义形式为:
返回值 (*指针变量名) ()
注意:前者是返回指针的函数,它是一个函数声明。后者是指向函数的指针,它定义了一个指针。

int *f(int i, int j);
int (*f)(int i, int j);

函数指针作为形参

例4:函数指针作为形参

#include <stdio.h>

int get_max(int i, int j)
{
    return (i > j? i : j);
}

int compare(int i, int j, int k, int (*p)(int, int))
{
    int ret = 0;

    ret = p(i, j);
    ret = p(ret, k);
}

int main()
{
    int ret = 0;

    ret = compare(1, 3, 5, get_max);
    printf("The max is %d.\n", ret);

    return 0;
}

补充:信号处理函数将用到该知识点。

返回函数指针的函数

例5:返回函数指针的函数

#include <stdio.h>

int get_max(int i, int j)
{
    return (i > j? i : j);
}

int (*get_function(int a))(int, int)
{
    printf("The number is %d.\n", a);

    return get_max;
}

int main()
{
    int ret = 0;
    int (*p)(int, int);

    p = get_function(100);
    ret = p(10, 15);
    printf("The max is %d.\n", ret);

    return 0;
}

说明:get_function函数返回了指向函数get_max的指针int(*)(int, int)。

字符指针和字符数组的区别

例6:字符指针和字符数组的区别

#include <stdio.h>

int main()
{
    char string[] = "Linux C";
    char *pc = "Linux C";

    string[0] = 'A';
    printf("%c\n", string[0]);

    pc[0] = 'B';
    printf("%c\n", pc[0]);
    return 0;
}

上述代码的运行结果是:

# ./a.out 
A
Segmentation fault (core dumped)

进程执行过程中提示“段错误”是因为指针pc指向的数据在内存空间中是只读(这些数据存放在.rodata段)的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值