浅谈C语言指针的运用(函数与指针、数组与指针)

1. 函数与指针

一个函数在编译以后会占用一定的内存,在c语言中函数一般是在栈里面,而函数名就是函数在栈中的首地址。那么接下来会讲解如何通过指针调用函数呢?用指针调用函数我们称为函数指针,指针作为一种数据类型,它指向或引用内存中的数据,那么指针同样可以用来存储函数地址(起始地址),从而可以通过指针来解引用和执行函数。
我们用这段代码来讲解

#include<stdio.h>
void PrintHello(char *name){
    printf("Hello %s\n",name);
}
int add( int a, int b)
{
    return a+b;
}
int main(){
    int c;
    int (*p)(int,int); //声明函数指针,括号里面的变量类型必须要和函数保持一致
    p = &add; //这里用函数名(add)也可以返回地址
    c = (*p)(2,3);//p(2,3)也可以
    printf("%d",c);

    void (*ptr)(char*); //因为PrintHello这个函返回的类型是void所以定义指针的时候也应该是void
    ptr = PrintHello;
    ptr("Tom");
}

此外,在函数与指针中有一个常见的问题

#include<stdio.h>
int* add( int* a, int* b)
{
    int c = (*a) + (*b);
    return &c;
}
int main(){
    int a = 2,b=4;
    int* p = add(&a,&b);
    printf("Sum = %d \n",*p);
}

此时并不能打印出我们想要的结果,因为add函数在执行完毕以后就被弹出栈空间了,所以被调函数的局部常量并不能返回给主调函数(那块内存已经被释放了)。那么如何解决这个问题呢,此时我们就需要malloc这个库函数派上用场了,它可以堆空间上单独开辟一块空间存放变量,如此一来就再也不担心被弹出栈空间了。

#include<stdio.h>
#include<stdlib.h>
int* add( int* a, int* b)
{
    int* c = (int*)malloc(sizeof(int));
    *c = (*a) + (*b);
    return c;
}
int main(){
    int a = 2,b=4;
    int* p = add(&a,&b);
    printf("Sum = %d \n",*p);
}

现在可以正常输出6!!!需要注意的是,所有在堆上申请的内存都需要用free函数显示地释放!这个示例是需要我们注意,从函数返回指针的时候,一定要注意它们的作用范围。

数组与指针

数组需要注意的是它是默认以 \0 作为定界符的。
例如:

#include<stdio.h>
int main(){
    char c[4];
    c[0] = 'J';
    c[1] = 'h';
    c[2] = 'o';
    c[3] = 'n';
    printf("%s\n",c); //会额外多输出两个乱字符

    char b[] = "hello";
    printf("Size in bytes = %d\n",sizeof(b)); //打印出来的值是6,因为是以 \0 作为定界符

    int len = strlen(b);
    printf("Length = %d\n",len);//5 strlen是计算实实在在字符串的长度
}

接下来我们用指针操作数组,重新写一个print函数,打印出数组中的所有元素。
指针操作数组关键是对指针位移的运用

void print(char *c){
    int i = 0;
    while (*(c+i) != '\0') //指针位移且解引用
    {
        printf("%c",c[i]); 
        i++; 
    }
    
}
void print(char *c){
    int i = 0;
    while (*c != '\0') //解引用
    {
        printf("%c",*c);
        c++;
    }
    
}

以上两种写法都是可以的,第二种写法累加对象是指针。
该随笔意在展示指针在函数和数组中的基础应用,还请多多指教。

posted on 2023-06-15 12:01  露露头  阅读(164)  评论(0)    收藏  举报