【C語言】5.C語言函數(2)

文章目錄

  • 7.嵌套調?和鏈式訪問
    • 7.1 嵌套調?
    • 7.2 鏈式訪問
  • 8.函數的聲明和定義
    • 8.1 單個?件
    • 8.2 多個?件
    • 8.3 static 和 extern
      • 8.3.1 static 修飾局部變量
      • 8.3.2 static 修飾全局變量
      • 8.3.3 static 修飾函數


7.嵌套調?和鏈式訪問

7.1 嵌套調?

嵌套調用就是函數之間的互相調用。

#include <stdio.h>void arr(){}void menu() {arr();
}int main() {menu();return 0;
}

這里 main 函數調用 menu函數。menu 函數調用 arr 函數。

函數可以嵌套調用,但是不能嵌套定義。


7.2 鏈式訪問

所謂鏈式訪問就是將一個函數的返回值作為另外一個函數的參數,像鏈條一樣將函數串起來就是函數的鏈式訪問。

#include <stdio.h>
int main()
{printf("%d\n", strlen("abcdef"));//鏈式訪問 return 0;
}

把strlen的返回值直接作為printf函數的參數,鏈式訪問 。

這個代碼執行的結果是什么?

#include <stdio.h>
int main()
{printf("%d", printf("%d", printf("%d", 43)));return 0;
}

打印:

4321 

printf 函數的返回int printf ( const char * format, ... );,也就是說printf函數返回的是打印在屏幕上的字符的個數。

printf("%d", 43)這個打印43,在屏幕上打印2個字符,再返回2。

然后printf("%d", printf("%d", 43))打印2,在屏幕上打印1個字符,再返回1。

printf("%d", printf("%d", printf("%d", 43)));打印1。

所以屏幕上最終打印:4321


8.函數的聲明和定義

8.1 單個?件

C語言編譯器對源代碼進行編譯的時候,從第一行往下掃描的,所以函數調用之前先聲明一下調用的函數。

#include <stdio.h>void menu() {}int main() {menu();return 0;
}

3-5行是函數menu的定義,第8行是函數的調用。

#include <stdio.h>int main() {menu();return 0;
}void menu() {}

如果把函數定義放在函數調用的后面就會報錯。

#include <stdio.h>void menu();int main() {menu();return 0;
}void menu() {}

這里的函數定義放在了函數調用的后面,但是第3行是函數聲明,所以就不會報錯。

函數的調用一定要滿足,先聲明后使用;

函數的定義也是一種特殊的聲明,所以如果函數定義放在調用之前也是可以的。


8.2 多個?件

一般在企業中我們寫代碼時候,代碼可能比較多,不會將所有的代碼都放在一個文件中;我們往往會根據程序的功能,將代碼拆分放在多個文件中。

一般情況下,函數的聲明、類型的聲明放在頭文件(.h)中,函數的實現是放在源文件(.c)文件中。

add.c

//函數的定義
int Add(int x, int y)
{return x+y;
}

add.h

//函數的聲明
int Add(int x, int y);

test.c

#include <stdio.h>
#include "add.h"
int main()
{int a = 10;int b = 20;//函數調用int c = Add(a, b);printf("%d\n", c);return 0;
}

運行結果:

在這里插入圖片描述


8.3 static 和 extern

作用域和生命周期:

作用域是限定這個名字的可用性的代碼范圍。

  1. 局部變量的作用域是變量所在的局部范圍。

  2. 全局變量的作用域是整個工程(項目)。

生命周期指的是變量的創建(申請內存)到變量的銷毀(收回內存)之間的一個時間段。

  1. 局部變量的生命周期是:進入作用域變量創建,生命周期開始,出作用域生命周期結束。

  2. 全局變量的生命周期是:整個程序的生命周期。


static 和 extern 都是C語言中的關鍵字:

static 是 靜態的 的意思,可以用來:

  • 修飾局部變量

  • 修飾全局變量

  • 修飾函數

extern 是用來聲明外部符號的。


8.3.1 static 修飾局部變量

#include <stdio.h>
void test()
{//static修飾局部變量static int i = 0;i++;printf("%d ", i);
}
int main()
{int i = 0;for(i=0; i<5; i++){test();}return 0;
}

打印:

1 2 3 4 5 

如果把第五行的static去掉的話,就會打印:1 1 1 1 1

我們從輸出結果來看,i的值有累加的效果,這是因為 static修飾局部變量改變了變量的生命周期。

生命周期改變的本質是改變了變量的存儲類型,本來一個局部變量是存儲在內存的棧區的,但是被 static 修飾后存儲到了靜態區。存儲在靜態區的變量和全局變量是一樣的,生命周期就和程序的生命周期一樣了,只有程序結束,變量才銷毀,內存才回收。但是作用域不變的。

使用建議:未來一個變量出了函數后,我們還想保留值,等下次進入函數繼續使用,就可以使用static修飾。


8.3.2 static 修飾全局變量

代碼1:

add.c

int g_val = 2018;

