[英]C - comparison between pointer and integer ('char *' and 'int')
[英]Are there differences between int pointer and char pointer in c?
我是 C 新手,無法理解指針。 我感到困惑的部分是關於char *
和int *
。
比如我們可以直接給char賦值一個指針,比如
char *c = "c";
它不會出錯。
但是,如果我像剛才那樣為 int 分配一個指針,例如int * a = 10;
,
它會出錯。 我需要在內存中留出額外的空間來為 int 分配一個指針,
像int *b = malloc(sizeof(int)); *b = 20; free(b);
int *b = malloc(sizeof(int)); *b = 20; free(b);
...
誰能告訴我為什么?
我認為您誤解了指針是什么以及它的含義。 在這種情況下:
int* a = 10;
您是說“創建一個指針(指向int
)並將其瞄准文字內存位置0x0000000A
(10)。
這和這個不一樣:
int n = 10;
int* a = &n;
即“創建一個指針(指向int
)並將其瞄准n
的內存位置。
如果你想動態分配這個:
int* a = malloc(sizeof(int));
*a = 10;
這意味着“創建一個指針(指向int
)並將其指向剛剛分配的內存塊,然后將值10
分配給該位置。
通常你從來沒有分配單個int
,你會分配其中一束用於陣列,在這種情況下,你把它稱為a[0]
通過a[n-1]
用於大小的數組n
。 在 C 中*(x + y)
通常與x[y]
相同,或者換句話說*(x + 0)
只是*x
或x[0]
。
在您的示例中,您不會將c
發送到字符'c'
。 您使用了"c"
,它是一個字符串字面量。 對於字符串文字,它的工作原理如https://stackoverflow.com/a/12795948/5280183 中所述。
像"c"
這樣的字符串文字實際上是一個數組表達式( "c"
的類型是“ char
的二元數組”)。
除非它是sizeof
或&
運算符的操作數,或者是用於在聲明中初始化字符數組的字符串文字,否則類型為“ T
數組”的表達式將被轉換,或“衰減”為類型為“的表達式”指向T
" 的指針,其值將是數組第一個元素的地址。
所以當你寫
char *c = "c";
它大致相當於寫作
char string[] = "c";
char *c = &string[0];
您正在為指針分配一個指針,因此編譯器不會抱怨。
然而,當你寫
int *a = 10;
您正在為指針分配一個int
值並且類型不兼容,因此編譯器會抱怨。 指針不是整數; 它們可能有一個整數表示,但這不能保證,並且它的大小不會與int
相同。
在初始化時,右側 (RHS) 表達式必須屬於或可轉換為聲明的變量類型。
如果你這樣做
char *cp = ...
int *ip = ...
那么...
必須可轉換為指向char
的指針或指向int
的指針。 還要記住, char
是單個字符。
現在, "abc"
是 C 中的特殊語法 - 字符串文字,用於創建(許多)不可變字符數組。 它具有char [size]
類型,其中size
是文字中的字符數加上終止空字符的 1。 所以"c"
類型是char [2]
。 它不是char
。 C 中的數組被隱式轉換為指向第一個元素的指針,然后具有“指向元素類型的指針”的類型。 即"c"
型的char [2]
中char *cp = "c";
被隱式轉換為類型char *
,這點與第一兩個字符的c
和\\0
兩字符陣列英寸它也是char *
類型的方便,現在我們有char *cp = (something that has type char * after conversions);
.
至於int *
,您正在嘗試將整數值傳遞給指針。 它沒有任何意義。
一個指針保存一個地址。 如果你要問夏洛克福爾摩斯的地址,答案是貝克街 221 號。 現在你所做的是“福爾摩斯的地址是我今天早上給他拍的這張照片”。
為char *
編寫的相同錯誤代碼將是
char *cp = 'c'; // or more precisely `char *p = (char)'c';
它會給你完全相同的錯誤證明char *cp
和int *cp
工作方式相似。
不幸的是,C 沒有int
字符串文字,也沒有整數數組的文字,但從 C99 開始,您可以編寫:
int *ip = (int[]){ 5 };
或者
const int *ip = (const int[]){ 5 };
同樣,您始終可以將char *
或int *
指向該類型的單個對象:
字符 a = 'c'; 字符 *pa = &a; 整數 b = 42; int *pb = &b;
現在我們可以說a
和*pa
指定相同的char
對象a
,同樣b
和*pb
指定相同的int
對象b
。 如果您更改*pa
您將更改a
,反之亦然; 對於b
和*pb
也是如此。
c中int指針和char指針之間有區別嗎?
在過去的幾十年里,C 中的所有指針都是平等的。 由於一種稱為內存模型的東西,在某些平台(如 Windows)中,有一段時間存在不同大小的指針。
今天,編譯器根據平台將代碼設置為使用 32 位或 64 位或任何大小的指針,但一旦設置,所有指針都相等。
不相等的是指針指向的東西,是你困惑的地方。
void*
指針。 malloc()
在 C 中分配內存。它總是返回一個void*
指針,然后你把它轉換成你需要的任何東西sizeof(void*)
與sizeof(int*)
。 與sizeof(GiantStruct*)
,在 64 位編譯器中為 8 字節或 64 位"c"
。 是char[2]
。 它是一個字符串文字。 在內存中的某個地方,系統將分配至少 2 個字節的區域,在那里放置一個'c'
和一個零,因為字符串文字在C
中以NULL
結尾,將該地址放入分配給您的指針c
的地址中。int* a = 10
呢?a
? 一個是int*
指針,指向一個int
。 什么是*a
? 一個int
。 在哪個地址? 10
. 好吧,事實是系統不會讓您訪問該地址,因為您設置了一個指向該地址的指針。 在 80 年代,你可以。 今天對此有非常嚴格的規則:您只能訪問分配給您的進程的內存。 僅有的。 因此,一旦您嘗試訪問,系統就會中止您的程序。如果你寫
int* a = malloc(300);
系統會分配一個300字節的區域,把區域地址給你寫在分配給a的地址上。 當您寫入*a=3456
,系統會將這個值寫入該地址的第一個sizeof(int)
字節。
您肯定可以寫出所有 300 個,但您必須稍微操縱指針以指向該區域內。 只在那個區域里面。 事實上,C 語言就是為此而設計的。
讓我們在分配給 a 的 300 字節區域的末尾寫入“c”:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char* c = "c";
int* a = (int*)malloc(300);
*a = 3456;
printf("Area content is %d\n", *a);
char* pToEnd = (char*)a + 298;
*(pToEnd) = 'c';
*(pToEnd + 1) = 0;
printf("At the end of the 300-byte area? [Should be 'c'] '%s'\n", pToEnd);
printf("The pointer c points to '%s'\n", c);
//*c = 'x'; // error: cancel program
c = pToEnd;
printf("The pointer c now points do the end of the 300-byte area:'%s'\n", c);
free(a);
return 0;
};
看看
Area content is 3456
At the end of the 300-byte area? [Should be 'c'] 'c'
The pointer c points to 'c'
The pointer c now points do the end of the 300-byte area:'c'
另請注意,一旦您嘗試覆蓋c
,即示例中的char
指針,您的程序也將取消。 它是一個只讀區域 --- 請參閱第 14 行的注釋。但是您可以在示例中將c
指向該區域內並使用它,因為指針本身不是常量。
當您在上面的示例中編寫c = pToEnd
時,對字符串文字的訪問將永遠丟失。 從某種意義上說是內存泄漏,但它是靜態分配的區域。 泄漏的不是區域而是地址。
還需要注意的是free(a)
到了最后,即使是a
int*
將釋放所有300個字節
您的問題的直接答案是, C
語言是一種嚴格類型的語言。 在生成機器碼之前,編譯器會檢查一些可能的錯誤。 類型不同,這就是編譯器想要知道的全部內容。
但是從bit-byte來看,沒有區別,對於C
語言來說,跟上面兩個指針沒有區別。
void main(){
int * a = 10; /* <= this presumably gives you an error. */
}
我所做的是復制粘貼你的代碼,給你帶來錯誤。 並且在線編譯器發出了警告,而不是錯誤。 甚至更多。 將C
標准更改為c17
,您仍然c17
收到警告。
關於將字符串文字分配給指針的注意事項已在 SO 上進行了廣泛討論。 它值得一個不同的話題。
把它們加起來。 對於C
語言,上述兩個指針沒有任何意義。 用戶有責任了解他/她程序中的內存布局。 總而言之,該語言被設計為一種在線性內存上運行的高級工具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.