教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

c/c++培訓(xùn)C語言核心知識(shí)總結(jié)(五、六)

更新時(shí)間:2016年10月21日16時(shí)34分 來源:傳智播客C++培訓(xùn)學(xué)院 瀏覽次數(shù):

五、指針 和 數(shù)組的用法
 
int num[5] = {10, 20, 30, 40, 50};
int *p = num;
 
打印的值 打印后*p的值是 數(shù)組里的原值
// 操作地址
*p++ 10   20 10
*(p++)
*和++的優(yōu)先級(jí)相同,根據(jù)結(jié)合性(從右往左),那么p先和后自增運(yùn)算符++結(jié)合,
++操作將在表達(dá)式完成后進(jìn)行自增,也就取出p指向的值之后,p指向的下標(biāo)后移一位(4個(gè)字節(jié))。
 
*++p 20   20 10
*(++p)
*和++優(yōu)先級(jí)相同,根據(jù)結(jié)合性(從右往左),那么p先和前自增運(yùn)算符++結(jié)合,
++操作將會(huì)立即完成,p指向的下標(biāo)后移一位(4個(gè)字節(jié)),然后再取出p指向的值。
 
 
// 操作數(shù)值
(*p)++ 10 11 11
根據(jù)優(yōu)先級(jí)()小括號(hào)優(yōu)先級(jí)最高,p先和*相結(jié)合,然后再和后自增運(yùn)算符++結(jié)合,
因?yàn)槭呛笞栽?,所以先打印?dāng)前下標(biāo)的值,然后在原值的基礎(chǔ)上自增 1,此時(shí)原值已被改變
 
 
++*p 11 11 11
++(*p)
根據(jù)結(jié)合性/優(yōu)先級(jí),*和p先結(jié)合,然后再和前自增運(yùn)算符++結(jié)合,
因?yàn)槭乔白栽?,所以先在原值的基礎(chǔ)上自增1,然后在打印這個(gè)值,此時(shí)原值已被改變。
 
 
總結(jié):如果一個(gè)表達(dá)式里有多個(gè)運(yùn)算符,則先進(jìn)行優(yōu)先級(jí)比較,先執(zhí)行優(yōu)先級(jí)高的運(yùn)算符;
如果優(yōu)先級(jí)相同,那就看結(jié)合性,根據(jù)結(jié)合方向來做運(yùn)算。
 
 
結(jié)合性:
從左往右:
小括號(hào)()、數(shù)組括號(hào)[]、成員選擇 . 和 ->,雙目運(yùn)算符,逗號(hào)運(yùn)算符
 
從右往左:
單目運(yùn)算符、三目運(yùn)算符、賦值類運(yùn)算符
 
/*
++a:  是直接從變量 a 所在的內(nèi)存地址中取值,并進(jìn)行加1操作,再執(zhí)行表達(dá)式剩余部分。
a++: 先把變量的值保存在一個(gè)臨時(shí)寄存器里,然后再執(zhí)行整個(gè)表達(dá)式,執(zhí)行完之后,再把a(bǔ)的值自增1,再返回內(nèi)存里。
 
CPU -》 寄存器 -》 緩存(L1\L2\L3) -》 來自于內(nèi)存
CPU只和寄存器做數(shù)據(jù)交換,對(duì)于重復(fù)操作的數(shù)據(jù)會(huì)放在緩存里。
但是不管寄存器還是緩存,他們的數(shù)據(jù)都來自于內(nèi)存。
*/
 
 
六、指針數(shù)組 和 數(shù)組指針
 
1. 指針數(shù)組:
定義形式:
int *p[n] = { 0 };
[]的優(yōu)先級(jí)高于*,那么p先和[]結(jié)合,說明這是一個(gè)數(shù)組。
再和int *結(jié)合,說明這個(gè)數(shù)組里的每個(gè)元素都是一個(gè)指針,每個(gè)元素都能保存一個(gè)地址。
 
1) 使用指針數(shù)組保存多個(gè)數(shù)據(jù)的地址
int main(void)
{
int a[3] = { 10, 20, 30};
int *p[3] = { 0 };
for (int i = 0; i < 3; ++i)
p[i] = &a[i];
 
for (int i = 0; i < 3; ++i)
{
printf("%p\n", p[i]);
printf("%d\n", *p[i]);
    }
}
 
 
2) 使用指針數(shù)組保存多個(gè)字符串的首地址
#include <stdio.h>
 
int main(void)
{
char *str[5] =
{
"ISO/IEC9899:2011",
"Programming",
"Dennis Ritchie",
"c",
"bell ssss"
};
 
char *str1 = str[1]; // 取出 第2行的字符串
char *str2 = *(str + 3); // 取出 第4行的字符串
char ch1 = *(*(str + 4) + 2); //取出 第5行的字符串的第3個(gè)字符
char ch2 = (*str + 5)[7]; // 取出第1個(gè)字符串的第6個(gè)字符,并以此做數(shù)組首元素,向后遍歷到第7個(gè)。
char ch3 = *str[0] + 6;  // 取出第1個(gè)字符串的第1個(gè)字符,然后把這個(gè)字符ASCII碼加上6,再用%c打印出來
 
printf("str1 = %s\n",  str1); // Programming
printf("str2 = %s\n",  str2); // c
printf("ch1 = %c\n",  ch1); // l
printf("ch2 = %c\n",  ch2); // 2
printf("ch3 = %c\n",  ch3); // O (不是0)
 
return 0;
}
 
