C语言 二 数组/指针

1. 数组

数组声明

  1. 元素值类型 2.数组名 3.数组长度

int myArray[10];

数组下标

  • 数组元素索引从0开始,到length-1
  • 有效下标
#include<iostream>
using namespace std;
int a[100] ;
int main(){
	a[110] = 1;   //不会报错
	cout<<a[110]<<endl;
	cout<<sizeof(a) / sizeof(int) <<endl; //长度为100
	return 0;
} 

数组初始化
只有定义数组时才能使用初始化,此后就不能用,且不能将一个数组赋值给另一个数组,但之后可以给数组元素赋值

  1. 指定长度,指定所有数据
int a[5] = {1,2,3,4,5};
  1. 指定长度,指定部分数据(前几个)
int a[5] = {1,2,3}; //长度为5,前三个指定,后两个随机
  1. 不指定长度,但指定所有数据
int a[] = {1,2,3,4,5};  //自动计算长度为5
  1. 指定长度,不指定数据
int a[5];
a[0] = 1;
a[1] = 2;

错误的初始化方法:

int a[5];
a = {1,2,3,4,5}; //not allowed

int c[5] = {5,4,3,2,1};
a = c			 //not allowed

2. 指针

2.1 地址

位(bit) : 一个0或1
字节(Byte): 8位

任何数据都有存放的地址与存储的方式

不同数据类型其长度与编码方式均不同

数据类型长度(字节)编码方式取值范围
int4补码-2147483648-2147483647
short2补码-32768-32767
unsigned short2补码0-65535
long8补码
float4IEEE 754
double8IEEE 754
char1ASCII-128-127

注:int/short/long/float/double在不同机器上长度不一样,sizeof(a)获取其存储长度(单位字节)

整数的地址与编码

例:

short c = 32768; // -> -32767
unsigned short c = 32768; // -> 32768
unsigned short c = -1; // -> 65535
unsigned short c = 65536; // -> 0

浮点数的地址与编码
在这里插入图片描述在这里插入图片描述
参考:浮点数的表示方法

字符型地址与编码

ASCII码对照表

需要记住的是:

  1. 小写字母比大写字母大32
char a = 'A';
char b = 'a';
cout << b-a << endl;  // 32
  1. 判断一个字符是否是字母:
void is_letter(char c){
    if(c>='A'&&c<='Z') cout <<"大写字母" << endl;
    else if(c>='a'&&c<='z') cout<<"小写字母"<<endl;
    else cout <<"不是字母"<< endl;
}

2.2指针

地址运算符 & 可获得变量的地址

 //地址运算符的使用
 int c[] = {1, 2, 3};
 cout<<"c[0] address: "<<&c[0]<<endl;         //0x6ffe00
 cout<<"c[1] address: "<<&c[1]<<endl;         //0x6ffe04
 cout<<"size of int: "<<sizeof(int)<<endl;    //4  int 32位 4Byte

在这里插入图片描述
一种新的变量 指针–用于存储值的地址,通过 * 运算符可以获得该地址处的变量
两个恒等式(p:指针变量 a:变量):
*p = a
&a = p

//指针变量的定义与使用
int a = 6;
int* p; // 指针(变量)的声明 
p = &a;  // 指针(变量)的赋值  可直接写为 int* p = &a;

cout<<"two ways to express value"<<endl;
cout<<a<<endl;  //6
cout<<*p<<endl; //6

cout<<"two ways to express address"<<endl;
cout<<&a<<endl; //0x6ffe14
cout<<p<<endl;  //0x6ffe14

在这里,*p的类型为int, 而p的类型为指向Int的指针

不同类型的长度不同,不同数据类型的指针(地址)长度相同

//指针变量的加减
int a[3] = {1, 2, 3};
double d[3] = {4.5, 5.5, 6.5};
int* p_a = a;
double* p_d = d;
cout<<"p_a: "<<p_a<<"   *p_a= "<<*p_a<<endl;     
cout<<"p_a+1: "<<p_a+1<<" *(p_a+1)= "<<*(p_a+1)<<endl;   // 指针变量加1, 增加的量等于它指向的字节树
cout<<"p_d: "<<p_d<<"   *p_d= "<<*(p_d)<<endl;       
cout<<"p_d+1: "<<p_d+1<<" *(p_d+1)= "<<*(p_d+1)<<endl;  

cout<<endl<<"sizeof int= "<<sizeof(int)<<endl;
cout<<"sizeof double= "<<sizeof(double)<<endl;

指针的错误使用,一定要在使用指针之前给出一个确定的地址

int* p;
*p = 23;        //错误
cout<<*p<<endl;   

1.3指针与数组

C++将数组名解释成数组第一个元素的指针

int a[3] = {1, 2, 3};
cout<<"a是什么? "<<a<<endl;   
int* p = a;
cout<<"p= "<<p<<endl;

两个恒等式
a[i] == *(a+i)
&a[i] == a+i

double a[3]={10000.0, 20000.0, 30000.0};
  
cout<<"两种遍历数组的方法"<<endl;
for(int i=0;i<3;i++)
	cout<<a[i]<<endl;
for(int i=0;i<3;i++)
	cout<<*(a+i)<<endl;
]
cout<<"看一下数组的地址"<<endl;
for(int i=0;i<3;i++)
	cout<<a+i<<endl;

在这里插入图片描述

3.函数与指针

3.1形参与实参