test.c

#include <stdio.h>
extern int g_val;
int main(){printf("%d\n", g_val);return 0;
}

代碼2:

add.c

static int g_val = 2018;

test.c

#include <stdio.h>
extern int g_val;
int main(){printf("%d\n", g_val);return 0;
}

extern 是用來聲明外部符號的,如果一個全局的符號在A文件中定義的,在B文件中想使用,就可以使用 extern 進行聲明,然后使用。

結果:代碼1正常,代碼2在編譯的時候會出現鏈接性錯誤。

解釋:

一個全局變量被static修飾,使得這個全局變量只能在本源文件內使用,不能在其他源文件內使用。

本質原因是全局變量默認是具有外部鏈接屬性的,在外部的文件中想使用,只要適當的聲明就可以使用;但是全局變量被 static 修飾之后,外部鏈接屬性就變成了內部鏈接屬性,只能在自己所在的源文件內部使用了。

使用建議:如果一個全局變量,只想在所在的源文件內部使用,不想被其他文件發現,就可以使用static修飾。


8.3.3 static 修飾函數

代碼1:

add.c

int Add(int x, int y)
{return x+y;
}

test.c

#include <stdio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n", Add(2, 3));return 0;
}

代碼2:

add.c

static int Add(int x, int y)
{return x+y;
}

test.c

#include <stdio.h>
extern int Add(int x, int y);
int main()
{printf("%d\n", Add(2, 3));return 0;
}

結果:代碼1是能夠正常運行的,但是代碼2就出現了鏈接錯誤。

解釋:

static 修飾函數和 static 修飾全局變量是一模一樣的,一個函數在整個工程都可以使用,被static修飾后,只能在本文件內部使用,其他文件無法正常的鏈接使用了。

本質是因為函數默認是具有外部鏈接屬性,具有外部鏈接屬性,使得函數在整個工程中只要適當的聲明就可以被使用。但是被 static 修飾后變成了內部鏈接屬性,使得函數只能在自己所在源文件內部使用。

使用建議:一個函數只想在所在的源文件內部使用,不想被其他源文件使用,就可以使用 static 修飾。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13081.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13081.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13081.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Docker安裝Mosquitto

在物聯網項目中&#xff0c;我們經常用到MQTT協議&#xff0c;用MQTT協議做交互就需要部署一個MQTT服務&#xff0c;而mosquitto是一個常用的MQTT應用服務&#xff0c; Mosquitto是一個實現了消息推送協議MQTT v3.1的開源消息代理軟件。MQTT&#xff08;Message Queuing Teleme…

python的幾個關于文本文件的demo腳本

部分來自WeTab AI PRO 1.在文末添加一行文字 def add_endline(filename, texts): # 文本末尾增加一行with open(filename, a) as file:file.write(f\n{texts})file.close() 當使用 open() 函數打開文件時&#xff0c;第二個參數指定了文件的打開模式。常見的文件打開模式包…

【LeetCode】每日一題 2024_5_14 完成所有任務需要的最少輪數(哈希)

文章目錄 LeetCode&#xff1f;啟動&#xff01;&#xff01;&#xff01;題目&#xff1a;完成所有任務需要的最少輪數題目描述代碼與解題思路 每天進步一點點 LeetCode&#xff1f;啟動&#xff01;&#xff01;&#xff01; 題目&#xff1a;完成所有任務需要的最少輪數 題…

拿到測試點如何跑

首先你要知道你測試點文件的位置,然后你要創建一個接收結果的文件,將你代碼中的std::cin替換成infile,std::cout替換成outfile即可 #include <fstream> int main() {// 打開輸入文件std::ifstream infile("C:\\Users\\Downloads\\P4779_1.in");// 打開輸出文件…

OpenCV 圖像退化與增強

退化 濾波 img_averagingcv2.blur(img2,(3,3)) #均值濾波 img_median cv2.medianBlur(img2,3) #中值濾波高斯模糊 result cv2.GaussianBlur(source, (11,11), 0)高斯噪聲 def add_noise_Guass(img, mean0, var0.01): # 添加高斯噪聲img np.array(img / 255, dtypefloat…

麒麟 V10 安裝docker2

1. 查看系統版本 2.安裝docker-ce 添加源 yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 安裝docker yum install docker-ce --allowerasing 重啟docker systemctl start docker 3.安裝nvidia-container-runtime 添…

el-tooltip 提示框樣式修改?

【element-plus el-tooltip官網地址&#xff1a; Tooltip 文字提示 | Element Plus】 <el-tooltippopper-class"Tooltip":content"content"placement"top"effect"light" ><span class"content">{{ content }}&l…

【TypeScript的JSX簡介以及使用方法】

TypeScript 是 JavaScript 的一個超集&#xff0c;它添加了靜態類型檢查和面向對象編程的特性。JSX 是一種 JavaScript 的語法擴展&#xff0c;主要用于 React 組件的聲明性渲染。TypeScript 完美地支持 JSX&#xff0c;并允許你為 React 組件和它們的 props 添加類型注解。 T…