2. 數(shù)組指針(行指針)
定義形式: int *p;  int (*p)[n];   int (*p)[n][m];
()和[]的優(yōu)先級(jí)相同,但是結(jié)合性是從左往右,那么p先和*相結(jié)合,說明這是一個(gè)指針。
然后再和[]結(jié)合,說明這個(gè)指針指向了一個(gè)數(shù)組。
 
示例:
1)
#include <stdio.h>
 
void func(int (*p)[3], int n);
int main(void)
{
int a[2][3] = {10, 20, 30, 40, 50, 60};
// 行:    0    1
// 列:    0   1   2   0   1   2
func(a, sizeof(a));
return 0;
}
 
void func(int p[2][3], int n);
// 明確行和列的數(shù)量
 
void func(int p[][3], int n);
//明確列的數(shù)量
 
void func(int (*p)[3], int n)  //明確列的數(shù)組指針
{
printf("%d\n", p[1][2]);
// 取出第2行的第3個(gè)元素:60
 
printf("%d\n", **p);
//p是行指針,先是取出當(dāng)前行的列地址,再取出這個(gè)列地址里的值: 10
 
printf("%d\n", (*p + 1)[2]);
// 先取出列地址,然后往后移動(dòng)一個(gè)int(4個(gè)字節(jié)),再以這一列的下標(biāo)為起點(diǎn),取出后面第2個(gè)元素的值:40
 
printf("%d\n", *(*p + 1));
// 先取出列地址,往后移動(dòng)1位(1個(gè)int),再取出這個(gè)下標(biāo)的值:20
 
printf("%d\n", *(p[1] + 2));
// 先取出p[1]的列下標(biāo)地址,再往后移動(dòng)2位(2個(gè)int),再取出這個(gè)下標(biāo)的值:60
 
printf("%d\n", *(*(p + 1)));
// 先將行指針p后移一位(3個(gè)int),再取出這一行的這一列的下標(biāo)地址,再根據(jù)這個(gè)下標(biāo)取值:40
 
printf("%d\n", *((*p + 1) + 2));
//這個(gè)表達(dá)式相當(dāng)于 *(*p + 3),先取出列下標(biāo)地址,然后往后移動(dòng)3位(3個(gè)int),再取值:40
 
printf("%d\n", *(*p + 1) + 2);
// 先取出列下標(biāo)的地址,然后往后移動(dòng)一位(1個(gè)int),再進(jìn)行取值得出20,再加2,結(jié)果是:22
 
}
 
// 三維數(shù)組同理
void func(int (*p)[3][4])
{
printf("%d\n", *(*(*(p + 0) + 1 ) + 2);  //70
}
 
int main(void)
{
int a[2][3][4] =
{
{{10, 20, 30, 40}, {50, 60, 70, 80}, {90, 100, 110, 120}},
{{11, 22, 33, 44}, {55, 66, 77, 88}, {99, 101, 111, 121}}
};
 
func(a);
return 0;
}
 
總結(jié):
1.指針數(shù)組:就是一個(gè)數(shù)組,這個(gè)數(shù)組里的每個(gè)元素都是一個(gè)指針,這個(gè)數(shù)組在內(nèi)存空間中占用了n個(gè)指針的大小。
 
2.數(shù)組指針:就是一個(gè)指針,這個(gè)指針指向一個(gè)數(shù)組,這個(gè)指針在內(nèi)存空間中占用一個(gè)指針的大小。
 
3.二級(jí)指針p 和 二維數(shù)組名p 的區(qū)別:
int **p; 這個(gè)是一個(gè)整型的二級(jí)指針,p是一個(gè)可變句柄/鑰匙,我們可以讓這個(gè)指針指向任何我們希望它指向的地方。
這個(gè)句柄不需要指定內(nèi)存空間的大小。
int p[n][m]; 這個(gè)是一個(gè)整型的二維數(shù)組,p是引用了這塊內(nèi)存空間的句柄/鑰匙,數(shù)組在定義的時(shí)候,
就被固定指向某個(gè)內(nèi)存空間了,這個(gè)空間大小是 sizeof(int) * n * m,而且不可修改p的指向,
p就是一個(gè)不可變的常量,永遠(yuǎn)的都只能指向這里了。
 
如果想確定某個(gè)一維數(shù)組的值: * 、 []
如果想確定某個(gè)二維數(shù)組的值:** 、 [][] 、 *[]

本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://metathetuscanyresort.com/c/ 

 

0 分享到:
和我們?cè)诰€交談!