日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言程序设计 | 指针(二):常量指针和指针常量、数组参数和指针参数、函数指针数组

發布時間:2024/4/11 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言程序设计 | 指针(二):常量指针和指针常量、数组参数和指针参数、函数指针数组 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

指針的進階(二)目錄:

  • 常量指針和指針常量
  • 數組參數和指針參數
  • 函數指針數組

常量指針和指針常量

在我們日常中,經常會用到一個關鍵字const

const是一個C語言(ANSI C)的關鍵字,具有著舉足輕重的地位。它限定一個變量不允許被改變,產生靜態作用。使用const在一定程度上可以提高程序的安全性和可靠性。

合理的運用const可以大幅度的提高代碼的安全性和可讀性。
但是在指針中,const該如何運用呢?

對于上面兩種情況,大多數人很容易就把第一個指針當成了常指針,但是卻并非如此。
第一個其實是一個,第二個才是常量指針。
定義時const位于 * 前面是常量指針,const位于*后面是指針常量。

1.常量指針

即指向常量的指針

因為它指向的對象是一個常量,所以該指針的值無法修改,但是可以修改它指向的對象

編譯器提示我們不能進行修改。

而當我們去修改它所指向的對象的時候,編譯就通過了。

2.指針常量


這個就與上面的剛好相反的,這個指針本身就是一個常量,所以不能改變它所指向的對象,但我們能夠改變指向對象的數值。


我們試圖去修改它所指向的對象,編譯不通過。

我們試圖去修改它所指向的對象的值,編譯通過。

指向常量的指針常量


指向常量的指針常量其實就是將上述的兩個結合了起來
當我們既不想讓別人修改我們指向的對象,也不想讓別人修改指向對象的值時,我們就可以用這個來實現。


數組參數和指針參數

在我們寫代碼的時候經常會把指針和數組作為參數傳給數組,那函數的參數該如何設計呢?

一維數組傳參

假設我們存在一個大小為10的數組,當我們將其作為參數傳給函數時

會驚奇的發現,當我們不填數組元素個數時,我們傳參成功了。當我們填寫的元素個數大于數組大小時,傳參竟然也成功了。
同時我們在函數中用sizeof來判斷數組大小時,我們得到的結果是4。
結合這兩點,我們發現,C語言傳參時為了效率和節約空間,并不會直接傳整個數組,而是轉為傳指針,指針指向數組首元素的地址,這又就是為什么我們無論下標中填寫多少都沒有問題的原因。
所以我們傳遞參數的形式其實應該是這樣


二維數組傳參

當我們在傳遞二維數組的時候,如果還像剛剛一樣,就會出現問題了
![在這里插入圖片描述](https://img-blog.csdnimg.cn/20191110194548757.png
我們發現了一個問題,上面的三個只有中間編譯通過,所以二維數組并不能完全省略下標的內容,第二個下標中必須要填寫數字,這又是為什么呢?
我們對arr進行+1,查看它地址的變化


我們發現它+1加了20,是一列的大小。

在第一節中我說過,指針的類型決定了它如何看待這個地址,而它加一加了一列的大小,說明它指向的類型應該是一個數組,數組的大小為列的元素。
所以在這里,我們傳進去的參數就應該是一個數組指針,而了解到這一點后,我們也會發現,數組名代表的首元素地址就是第一行的地址。

所以它的本質應該是


指針傳參

指針的傳參就相對來說簡單一點了,在這里就不太詳細的介紹。

一級指針
#include<stdio.h>void print(int *p, int size) {int i = 0;for (i = 0; i < size; i++){printf("%d ", *(p + i));;} } int main() {int arr[5] = {1, 2, 3, 4, 5};int *p = arr;int size = sizeof(arr) / sizeof(arr[0]);print(p,size);return 0; }


當指針作為參數時,我們只需要對其進行解引用,就可以操作它所指向的對象。

二級指針
#include<stdio.h>void print(int **p) {printf("%d\n", **p); } int main() {int n = 10;int *p = &n;int **pp = &p; print(pp);print(&p);return 0; }


同理。


函數指針數組

大家在接觸指針的時候經常會聽到一些名詞,數組指針數值,函數指針數組,函數指針數組指針這種一環套一環的令人頭大的東西。

其實按照我們上一節一開始介紹的方法很容易就可以看出來。

如:
先看括號內的優先級,星號的優先級比方括號低,所以這個東西的本質就時一個數組,然后剩下的就是它所存放的數據的類型,然后第二優先級是星號,所以他存放的是一個指針,剩下的就是它所指向的數據的類型,所以它保存的元素是數組指針,所以它是一個數組指針數組。

同理 :
這樣的就是函數指針數組。

而這個看起來像

但他其實是一個函數的聲明,其返回值為指針數組。

那么函數指針數組的作用是什么呢?它最大的作用就是可以簡化代碼,減少很多重復的不必要的代碼。
例如下面這段代碼

int main() {int x, y;int input = 1;int ret = 0;do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);switch (input){case 1:printf("輸入操作數:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("輸入操作數:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("輸入操作數:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("輸入操作數:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");breark;default:printf("選擇錯誤\n");break;}} while (input);return 0; }

在switch中有很多完全重復的代碼,如果我們用函數指針數組優化后是這樣的。

int main() {int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; while (input){printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf("*************************\n");printf("請選擇:");scanf("%d", &input);if ((input <= 4 && input >= 1)){printf("輸入操作數:");scanf("%d %d", &x, &y);ret = (*p[input])(x, y);}elseprintf("輸入有誤\n");printf("ret = %d\n", ret);}return 0; }

這樣就大大減少了代碼量。

總結

以上是生活随笔為你收集整理的C语言程序设计 | 指针(二):常量指针和指针常量、数组参数和指针参数、函数指针数组的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。