C中Mysql的基本api接口

一、初始化參數返回值 二、鏈接服務器三、執行SQL語句注意事項 四、獲取結果集4.1mysql_affected_rows和mysql_num_rows4.2mysql_store_result與mysql_free_result注意事項注意事項整體的工作流程 4.3mysql_use_result&#xff08;&#xff09;4.4mysql_field_count&#xff08…

001 側邊欄 地址增刪改查 默認地址代碼沒完善

文章目錄 user_index.htmlmyaccount_style.cssmyaccount_scripts.jsaddress_edit.htmlReceiverAddressReceiverAddressControllerReceiverAddressServiceImplIReceiverAddressServiceRFshopAppApplicationServletInitializerpom.xmlReceiverAddressMapper.xmlReceiverAddressMa…

文件存儲解決方案-阿里云OSS

文章目錄 1.菜單分級顯示問題1.問題引出1.蘋果燈&#xff0c;放到節能燈下面也就是id大于1272.查看菜單&#xff0c;并沒有出現蘋果燈3.放到燈具下面id42&#xff0c;就可以顯示 2.問題分析和解決1.判斷可能出現問題的位置2.找到遞歸返回樹形菜單數據的位置3.這里出現問題的原因…

Golang 的 unmarshal 踩坑指南

文章目錄 1. 寫在最前面2. 字段區分出空字段還是未設置字段2.1 問題描述2.2 解決 3. 字段支持多種類型 & 按需做不同類型處理3.1 問題描述3.2 解決 4. 碎碎念5. 參考資料 1. 寫在最前面 筆者最近在實現將內部通知系統的數據定義轉化為產品定義的對外提供的數據結構。 舉例…

算法學習筆記(5.0)-基于比較的高效排序算法-歸并排序

##時間復雜度O(nlogn) 目錄 ##時間復雜度O(nlogn) ##遞歸實現歸并排序 ##原理 ##圖例 ##代碼實現 ##非遞歸實現歸并排序 ##釋 #代碼實現 ##遞歸實現歸并排序 ##原理 是一種基于分治策略的基礎排序算法。 1.劃分階段&#xff1a;通過不斷遞歸地將數組從中點處分開&…

Java 開發 框架安全:Spring 命令執行漏洞.(CVE-2022-22965)

什么叫 Spring 框架. Spring 框架是一個用于構建企業級應用程序的開源框架。它提供了一種全面的編程和配置模型&#xff0c;可以簡化應用程序的開發過程。Spring 框架的核心特性包括依賴注入&#xff08;Dependency Injection&#xff09;、面向切面編程&#xff08;Aspect-Or…

【SpringBoot筆記43】SpringBoot應用程序集成spring-boot-admin監控工具

這篇文章,主要介紹SpringBoot應用程序如何集成spring-boot-admin監控工具。 目錄 一、spring-boot-admin監控工具 1.1、創建admin-client客戶端 (1)引入依賴

DeepSpeed

文章目錄 一、關于 DeepSpeed1、DeepSpeed 是什么2、深度學習訓練和推理的極致速度和規模3、DeepSpeed 的四大創新支柱1&#xff09;DeepSpeed 訓練2&#xff09;DeepSpeed 推理3&#xff09;DeepSpeed 壓縮4&#xff09;DeepSpeed4Science 4、DeepSpeed 軟件套件DeepSpeed 庫推…

React 第二十七章 Hook useCallback

useCallback 是 React 提供的一個 Hook 函數&#xff0c;用于優化性能。它的作用是返回一個記憶化的函數&#xff0c;當依賴發生變化時&#xff0c;才會重新創建并返回新的函數。 在 React 中&#xff0c;當一個組件重新渲染時&#xff0c;所有的函數都會被重新創建。這可能會…

青少年軟件編程(Python)等級考試試卷(五級)2024年3月

2024.03 電子學會 青少年軟件編程&#xff08;Python&#xff09;等級考試試卷&#xff08;五級&#xff09; 一、單選題 1.以下代碼的輸出結果是? ) nums list(range(100, 201)) print(nums[::10]) A.[100,110,120,130,140,150,160,170,180,190,200] B.[100,101,1…

QML筆記八

QML與C交互 QML中調用C功能、使用QML或者Quick中的C接口、使用C實現自定義的QML對象 注&#xff1a; 只有QObject的派生類才能與QML交互 QML引擎集成Qt元對象系統&#xff0c;QObject的派生子類的屬性、方法、信號都可以在QML中訪問 C類可以被注冊為一個QML實例 C類可以被注冊為…

【Web后端】請求頭

1、簡介 請求頭&#xff08;Request Headers&#xff09;是在HTTP協議中&#xff0c;客戶端&#xff08;如瀏覽器或應用程序&#xff09;向服務器發送請求時附帶的元數據。包含了關于請求的額外信息&#xff0c;有助于客戶端與服務器之間的有效通信。請求頭中的信息可以讓服務…