首页 > 其他分享 >浅谈C语言指针的运用(函数与指针、数组与指针)

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

时间:2023-06-15 12:23:30浏览次数:41  
标签:函数 int void C语言 add printf 指针 浅谈

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

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

标签:函数,int,void,C语言,add,printf,指针,浅谈
From: https://www.cnblogs.com/zzinvincible/p/17482128.html

相关文章

  • 浅谈 .NET 中的对象引用、非托管指针和托管指针
    目录前言一、对象引用二、值传递和引用传递三、初识托管指针和非托管指针四、非托管指针1、非托管指针不能指向对象引用2、类成员指针五、托管指针 前言#本文主要是以C#为例介绍.NET中的三种指针类型(本文不包含对于函数指针的介绍):对象引用、非托管指针、......
  • 【LeetCode双指针】合并两个有序数组,从后向前遍历
    合并两个有序数组https://leetcode.cn/problems/merge-sorted-array/给你两个按非递减顺序排列的整数数组nums1和nums2,另有两个整数m和n,分别表示nums1和nums2中的元素数目。请你合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。注意:最终,合并后数......
  • VScode配置C语言环境
    0.前言运行系统为【Windows11专业版】1.安装VScode 官网下载 VScode或使用电脑自带【MicrosoftStore】(微软商店)下载。2.运行配置VScode3.安装编译器(MinGW-W64GCC)下载地址官网:MinGW-w64蓝奏云:https://hyborn.lanzouw.com/iqb1x0i0wwjc密码:0000下载完成后把压缩......
  • 浅谈 thinkphp composer 扩展包加载原理
    浅谈thinkphpcomposer扩展包加载原理本文将介绍ThinkPHP中Composer扩展包的加载原理,帮助读者更好地理解和应用该功能。前言如题,今天感觉好久没有更新博客了。最近迷上了物联网开发。一直在研究stm32、51这些东西。想起来前几天群里面有人问到tp扩展包原理。其实这个前......
  • 哈希搜索算法及C语言实现
    一、哈希搜索算法原理哈希搜索,也叫散列查找,是一种通过哈希表(散列表)实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景,其时间复杂度最高为O(1),而平均情况下的时间复杂度通常相当接近O(1),因此在实际应用中具有很高的效率和性能。哈......
  • [C语言/PTA] 学生成绩链表处理
    题目要求本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。函数接口定义:structstud_node*createlist();structstud_node*deletelist(structstud_node*head,intmin_score);函数createlist利用scanf从输入......
  • [C语言/PTA] 单链表结点删除
    题目要求本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:structListNode{intdata;ListNode*next;};函数接口定义:structListNode*readlist();structListNode*deletem(structListNode*L,intm);......
  • [C语言/PTA] 建立学生信息链表
    题目要求本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。函数接口定义:voidinput();该函数利用scanf从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下:structstud_node{intnum;/*学号*/charnam......
  • WPF之浅谈数据模板(DataTemplate)
    数据模板有什么用简而言之,数据模板能让你更方便、更灵活的显示你的各类数据。只有你想不到,没有它做不到的(感觉有点夸张,实践之后,你就觉得一点不夸张......
  • StringPtr StringPtrs 字符串指针 字符串指针切片
    funcBoolPtr(vbool)*bool{  return&v}funcStringPtr(vstring)*string{  return&v} funcStringPtrs(vals[]string)[]*string{  ptrs:=make([]*string,len(vals))  fori:=0;i<len(vals);i++{    ptrs[i]=&v......