char a;
a = 10;
程序內部是怎麼操作的呢?
其實,程序對變量的讀寫操作,實際上是對變量所在的存儲空間進行寫入或取出數據。就上面的代碼而言,
系統會自動將變量名a轉換為變量的存儲地址,根據地址找到變量a的存儲空間,然後再將數據10以2進制的形式放入變量a的存儲空間中。
通過變量名引用變量,由系統自動完成變量名和其存儲地址之間的轉換,稱為變量的"直接引用"方式
如 將變量a的地址存放在另一個變量中,比如存放在變量b中,然後通過變量b來間接引用變量a,間接讀寫變量a的值。這就是"間接引用"
總結一句:用來存放變量地址的變量,就稱為"指針變量"。在上面的情況下,變量b就是個"指針變量",我們可以說指針變量b指向變量a。
一般形式:類名標識符 *指針變量名;
int *p;
float *q;
int a = 10;int *p = &a; float b = 2.3f; float *q; q = &b;
char a = 10;
printf("修改前,a的值:%d\n", a);
// 指針變量p指向變量a
char *p = &a;//這個* 是定義指針的說明符
// 通過指針變量p間接修改變量a的值
*p = 9;//這個* 是指針運算符,表示 把9賦值給 指針指向的地址a,也就相當於 a = 9;
//這裡 就是間接修改a的值
printf("修改後,a的值:%d", a);
char a = 10;
char *p;
p = &a;
char value = *p; //根據p值(即變量a的地址)訪問對應的存儲空間,並取出存儲的內容(即取出變量a的值),賦值給value
printf("取出a的值:%d", value);
在指針變量沒有指向確定地址之前,不要對它所指的內容賦值。下面的寫法是錯誤的
int *p;
*p = 10; //這是錯誤的
應該在指針變量指向一個確定的變量後再進行賦值。下面的寫法才是正確的
// 定義2個int型變量
int a = 6, b;
// 定義一個指向變量b的指針變量p
int *p;
p = &b;
// 將a的值賦值給變量b
*p = a;
交換兩個字符變量的地址(改變實參的值)
void swap(char *p,char *q)
{
char temp = *p;
*p = *q;
*q = temp;
}
int main(int argc,constchar * argv[])
{
char a ='A', b ='&';
swap(&a, &b);
printf("a=%c b=%c\n”, a, b);
}
int a[2] = {2, 3}; int *p = &a[0]; *p = 10; 那麼 a[0]應該等於10
數組名a 的地址 與 它的第一個元素的地址相同, 所以 p = &a[0] 與 p = a 效果一樣
指針來遍歷數組元素
int ary[] = {1,2,3,4, 5};
int *q = ary;
for (int i =0; i <5; i++)
{
//數組內元素內存地址是連續的存儲方式,指針移動一個對應類型單位字節數(int、char...),則指向下一個元素值
// printf("數為:%d ", *(q+i)); //地址移動
// printf("數為:%d ", *(ary+i)); //地址移動
printf("數為:%d ", *(q++));//q=q+1,指針指向的地址移動
// printf("數為:%d ", *(ary++)); //錯誤,常量不能賦值
}
形參數組,實參指針
void change(int b[]) {
b[0] = 10;
}
int main()
{
// 定義一個int類型的數組
int a[4] = {1, 2, 3, 4};
int *p = a;
// 將數組名a傳入change函數中
change(p);
// 查看a[0]
printf("a[0]=%d", a[0]);
return 0;
}
形參指針,實參數組
void change(int *b) {
b[0] = 10;
// 或者*b = 10;
b[1] = 11;
// 或 *(b+1) = 11;
}
int main()
{
// 定義一個int類型的數組
int a[4] = {1, 2, 3, 4};
// 將數組名a傳入change函數中
change(a);
// 查看a[0]
printf("a[0]=%d", a[0]);
return 0;
} //可以看出,在很多情況下,指針和數組是可以相互切換使用的。但是,並不能說指針就等於數組
char chs[] ="abcde";
char *p;
p = chs;
for (; *p != '\0';p++)
{
printf("data:%c ", *p);
}
printf("\n");
char *p ="abcde";
strlen("abde”);
size_t strlen(const char *);
char *strcpy(char *,const char *);// 字符串拷貝函數
char *strcat(char *,const char *);// 字符串拼接函數
int strcmp(constchar *, constchar *); // 字符串比較函數
它們的參數都是指向字符變量的指針類型,因此可以傳入指針變量或者數組名。
1 char s[10];
2 s ="mj"; //編譯器肯定報第2行的錯,因為s是個常量,代表數組的首地址,不能進行賦值運算
1 char *s ="mj";
2
3 *s = "like";
第3行代碼犯了2個錯誤:
返回指針的函數的一般形式為:類型名 *函數名(參數列表)
// 將字符串str中的小寫字母變成大寫字母,並返回改變後的字符串
// 注意的是:這裡的參數要傳字符串變量,不能傳字符串常量
[plain] view plaincopyprint?
定義的一般形式:函數的返回值類型 (*指針變量名)(形式參數1,形式參數2, ...);
注意:形式參數的變量名可以省略,甚至整個形式參數列表都可以省略
int sum(int a,int b)
{
return a + b;
}
int main()
{
int (*q) (int a,int b) = sum;// (int a, int b) 可以寫成(int a, int)或(int,int)或()
int result = (*q)(2,5);//調用函數
printf("\n%d", result)
return 0;
}
將函數作為參數
void get(int (*q)(int a,char b), float c) {}