網站首頁 編程語言 正文
前言?
今天在項目中需要求采樣點的數量并且遍歷,采樣點用數組存儲,自定義了一個函數想要用sizeof求其長度,然后遍歷,結果失敗了,查閱之后發現以下問題:
在main函數中,sizeof是可以正常工作的
#include <stdio.h>
int Number[10];
int main()
{
int size = sizeof(Number);
printf("數組大小為:%d\n",size);
int len = sizeof(Number)/sizeof(int);
printf("數組共有%d個數據\n",len);
return 0;
}
輸出:
但是在自定義函數中就不可以了,如下:
#include <stdio.h>
int Number[10];
void print_1(int n[])
{
int size = sizeof(n);
printf("數組大小為:%d\n",size);
int len = sizeof(n)/sizeof(int);
printf("數組共有%d個數據\n",len);
}
int main()
{
print_1(Number);
return 0;
}
那么我們首先要知道sizeof函數的功能:
sizeof是獲取數據在內存中所占用的存儲空間,以字節為單位來計數。
那么這個時候有的同學就會有問題了,兩次傳入的都是數組的首地址,為什么主函數中就可以,自定義函數中就不行呢?
得益于譚老爺子的C語言書籍普及量和銷量,很多人認為數組名就是指向數組首地址的一個指針,但其實這個說法是錯誤的!
我們用一個最簡單的例子,假設數組名是一個指針,那么:
#include <stdio.h>
int Number[10];
int *Number2;
int main()
{
int a=sizeof(Number);
int b=sizeof(Number2);
printf("a的大小為:%d \n b的大小為 %d\n",a,b);
return 0;
}
- Number是一個指針,Number2也是一個指針,正常情況下 大小都應該為8
- 但是實際的輸出確實 a=40 b=8
- 也就是說數組名在某些情況下是不等于指針的,只是在一些情況下會退化為指針
首先我們要知道,單純的數組名,不是指針
數組名是一個標識符,它標識出我們之前申請的一連串內存空間,而且這個空間內的元素類型是相同的——即數組名代表的是一個內存塊及這個內存塊中的元素類型 。
只是在大多數情況下數組名會“退化”(C標準使用的decay和converted這兩個詞)為指向第一個元素的指針。
而指針不是一種聚合類的數據結構,它保存著某一種類型的對象的地址(void*除外),也說它指向這個對象。
我們可以通過這個地址訪問這個對象。用一個圖來解釋,其中a代表了整個我們聲明的內存塊,p僅僅指向了一個char類型的對象
char a[] = {'h' 'e' 'l' 'l' 'o'};
char b[] = {'w' 'o' 'r' 'l' 'd'};
char *p=b;
這是怎么一回事呢?
我們看一下C99標準:
C99 6.3.2.1 Lvalues, arrays, and function designators 中第三段是這樣說的:
Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
the array object and is not an lvalue. If the array object has register storage class, the
behavior is undefined.
這段話的意思是: 數組名只有在
- sizeof 運算符
- 取址 & 運算符
- 字符串常量初始化的數組 Str[]=“abcdef”
這三種情況下不會發生退化(array decay)
其余情況下調用數組名,都會退化成指向數組首地址的指針
再深入的話,就是要了解指針的sizeof
- 指針是用來記錄另一個對象的地址,所以指針的內存大小就等于計算機內部地址總線的寬度。
- 對一個地址來取大小呢,如果是32位系統的話即為4,如果是64位系統的話為8,所以呢,在函數中sizeof獲取的是指針的長度而不是數組的長度
- 指針變量的sizeof值與指針所指的對象沒有任何關系。
結論
也就是說在c語言中,數組名在函數的調用中退化成了一個指針,對函數的參數使用Sizeof,sizeof獲取的結果就是指針的大小,而不是數組本身的大小
再了解一下Sizeof的處理時間
sizeof是C語言的一種單目操作符(但有人也不這么以為,認為它是一種特殊的宏),如C語言的其他操作符++、–等一樣。它并不是函數。
sizeof操作符以字節形式給出了其操作數的存儲大小。操作數可以是一個表達式或括在括號內的類型名。操作數的存儲大小由操作數的類型決定,簡單的說其作用就是返回一個對象或者類型所占的內存字節數。
也就是說,Sizeof是一個C語言的操作符,那么他的處理階段在編譯階段,也就是說你程序沒有運行前,sizeof(arr)就被替換成了一個固定的常量,那么對于動態生成的數組大小是不能用sizeof來算出來的。
解決方法
在函數中多加一個參數,表示數組的長度
#include <stdio.h>
int Number[10];
void print_1(int n[], int len)
{
printf("數組大小為:%d\n",len);
printf("數組共有%d個數據\n",len/sizeof(int));
}
int main()
{
print_1(Number,sizeof(Number));
return 0;
}
原文鏈接:https://blog.csdn.net/as480133937/article/details/123512497
相關推薦
- 2022-07-29 Linux磁盤管理方法介紹_linux shell
- 2022-09-10 pycharm中沒有找到database的解決方案_python
- 2022-08-27 一文讀懂Android?Kotlin的數據流_Android
- 2022-10-07 Rust中的Struct使用示例詳解_相關技巧
- 2022-05-15 go?RWMutex的實現示例_Golang
- 2022-05-11 如何在 CSS 中設置組件在瀏覽器屏幕水平垂直居中
- 2022-10-13 Python教程之類型轉換詳解_python
- 2023-01-26 C#實現批量Word轉換Html的示例代碼_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支