void swap(int x, int y){    //这里的x,y是普通变量
	int temp=x;
	x = y;
	y = temp;
}

void swap2(int* x, int* y){   //这里的x,y是指针变量,也就是地址
	int temp = *x;
	*x = *y;
	*y = temp;
}

int main(){
int a=1, b=2;
swap(a, b);
cout<<"a= "<<a<<" b= "<<b<<endl;
swap2(&a, &b);   //传递地址  相当于 int* x = &a 
cout<<"a= "<<a<<" b= "<<b<<endl;
} 

3.2一维数组作为函数的输入输出

void printArray(int a[4], int n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<endl;
	}
}
void printArray2(int a[], int n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<endl;
	}
}
void printArray3(int *a, int n){   
	for(int i=0;i<n;i++){
		cout<<a[i]<<endl;
	}
}

int main(){
int a[3]={1, 2, 3};
printArray3(a, 3);
} 

将数组作为函数的参数,实际上并没有将数组的内容传递给函数,而是将数组的地址(指针)传递给函数

一维数组作为函数的输出

void getAbs(int a[], int n){
	for(int i=0;i<n;i++){
		if(a[i]<0) a[i]=-a[i];
	}
}

void printArray(int a[], int n){
	for(int i=0;i<n;i++){
		cout<<a[i]<<endl;
	}
}

int main(){
int a[3]={1, -2, 3};
getAbs(a, 3);
printArray(a, 3);
} 

3.3二维数组作为函数的输入

void swap(int x, int y){    //这里的x,y是普通变量
	int temp=x;
	x = y;
	y = temp;
}

void swap2(int* x, int* y){   //这里的x,y是指针变量,也就是地址
	int temp = *x;
	*x = *y;
	*y = temp;
}

int main(){
int a=1, b=2;
swap(a, b);
cout<<"a= "<<a<<" b= "<<b<<endl;
swap2(&a, &b);   //传递地址  相当于 int* x = &a 
cout<<"a= "<<a<<" b= "<<b<<endl;
} 

3.总结

指针

int n = 3;  //普通变量

取地址运算符&&n:  n的地址

指针变量:存储地址的变量
声明  int* p
赋值  p = &n
或连在一起  int* p = &n

两个恒等式
*p = n (都是数值)
p = &n  (都是地址)

数组与指针

int a[3] = {1, 2, 3};  //数组
a : 指针变量,  是数组第一个元素的地址
*p = a  //指针变量赋值给指针变量

两个恒等式
a[i] = *(a+i)  数组第i个元素的数值
&a[i] = a+i    数组第i个元素的地址

两种遍历数组的方法
for(int i=0;i<n;i++)
 cout<<a[i]<<endl;
 cout<<*(a+i)<<endl;

数组与函数

<--一维数组-->
函数声明  
void func(int a[], int n)   //数组地址,数组长度n
函数内对数组的操作会作用与原数组

函数的使用:
a[5] = {1, 2, 3, 4, 5};
func(a, 5);
printArray(a, 5);

<--二维数组-->
函数声明
void func(int a[][4], int m)  //必须指明数组的列数
函数使用
a[][4] ={..};
func(a, 3);

实例:求成绩平均值函数

#include <iostream>
#include <iomanip>
#define m_num 4       //m_num 不能和变量m冲突 
using namespace std;


//输入成绩函数   n个人   m科成绩 
void input(double a[][m_num],int n,int m)
{
int i,j;
for(i=0;i<n;i++)
	{for(j=0;j<m;j++)
		cin>>a[i][j];
	}
}


//平均函数:——我要返回ave[i]这个数组,怎么返回?
void fun(double (*a)[m_num], double ave[], int n, int m)  //n行m列 
{
  	//int i,j;
	double sum;
 	for(int i=0;i<m;i++){
  	 	sum=0.0;
  		for(int j=0;j<n;j++){
   			sum+=a[j][i];
   		}
  		ave[i]=sum/(double(n));
 	}
}

void output(double a[][m_num],double ave[], int n, int m)
{	int i,j;
	for(j=0;j<m;j++)
				//cout<<stew(5)<<a[i][j]<<endl;
		cout<<"第"<<j+1<<"科的平均成绩"<<ave[j]<<endl;
}

//主函数:
int main()
{
int n;
cout<<"输入有多少人"<<endl;
cin>>n;

double a[n][m_num];
double ave[m_num]={0};
cout<<"输入每个人成绩"<<endl;

input(a,n,m_num);
fun(a,ave,n,m_num);
output(a,ave,n,m_num);
}

4. 引用

4.1引用的定义

引用:已定义的变量的别名(相同内存单元)
& 的两种含义:1.取地址符 2.引用

int a = 1;
int *p = &a; //取地址符,声明指针变量
int &b = a;  //声明引用变量

int a;
int &b = a; //引用的声明,必须在声明引用时将其初始化,引用不能赋值
这里的 int& 指的是指向int的引用, b和a指向相同的值和内存单元,改变其中一个另一个也会改变

int a = 1;
int &b = a;
cout<<"a="<<a<<", b="<<b<<endl;   //a=1, b=1
a++;
cout<<"a="<<a<<", b="<<b<<endl;   //a=2, b=2
void swap(int& a, int& b){
	int temp = a;
	a = b;
	b = temp;
	}
int main(){
	int a=1, b=2;
	swap(a, b);
	cout<<a<<b<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值