C++基础积累(2)指针与数组、指针与函数关系详解

本文详细介绍了C++中各种运算符的优先级、结合性、操作对象及使用示例,包括作用域解析、递增、递减、赋值、逻辑运算、位运算、比较运算等,并提供了实例代码进行说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

欢迎转载!转载时请注明出处:http://blog.youkuaiyun.com/aa4790139/article/details/8144416

这篇将详细讲解这些关系...

首先我们的搞清楚,运行符的优先级:

优先级运算符叙述示例重载性结合性
1::作用域解析(C++专有)Class::age = 2;由左至右
2++后缀递增i++
--后缀递减i--
{}组合{i++;a*=i;}
()函数调用或变量初始化c_tor(int x, int y) : _x(x), _y(y * 10) {}
[]数组访问array[4] = 2;
.以对象方式访问成员obj.age = 34;
->以指针方式访问成员ptr->age = 34;
dynamic_cast运行时检查类型转换(C++专有)Y& y = dynamic_cast<Y&>(x);
static_cast未经检查的类型转换(C++专有)Y& y = static_cast<Y&>(x);
reinterpret_cast重定义类型转换(C++专有)int const* p = reinterpret_cast<int const*>(0x1234);
const_cast更改非常量属性(C++专有)int* q = const_cast<int*>(p);
typeid获取类型信息(C++专有)std::type_info const& t = typeid(x);
3++前缀递增++i由右至左
--前缀递减--i
+一元正号int i = +1;
-一元负号int i = -1;
!
not
逻辑非
!的备用拼写
if (!done) …
~
compl
按位取反
~的备用拼写
flag1 = ~flag2;
(type)强制类型转换int i = (int)floatNum;
*引用int data = *intPtr;
&取某某的地址(参考)int *intPtr = &data;
sizeof某某的大小size_t s = sizeof(int);
new动态内存分配(C++专有)long* pVar = new long;
new[]动态数组内存分配(C++专有)long* array = new long[20];
delete动态内存释放(C++专有)delete pVar;
delete[]动态数组内存释放(C++专有)delete [] array;
4.*成员对象选择(C++专有)obj.*var = 24;由左至右
->*成员指针选择(C++专有)ptr->*var = 24;
5*乘法int i = 2 * 4;
/除法float f = 10.0 / 3.0;
%模数(取余)int rem = 4 % 3;
6+加法int i = 2 + 3;
-减法int i = 5 - 1;
7<<比特左移int flags = 33 << 1;
>>比特右移int flags = 33 >> 1;
8<小于关系if (i < 42) …
<=小于等于关系if (i <= 42) ...
>大于关系if (i > 42) …
>=大于等于关系if (i >= 42) ...
9 ==
eq
等于关系
==的备用拼写
if (i == 42) ...
!=
not_eq
不等于关系
!=的备用拼写
if (i != 42) …
10 &
bitand
比特 AND
&的备用拼写
flag1 = flag2 & 42;
11 ^
xor
比特 XOR(独占or)
^的备用拼写
flag1 = flag2 ^ 42;
12 |
bitor
比特 OR(包含or)
|的备用拼写
flag1 = flag2 | 42;
13 &&
and
逻辑 AND
&&的备用拼写
if (conditionA && conditionB) …
14 ||
or
逻辑 OR
||的备用拼写
if (conditionA || conditionB) ...
15c?t:f三元条件运算int i = a > b ? a : b;由右至左
16=直接赋值int a = b;
+=以和赋值a += 3;
-=以差赋值b -= 4;
*=以乘赋值a *= 5;
/=以除赋值a /= 2;
%=以取余数赋值a %= 3;
<<=以比特左移赋值flags <<= 2;
>>=以比特右移赋值flags >>= 2;
&=
and_eq
以比特AND赋值
&=的备用拼写
flags &= new_flags;
^=
xor_eq
以比特XOR赋值
^=的备用拼写
flags ^= new_flags;
|=
or_eq
以比特OR赋值
|=的备用拼写
flags |= new_flags;
17throw抛出异常throw EClass(“Message”);
18,循环评估运算for (i = 0, j = 0; i < 10; i++, j++) …由左至右

记住一个大概就行,要不然记住这么多头都会大...也没有必要

运算符优先级:括号>算术运算符>位运算符>赋值运算符

指针:int *p指向一个int类型的指针变量

指针数组:int *p[] 由指针构成的一个数组(先结合p[],然后类型int *)

数组指针:int (*p)[] 指向一个一维的数组的指针(先结合(*p),然后指向int[]) 下面同理

指针函数:int *p() 返回一个int类型的指针函数

函数指针:int (*p)() 指向一个函数入口的指针

二维指针:int **p;指向一个int类型指针的指针变量

为什么我们要指针呢?比如有数组了,为什么要数组了

比如:

char s[3][3]={"a","de","h"};

cout<<sizeof(s)<<endl;

char *p[]={"a","de","h"};

//cout<<sizeof(p)<<endl;这个地方,我不知道,如何打印p指针指向地址所占用的内存大小....如果有朋友知道,怎么打印一个指针指向地址做占用的内存大小,请告诉我?感谢了

运行结果:

9

7

其实道理都是懂的...

s[3][5]第一个字符不够5个字符,一个结束字符,一个字节没有用到,后面的那个同理...而p指向的这个数组,是直接指向的,不费浪费...

加入char占用一个字节,那么这个数组就占用了

我觉得下面这几个例子挺好的~ 然后请大家自己的答案,然后和我下面的结果是否相同,这样的话,能加深理解和印象

1、int x[5]; int **p=&x;你觉得这样对吗?

答案:报错,因为类型不匹配,p的类型是int **,而&x的类型int(*)[5],因为取得是x的地址,也就是说这个地址是数组的地址,并不是只想数组第一个元素的指针的指针(二维指针),而是整个数组的地址。改成如下方式就正确了:int(*p)[5]=&x;

2、int x[5]; int(*p3)[5];p3++向前移动多少个字节?

答案:p3指向的是一个数组,是整个数组,所以p3移动的时候是将一个数组当做一个整体来看待的。所以移动4*5个字节(int 占4字节)

3、int a[2][3];int **p=&a;这样初始化行吗?

答案:肯定是不行的....&a的类型是int (*)[2][3],,而p的类型是int **;

正确写法1:int (*p)[2][3]=&a;

正确写法2:int (*p)[3]=a;

解释下第二种写法:a[0]、a[2]也是三个指针

a[0]--->a[0][0],a[0][1],a[0][2]

a[1]--->a[1][0],a[1][1],a[1][2]

那么a到底是什么类型,其实a数组有两个元素,a[0]、a[1],那么a的值自然就是其第一个元素的地址了,也就是&a[0]了,这是一个什么类型?我们知道如果将a[0]看成一个整体,例如用A来代替a[0],那么A[0],A[1]就相当于a[0][0],a[0][1]。此时A就是一个int类型的数组,&A的类型实际上就是int (*p) [3]类型

希望大家仔细阅读...真正理解...

感谢大家阅览我的博文,希望也能看到大家留下的脚印...呵呵!
如果讲述得有误,或者不对的地方,还望各位指出!

参考文章:

http://zh.wikipedia.org/wiki/C%E5%92%8CC%2B%2B%E9%81%8B%E7%AE%97%E5%AD%90

http://www.360doc.com/content/11/0506/22/6903212_114913991.shtml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值