前言
過了幾個月再次更新。最近時間也不多了,快要期中考試了,暫且先少寫一點吧。
本文僅在博客園發布,如在其他平台發現均為盜取,請自覺支持正版。
練習題
我們先來看幾道題目。如果這幾道題都不會的話,就先好好復習我寫的前四篇文章吧,這一章是肯定看不懂的。
- 1.使用指針編寫swap函數。(經典例題)
答案
void swap(int *a,int *b){
int t=*a;*a=*b;*b=t;
}
- 2.已知數組a[10][10],交換該數組的第1和第3行。
答案
實際上,二維數組的每一行都是一個單獨的數組,二維數組的本質就是“數組的數組”。因此,可以使用memcpy進行數組拷貝。int temp[10];
memcpy(temp,a[0],10*sizeof(int));
memcpy(a[0],a[2],10*sizeof(int));
memcpy(a[2],temp,10*sizeof(int));
const
const含義
const是constant的縮寫,意為“常量”,事實上我們也經常用const定義常量。
但是在C語言(這里不是C++),const的含義是“只讀變量”。也就是說,const就是普通變量。
我們做一個實驗確認一下。(務必采用C語言編譯)
#include<stdio.h>
int main(){
int *p;
const int a=5;
printf("a..%d",a);
p=&a;
*p=10;
printf("a..%d",a);
}
先說一下C++為什么不通過編譯,因為C++對於類型比較嚴格,編譯上述代碼會出這個錯誤:
error: invalid conversion from 'const int' to 'int' [-fpermissive]
因此,如果手頭只有C++環境的話,請務必開-fpermissive選項。
在C語言下,輸出結果是a..5和a..10。在C++下,即使開了fpermissive,結果仍然是a..5和a..5。
我們來閱讀一下程序。我們使用指針的形式,將a的地址賦值給p,那么p所指向的就是a。但是由於p不帶const(const指針的問題將會於下一節敘述),*p可以被修改,那么a就理所當然被修改為10了。
但是在C++中,const就是指常量,在處理a的時候,編譯器會自動的把a理解為5,不再去讀取a所在的內存了。因此,即使a對應的內存被修改,a輸出結果仍然為5。
如果把第二個printf語句中,a改為*p,輸出為10。這再次證明了C++這一特性。
const內存區域
如果把const int a一句放到main以外成為全局變量,結果又會如何?大家可以自行嘗試一下。
結果是運行時錯誤,segmentation fault段錯誤。
這是因為,全局變量的const,存儲的區域是配置在內存的只讀區域的,修改會出問題。而局部變量存儲的區域在棧上,和其他普通變量在一起,因此可以任意修改。
如果嘗試輸出全局變量和局部變量的地址,我們發現,兩個地址相差很遠。
0x402004 0x7ffd9a34094c
const和指針
聲明部分
(以下轉自我之前寫的C語言常見誤區)
關於const和指針連在一起,經常讓初學者們摸不着頭腦。
例如下面幾句:
const char *p
char const *p
char* const p
const char* const p
它們各有什么區別?
我這里曾經從《征服C指針》看到了幾條非常好的內容,在此給大家分享一下:
因為C語言是美國人發明的,最好還是用英語來讀(聲明語句)。
規則:從后往前倒序,如果遇到*號,就加上“pointer to”,如果有const,就追加“read-only”。
const在前面和在后面完全相同。
例如,對const char *p進行翻譯:
首先看到p:p is
然后是*:p is pointer to
然后是char:p is pointer to char
然后是const:p is pointer to read-only char
翻譯為中文:p是指向只讀的char的指針
按照這種方式解釋,我們對上面四個語句解釋如下:
p is pointer to read-only char
p is pointer to read-only char
p is read-only pointer to char
p is read-only pointer to read-only char
照這樣,我們得出結論:
const char* p 和char const* p含義完全相同,表示指向的字符是不可變的。
char* const p表示指針自身不可變,指向的字符可變。
而最后一個,指向的字符和指針自身都不可變。
應用
定義字符串常量,我們一般使用:
const char *str=...
這類的語句。指向的字符是不可改變的。
但注意下面的代碼:
#include<stdio.h>
#include<string.h>
struct test{
int a,b;
char str[10];
};
int main(){
const struct test a={1,2,"hello"};
strcpy(a.str,"abc");
printf("%s",a.str);
}
雖然結構體a是const的,因此str本身不可改變,但是str指向的字符仍然可以改變!圖示如下:
函數參數的const
比較簡單。例如strcpy的聲明:
void strcpy(char *dest, const char *src);
在此處,const表示在函數內部,src的值不可改動。並非表示傳入的參數一定是常量。
很多函數都包含輸入參數和輸出參數。與其使用繁雜的注釋,例如:
/*
src (i) 參數提供的輸入字符串
dest (o) 復制到的字符串
*/
使用i,o等標記,還不如使用const,后者在函數中不小心修改src的時候,還會發出警告。
以上參考《征服C指針》。
全文完。