目录
cap1绪论
1.2 计算机组成
- 计算机=软件+硬件;
- 硬件:输入设备、输出设备、存储器、控制器、运算器。(控制器+运算器=CPU)
- 存储器:内存的最小单元是bit,一个bit存储一个二进制位。一般8个bit组成一个byte,若干个byte组成一个word。
cap2通过例子学习
2.1程序的组成
- 注释:// or /* */
- 编译预处理:#include <iostream> (库包含)or #define pi 3.14(宏定义)(以#开头的指令,不需要以分号结尾)#include <cmath>(数学运算)
- 名字空间:using namespace std;
- main函数:函数头+函数体
- 换行:endl or \n
- 绘表:\t
2.2变量和常量
命名规则:
- 名字必须以字母或下划线开头。
- 名字中的其它字符必须是字母、数字或下划线,不得使用空格或其它特殊符号
- 名字不可以是系统的关键字,如:int, double, for, return等保留字,它们在C++语言中有特殊用途
变量初始化方式: int num1 = 1; int num2(2); int num3 = {3};
数据类型:
整型:
长整型:无符号unsigned long、有符号long int / long
标准整型:无符号unsigned int、有符号int
短整型:无符号unsigned short int、有符号short int / short
实型:
123e2=12300(①尾数不能为空 e3 →1e3 ②指数必须为整数 2.5e2.3是非法的)
实型常量都被作为double型处理,如要作为float型数据,可在数值后加F或f,例如,1.23F,1.23f
单精度:float
双精度:double
长双精度:long double
字符型:char ( ‘a’, ‘S’, ‘2’等用一对单引号括起来的数据称为字符常量。)(双引号括起来的是字符串。)toupper(ch)转大写;a97A65048;
askⅡ表(A65,a97,048)
布尔型:bool
类型转换规则:
bool、char和short这些非标准的整数在运算前都自动转换为int。
int和float运算时,将int转换成float。
int和long运算时,将int转换成long。
int和double运算时,将int转换成double。
float和double运算时,将float转换成double。
数据转换规则:
实型转换成整型时,舍弃小数部分
整型转换成实型时,数值不变,但表示成实数形式
字符型转换成整型时,不同编译器有不同处理方法(无符号或有符号数)
布尔型转换成整型时,true为1,false为0
整型转换成字符型时,直接取整型数据的最低8位
想使4/5的结果是0.8:4.0 / 5或4 / 5.0 or用强制类型转换 z = (double)x / y;
原码、反码、补码
可以给一个类型重新命名:typedef 原名 现名 → typedef int INTEGER
占用空间:sizeofxx
常数:#define PI 3.14159 const double PI = 3.141592;
2.3 输入和输出
cin >>
用回车(↙)结束
一般用空白字符(空格、制表符和回车)分隔多个输入数据
cin.get(ch) or ch= cin.get()
从键盘接收一个字符,可以接收任意的字符,包括空白字符
cout<<
2.4 算术和赋值运算
算术运算符:+ - * / %
优先级:高 * / %,低 + -
结合性:左结合(=是右结合)
复合赋值运算符:+=,-=,*=,/=,%=
自增、自减运算符:
cap3分支程序设计
3.1关系表达式
关系运算符:
<
<=
>
>=
==易错
!=
tips:
前四个的优先级大于后两个
左结合。(从左向右结合)
关系表达式:表达式 关系运算符 表达式
tip
表达式可以是算术表达式(a+b)、赋值表达式(a=b)or关系表达式(a>b)
优先级算术>关系>赋值
e.g a+b>c-3
3.2逻辑表达式
逻辑运算符:
!非(一元)
&&与(二元)
||或(二元)
tip
优先级!>&&>||
逻辑运算符的运算对象应该是bool型,都会转为0和1
a&&b ab都是真才是真,有一个错就是错
a||b ab有一个真就是真,全错才为错
e.g 0<x<10 0<x&&x<10
短路求值
3.3if语句
if语句的格式
1 if () xx;
2 if () xx;
else xx;
if语句的嵌套
else与最近的if在一起
?:运算符
()?xx:yy 赋值很好用;或者输出的时候使用flag
cout<<(flag?1or2);
3.4switch语句
switch(表达式) {
case 结果1:执行语句; break;
case 结果2:执行语句; break;
...
default:执行语句; break;
}
!!!!
①switch语句是不见break就会将下面的语句都执行一遍的!!!xXY这样
②switch若是省略了后面的语句,则是跟下面碰到的第一个语句执行。
cap4循环程序设计
4.1计数循环
for语句
for(i=0;i<n;++i){
}
tip
别忘了定义i
for循环的嵌套
范围for循环
for(int i:{1,3,4})
4.2break和continue语句
break直接退出
continua 结束当前循环,进入下个循环
4.3基于哨兵的循环
while语句
while(){
xx
}
do{
xx;
}while ();
4.4枚举法
九九乘法表
4.5贪婪法
cap5数组
5.1一维数组存
1、数组元素是有序的、同类的。
2、格式:int myarray[10]
※[]中元素个数必须是数字,不可以是变量,如果想全部更改的话,可以用
const int num=10;
或
#define num 10
int n=10; int myarray[n];是错的
3、数组中的元素
- 初始化的时候没定义的默认为0
- 单独使用一个元素用 myarray[0]来,这里的0是下标,下标可以是数字也可以是变量,注意0指的是第一个元素!
- 数组的输入和输出--for循环
4、数组的内存
- 数组名中存放的是该数组的起始地址
- 定义数组就是定义了一块连续空间
- 空间的大小=元素数*每个元素所占的空间大小。
- my[3]的地址=初始地址+4*4
- 在int x[10]中引用x[10]是正确的,只是会对下一个地址处理。
for(int i=0;i<10;i++)
{
cout<<"请输入第"<<i<<"个数据";
cin>>myarray[i];
}
for(int a=0;a<10;a++)
{
cout<<myarray[a]<<" ";
}
que1、求十个数的最大数
int allnum[10];
int max=0;
for(int i=0;i<10;i++)
{
cin>>allnum[i];
if(allnum[i]>max) max=allnum[i];
}
cout<<max;
ques2:输入一串数字,求里面各个字母出现的次数。
int zimu[26]={0};
char juzi;
for (int i=0;;)
{
juzi=cin.get();//如果是cin>>juzi;就无法存入回车然后结束循环了
juzi=toupper(juzi);
if(juzi<'A'||juzi>'z') break;
++zimu[juzi-'A'];
}
for(int a=0;a<26;a++)
{
cout<<zimu[a]<<" ";
ques3如何探测一个数组的长度?
int a[10];
cout<<sizeof a;
q4如何构建一个不定长度的数组?
5.2、排序和查找
顺序查找
int zu[]={1,3,4,2,5,1,6,2,4};
cout<<"input what you want";
bool flag=1;
int a;
cin>>a;
for(int i=0;i<9;i++)
{
if(zu[i]==a) cout<<i,flag=0;
}
if(flag) cout<<"not found!";
二分查找
int zu[]={2,3,4,5,6,7,8,9,10,11};
cout<<"input what you want";
bool flag=1;
int a;
cin>>a;
int lh=0;
int rh=9;
for(int i=1;;)
{
int mid=(lh+rh)/2;
if(a==zu[mid]){ cout<<mid; flag=0;break;}
if(lh==rh) break;
if(a>zu[mid]){lh=mid+1;}
if(a<zu[mid]){rh=mid-1;}
}
if (flag) cout<<"not found";
选择排序法
定义:例如说让输入的数字从小到大排序,或者从大到小。或者字母按顺序。
以下是代码让他们从小到大排序(or从大到小)有点难理解说实话emo
学会怎么让两个变量交换值---引入中间变量tmp
#include <iostream>
using namespace std;
int main()
{
int lh,rh;
int myarray[10]={10,2,3,4,5,6,7,8,9,1};
for(lh=0;lh<10;lh++)
{
rh=lh;
for(int k=lh;k<10;k++)
{
if(myarray[k]<myarray[rh]) rh=k;//若想从大到小排序只需改成>
}
int tmp=myarray[rh];
myarray[rh]=myarray[lh];
myarray[lh]=tmp;
}
for(lh=0;lh<10;lh++) cout<<myarray[lh]<<" ";
return 0;
}
效率:比较总的次数为1+2+3.。。+n次
气泡排序法
与选择排序法的区别在于,气泡会在筛选一遍的过程中将最大的,次大的,次次大的,拉到后面去。从而提高了效率。
过程:比较相邻的元素,若不符合就调整顺序。所以说结束的标志就是没有交换动作!
代码:难敲:整体思路是for{flag+(for复合flag去判断flag)+flag是否break}
int main()
{
int i,j;
bool flag;
int myarray[10]{7,8,9,0,1,2,3,4,5,6};
for(i=1;i<10;++i)
{
flag=0;
for(j=0;j<10-i;j++)//注意这个for没括号但是控制一整个if语句
if(myarray[j]>myarray[j+1])
{
int tmp=myarray[j];
myarray[j]=myarray[j+1];
myarray[j+1]=tmp;
flag=1;
}
if(!flag) break;//不在小for循环中
}
for(int o=0;o<10;o++) cout<<myarray[o]<<" ";
return 0;
}
5.3二维数组
定义:数组的每一个元素又是一个数组
二维数组又叫做矩阵
二维数组的定义格式:int zu[2][3]------表示2行3列,定义了2*3=6个变量;
zu[0][0] | zu[0][1] | zu[0][2] |
zu[1][0] | zu[1][1] | zu[1][2] |
二维数组的内存:
是连续的,且按行序优先排:zu[0][0]、zu[0][1]、zu[0][2]、zu[1][0]...
初始化:int a[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
int a[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12}};(这种明显更加方便!!)
部分赋初值: int a[3][4] = { 1, 2 , 3, 4, 5 }; 这是按一个一个填进去的
int a[3][4] = { {1, 2}, {3, 4}, {5}}; 这样有更多的选择!
如果数组的长度未知,就设100,然后在for循环的时候就知道了,可以用n之类的限制
栗子:输入矩阵,并计算他们的乘积
#include <iostream>
using namespace std;
int main()
{ //定义
int A[100][100];
int B[100][100];
int C[100][100]={0};
int rowofA,col,rowofB;
int m=0;
int o=0;
//输入行列
cin>>rowofA>>col>>rowofB;
//输入A
for (int i=0;i<rowofA;i++)
{
for (int j=0;j<col;j++)
{
cin>>A[i][j];
}
}
//输入B
for (int i=0;i<rowofA;i++)
{
for (int j=0;j<col;j++)
{
cin>>B[i][j];
}
}
//计算A*B
for (int i=0;i<rowofA;i++)
{
for (int j=0;j<rowofB;j++)
{
o=0;//我就是这里忘了,导致后面无法进行运算!
m=0;
for(o=0;o<col;o++,m++)
C[i][j]+=A[i][o]*B[m][j];//以及这里也很容易出错!
}
}
//输出C
for (int i=0;i<rowofA;i++)
{
for (int j=0;j<rowofB;j++)
{
cout<<C[i][j]<<" ";
}
}
return 0;
}
栗子:输出n阶魔阵
#include <iostream>
using namespace std;
int main()
{ //定义
int n=0;
int zu[100][100]={0};
int row=0;
//shuru
cin>>n;
int col=n/2;
//填数1
zu[0][n/2]=1;
//xuhuantianshu
for (int i=2;i<=n*n;i++)
{
int a=row;
int b=col;
if (row-1==-1) row=n-1;
else row--;
if (col+1==n) col=0;
else col=col+1;
if(zu[row][col]==0) zu[row][col]=i;
else
{
if (a+1==n) a=0;
else a++;
zu[a][b]=i;
row=a;
col=b;
}
}
//shuchu
for (int u=0;u<n;u++)
{
cout<<endl;
for (int p=0;p<n;p++)
{
cout<<zu[u][p]<<" ";
}
}
return 0;
}
改进:比如行列换的时候会遇见 第零行-1变成第-1行怎么办?
rol=(rol-1+scale)%scale
要绘表 cout<<zu[u][p]<<'/t'; 绘表‘/t’
5.4字符串
字符串的定义:由一系列字符组成的一个数据称为字符串。字符串的本质是一系列的有序字符,因此可以用一个字符数组来保存这组字符 。用数组名表示这个字符串。
字符串的分类
- 字符串常量:用一对双引号括起来,如”Hello,world”。
- 字符串变量:用字符类型的数组来表示。
字符串的储存
需要用‘\0’表示字符串的结束,所以字符串所需的存储空间比实际的字符串长度大1 。
e.g:如要将字符串”Hello,world”保存在一个数组中 ,该数组的长度为12。
字符串的初始化
char ch[ ] = { ‘H’, ’e’, ’l’, ’l’, ’o’, ’,’, ’w’, ’o’, ’r’, ’l’, ’d’, ’\0’};注意:‘a’是简单字符变量 “a”是数组
char ch[ ] = {”Hello,world”};
char ch[ ] = ”Hello,world”;
空字符串
不包含任何字符的字符串称为空字符串,空字符串占用的空间为1个字节,存储‘\0’。
\n是换行
\0是字符串结束标志。只要有空间,就会自动填\0~我觉得还是自动有\0比较好
输入一个字符串(少于80个字符),统计并输出其中元音字母(AEIOUaeiou)的个数(不区分大小写)。错的很傻
#include <iostream>
using namespace std;
int main()
{ //定义与输入
int Count=0;
char zu[81];
cin.getline(zu,82,'\n');//注意\n不进入数组中
//
for (int i=0;;i++)
{
if (zu[i]=='\0')//注意只要有/0的位置就会自动补/0
break;
if(zu[i]=='a'||zu[i]=='e'||zu[i]=='i'||zu[i]=='o'||zu[i]=='u'||zu[i]=='A'||zu[i]=='E'||zu[i]=='I'||zu[i]=='O'||zu[i]=='U')
Count+=1;
}
cout<<"Count="<<Count;
return 0;
}
字符串的输入
F1:cin.getline(字符数组,数组长度,结束标记); cout << ch;
读取包含空白字符的一句话。直到达到结束标记或者字符串读满(包含\0)。默认结束标记为’\0’。
cin.getline(zu,6)也可以,属于是省略了结束标记,默认’/0‘
易错:写成cin.get,\n写成/n,正确是cin.get(zu,80,'\n')
🌰栗子:
char x[4];
cin.getline(x, 4, ‘2’);
cout <<x;
键入:1234 , 显示:1易错并不包括2的
键入:13456,显示:134
键入:1 345, 显示:1 3
F2: cin >> ch; cout << ch;
无法输入包含空白字符的字符串。要注意输入的字符串的长度不能超过数组的长度。
字符串的输出
其他数组都是cout<<zu; 显示的是数组首地址
而字符串不一样,cout<<zu; 显示的是hello(如果想显示数组首地址,cout << (void *) zu)
cout<<zu+2 显示llo
for (int i=0;zu[i]!='\0';i++)
字符串の处理函数
栗子:输入一行文字,统计有多少个单词。思路是空格,后面不是空格就算一个单词,在1的基础上。
#include <iostream>
using namespace std;
int main()
{ //定义
char zu[100];
int num=1;
//
cin.getline(zu,8);
//
for (int i =0;i<8;i++)
{
if (zu[i]==' '&&zu[i+1]!=' ')
num+=1;
}
cout<<num;
return 0;
}
cap.6过程封装-函数
6.1 函数的用途与定义
函数的分类:
标准库函数:ANSI/ISO C++定义的标准库函数 &第三方库函数(卖的那些)。
调用前需要#include相应的头文件。
自定义函数:用户自己编的,也可以去卖
函数定义:
int max(int a, int b)
{
xxx
return(a)
}
返回值return:
若函数没有返回值,类型标识符用void。没有返回值的函数也称为过程。
只能有一个返回值,可以有多条返回语句。
返回值不能是数组!
无参数、无返回值,int max() {xx} 都不用写return!
6.2 函数的使用
函数的声明:
格式: 返回类型 函数名(参数表);
参数表中的每个参数说明可以是类型,也可以是类型后面再接一个参数名。
如:int max(int, int); int max(int a, int b);
如果被调函数的定义在主调函数之前,可以不必加声明。
函数调用:
函数名 (实际参数表)
如:cout << Getmax(x , y );
函数调用可以套用的!如 p(Getmax(x,y))
存储单元问题:
实参和形参各自占用一个独立的存储单元,不可能共用。
默认参数:
(●ˇ∀ˇ●) /
对于某些函数,程序往往会用一些固定的值去调用它。
例如对于以某种数制(2进制、8进制、10进制、16进制)输出整型数的函数print: void print(int value, int base); 在大多数情况下都是以10进制输出,因此base的值总是为10。
C++在定义或声明函数时可以为函数的某个参数指定默认值。
当调用函数时没有为它指定实际参数时,系统自动将默认值赋给形式参数。
例如,可以将print函数声明为void print(int value, int base=10),调用print(20),等价于 print(20, 10)。
又例如:int special(int x=2, float y=1.5);
调用时可用:
special(5, 3.2); //x=5; y=3.2
special(6); //x=6; y=1.5
special( ); //x=2; y=1.5
6.3 变量的作用域与存储类别
局部变量 和 全局变量
全局变量:在所有函数之外定义的变量 ;作用范围:从定义位置到文件结束;用关键词extern在函数内说明此全局变量。全局变量破坏了模块化,建议尽量少使用。当全局变量和局部变量同名时,在局部变量的作用范围中全局变量被屏蔽。如果要使用全局变量,可以使用作用域运算符::。
※当内部块与外部块有同名变量时,在内部块中屏蔽外部块的同名变量。
※形式参数不可以和局部变量同名。
存储类别
每个变量有两个属性:
数据类型:变量所存储的数据类型
存储类别:变量的存储位置和期限。存储类型决定了变量的生存期。
分类:
自动变量:auto。生存期是定义它的语句块。auto int i 等价于 int i;
静态变量:static。生存期是整个程序。只运行第一遍语句,之后就存着运行的数。未被程序员初始化的静态变量都由系统初始化为0。虽然局部静态变量在函数调用结束后仍然存在,但其他函数不能引用它。局部的静态变量在程序执行结束时消亡。
寄存器变量:register
外部变量:extern。 extern int num;用extern可引用另一文件中的全局变量。
int f(int a)
{ int b=0;
static int c=3;
b=b+1;
c=c+1;
return(a+b+c);
}
void main()
{int a=2,i;
for (i=0; i<3; ++i)
cout << f(a);
}
运行结果为:7 8 9
6.4函数变量为数组
函数:int average(int array[ ],int N)
调用时:cout<<average(sum)直接调用数组的名字
♥注意:在函数操作数组是会改变主函数中的值哦,,形式参数和实际参数是同一数组!!!
o(* ̄▽ ̄*)ブ在函数中并没有定义新的数组; 对形式参数数组指定规模是没有意义的,形式参数数组不需要指定大小,所以方括号中为空; 函数如何知道数组的规模?用另一个整型参数表示;
总结:数组传递需要两个参数: 数组名 ,数组规模。
6.5内联、重载、模板、递归
6.5.1内联函数
内联函数的定义:在函数头部前加保留词inline 栗子:inline float cube(float s)
理解:在调用内联函数时,编译器直接用内联函数的代码替换函数调用,于是省去了函数调用的开销。
慎用内联函数:
- 内联以代码复制(膨胀)为代价,省去了函数调用的开销,提高函数的执行效率。如果相比于执行函数体内代码的时间,函数调用的开销可以忽略不计,那么效率的收获会很小。
- 内联函数不能递归!
- 内联函数必须定义在被调用之前。
- 以下情况不宜用内联: 如果函数体代码比较长,内联将导致内存消耗代价较高。 如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大
6.5.2重载(好用的捏
理解:让具有相似功能的函数有一样的名字,比如取2个数的最大值、3个数的最大值、4个数的最大值,可以都叫max函数。
int max(int a1, int a2);
int max(int a1, int a2, int a3);
int max(int a1, int a2, int a3, int a4);
int max(int a1, int a2, int a3, int a4, int a5);
谢谢编译器:由编译器确定某一次函数调用到底是调用了哪一个具体的函数。这个过程称之为绑定(binding,又称为联编或捆绑)。
6.5.3模板(好用的捏
定义形式:class T T是数据类型捏
template<模板形式参数表>
返回类型 函数名(形式参数表)
{
//函数定义体
}
template<class T>
T max(T a, T b)
{ return a>b ? a : b;}
栗子:
template<class T1,class T2, class T3>
T3 calc( T1 x, T2 y)
{ return x+y; }
main()
{
int x = calc<int , char , int >(1,’2’);
char y = calc<int , char, char>(1,’2’);
cout << x << " " << y << endl;
}
6.5.4递归(简化的捏
必须能写出这个形式:
if (条件)
return (不需要递归的简单答案);
else
return (递归调用同一函数);
栗子:
①阶乘
long p(int n)
{
if (n == 0) return 1;
else return n * p(n-1);
}
②求n的k次幂
int RaiseIntToPower(int n, int k)
{ if (k == 0)
return(1);
else
return( n * RaiseIntToPower( n, k - 1));
}
优缺点:
逻辑清晰,好写,代码就几行,但是运行的时间是灾难性的。
cap7指针
7.1指针简介
7.1.1指针概念
定义:int *intp
统配指针:void * 可以指向任何类别
空指针:NULL
7.1.2指针运算(intp是地址,*intp是那个变量呀)
赋值:intp=&x(&后不可以加常量或表达式,只能加变量)
赋初值这么写:int x, *p=&x;
间接访问:*intp=5等价于x=5;
算术运算:指针+1表示数组中指针指向数组的下一元素地址;(存的地址其实是+4)
指针-1表示数组中指针指向数组的上一元素地址;
p1 - p2也正确
7.1.3指针与数组
指针和数组关系密切,常常可以互换使用。
数组名可以看成是常量指针,数组名是数组的起始地址,也就是第0个元素的地址。
int a[10], *p,并且执行了 p = a,则p[5]=a[5]都一样的,相当于换名了
数组元素的指针表示:*(p+1)=p[1]
注意数组名是常量指针,不可以加减。
7.1.4指针作为函数 参数和返回值
背景:我们的swap函数可是没法交换的。也是没法返回两个数的
swap(&x, &y);
swap(int *a, int *b)
{
int c;
c=*a;
*a= *b;
*b=c;
}
解一元二次方程!存在地址里,看例子吧
数组传递:type fun(type a[ ], int size); 也可写为 type fun(type *p , int size);
建议:如果传递的是数组,用第一种形式;如果传递的是普通的指针,用第二种形式。
调用时:func(数组名,长度)
还挺灵活:sort(a, 100); //排序整个数组
sort(a, 50); //排序数组的前50个元素
sort(a+50, 50); //排序数组的后50个元素
返回指针的函数:
返回指针的函数原型:类型 *函数名(形式参数表);
当函数的返回值是指针时,返回地址对应的变量不能是局部变量。
引用和引用传递:
给一个变量取一个别名。隐式指针。
例如:int i; int &j = i;
好多不能😅:::
定义引用时必须立即对它初始化,不能定义完成后再赋值。
为引用提供的初始值可以是一个变量或另一个引用。
引用不可重新赋值,不可使其作为另一变量的别名。
int &a[3]; //不能建立引用数组
int &&r; //不能建立引用的引用
引用参数 void swap(int &m, int &n) { int temp; temp=m; m=n; n=temp; } 调用:swap(x, y)
返回引用的函数:
返回引用的函数原型:类型 &函数名(形式参数表);
左值????????????
7.2动态内存分配
new:用于进行内存分配
p = new type;
p = new type[size];//分配数组p=new int[10];
p = new type(56);
delete:释放new分配的内存
delete p;
delete [ ] p;
动态分配检查:int *p; p = new int; if(!p){cout << "allocation failure\n"; return 1;
#include <cassert> assert (p != NULL); //若p等于NULL,则退出程序执行
栗子:
int *p, i, n;
if (!(p = new int [n])) exit(1);
for (i=0; i<n; ++i) cin >> p[i];
for(i=0; i<n; ++i) sum += p[i];
delete [] p;
7.3字符串再讨论
字符串的另一种表示是定义一个指向字符的指针,然后直接将一个字符串常量赋给它。
eg:char * string; string = “abcde”;
将存储字符串“abcde”的内存的首地址赋给指针变量string。
字符串常量存储在一个称为数据段的内存区域里。数据段区不可修改。
字符指针: cout << p; 显示整个字符串
cout << *p; 显示单个字符;
常量指针:定义格式 const type * 指针变量名;
type const * 指针变量名;
比如:const int * p;
作用:指针指向的内存内容不可修改,指针可移动;
指针常量:定义格式 type * const 指针变量名;
比如:int * const p;
作用:指针指向的内存内容可修改,但指针不可修改,指针定义时需同时初始化;
指向常量的常量指针:定义格式 const type * const 指针变量名;
比如:const int * const p;
后置++与指针运算优先级、数据交换问题
7.4指针数组 与多级指针
指针数组:一个数组,如果他的元素均为指针,则称为指针数组。
定义形式:char *string[10]
main函数的参数:???????????????????????
多级指针:指针指向的内容还是一个指针,称为多级指针。
两级指针:类型名 **变量名; 三级指针:类型名 ***变量名;