1. 数组 c++
声明:
一维数组: type arrayName [ arraySize ];
多维数组: type name[size1][size2]...[sizeN];
比如结构体数组的初始化和访问:
#include <iostream>
#include<stdlib.h>
using namespace std;
struct Share {
long int share_price;
char time_date[20];
};
int main()
{
//一维数组
Share one_D_share[] = {
{
100, "2017\\05\\31_09:00"}, {
200,"2017\\05\\31_09:01"} };
for (size_t index = 0; index < 2; ++index) {
cout << one_D_share[index].share_price<<'\t' << one_D_share[index].time_date << endl;
}
//二维数组
Share two_D_share[2][2] = {
{
{
100, "2017\05\31_09:00"}, {
200,"2017\\05\31_09:01"}},{
{
300, "2017\05\31_09:02"}, {
400,"2017\05\31_09:04"}} };
for (size_t i = 0; i < 2; ++i)
for(size_t j = 0; j < 2; ++j){
cout << two_D_share[i][j].share_price << two_D_share[i][j].time_date << endl;
}
//对部分元素赋值,为魏阙赋值的部分整数位0,字符为'\0'
Share share_3[3] = {
{
100, "2017\\05\\31_09:00"}, {
200,"2017\\05\\31_09:01"} };
for (size_t index = 0; index < 3; ++index) {
cout << share_3[index].share_price << '\t' << share_3[index].time_date << endl;
}
system("pause");
return 0;
}
2. 指针
1. C中指针的概念
数据存放在内存中,而不同类型的数据占用的字节数不同,比如int占用4个字节。为了正确的访问到这些数据,必须为每个字节编号,比如旅馆中的房间号,根据编号可以准确的找到某个字节。
一下是4G内存每个字节的编号(十六进制表示:)
内存中字节的编号称为地址(Address)或指针(Pointer)。地址从 0 开始依次增加,对于 32 位环境,程序能够使用的内存为 4GB,最小的地址为 0,最大的地址为 0XFFFFFFFF。
#include <stdio.h>
#include <stdlib.h>
void Function() {
}
int main() {
int a = 16;
char str[20] = "C语言指针";
int arr[] = {
10, 100, 1000 };
printf("%#X, %#X, %#X, %#X\n", &a, &str, &arr, &Function);
printf("%#x, %#X, %#X, %#X\n", a, str, arr, Function);
system("pause");
return 0;
}
out:
0X58FEAC, 0X58FE90, 0X58FE7C, 0XFA1348
0x10, 0X58FE90, 0X58FE7C, 0XFA1348
%#x
是16进制输出
一切都是地址
CPU访问内存需要的是地址,而非变量名和函数名,在编译和链接成可执行程序后,变量名和函数名都会被替换成地址。
比如:假设int类型 a, b, c的内存地址为 0X1000, 0x1004, 0x1008,则减法运算c=a-b;
在执行过程中转换为:
( 0 x 1008 ) = ( 0 X 1000 ) − ( 0 x 1004 ) (0x1008)=(0X1000)-( 0x1004) (0x1008)=(0X1000)−(0x1004),其中()
为取值操作,表达式的意思是,取出地址0X1000,0X1004中的值,相减赋值到0X1008的内存地址中。
需要注意的是:比如在上的胡代码示例中,变量名代表的是数据本身,而函数名,数组名,字符串名表示的是首地址
2.C指针
如果想在程序中访问数据的内存地址,只能需要指针变量了。
在C语言中们可以使用一个变量来存放指针(地址),该变量称为指针变量,值为某一数据的地址,该数据可以使数组,字符串,函数,另一普通变量火指针变量。
定义指针变量
datatype *name
或者datatype *name=value
*
代表是一个指针变量,datatype
为该指针所指向数据的数据类型。比如:
int *ip1=NULL;
int a = 100;
ip1 = &a;
其中,&
为取地址运算符
内存指向模型:
inp指向地址0x1000,然后根据类型为int,则向后取4个字节的地址,作为数据块,最终会得到a的数据。
指针可以向普通变量一样多次写入和修改
//定义int和char普通变量
int a=0, b=1;
char c='a', d='b';
//定义指针变量
int *ip1 = &a;
char *cp2 = &c;
//修该指针变量
ip1 = &b;
cp2=&c;
/*
与下列修改方法的不同:
*ip1 = b;
*cp2 = d;
指向的地址未变,更改了对应地址的内容,
而上一个是更改了指向的地址,也就是更改了指针变量本身的内容
*/
在声明变量是必须带*
,而在给指针变量赋值是不需要,实际上*ip
表示的是解引用,意思是取出ip所指向地址的数据
修改过程中,指针变化情况:
指针变量可以连续定义:注意每一变量前都要有*
int *a, *b, *c; //a、b、c 的类型都是 int*
而如果写成下面的形式,只有a为指针 变量,b,c为int类型的变量。
int *a, b,c;
解引用获取数据
格式: *pointer;
这里的*
为指针运算符,来取出某个地址上的数据:
int a = 20;
int *ip = &a;
printf("%d, %d\n", a, *ip);
out:
20, 20
处理流程为,在程序被编译和连接后,a,ip被替换为相应的地址0x1001和0x2007,使用*ip时,先通过地址0x2007获得ip的值,0x1001,也就是a的地址,然后再通过这个值取得变量a的数据,共进行两次运算;而使用a的话,只需要通过0x1001直接取得它的数据,只要一步计算。
修改内存数据
int a = 20, b = 200, c = 2000;
int *ip = &a;
*ip = b;
c = *ip;
printf("%d, %d,%d,%d\n", a, b,c,*ip);
out:
200, 200,200,200
*ip代表的是a中的数据,等价于a。可以将另外一份数据赋值给它,也可以将它赋值给别的数据。
注意:
*
在不同的场景下有不同的作用:在变量定义中,表明是指针变量和普通变量。而在使用指针变量是,前面加*
号表示获取指针指向的数据
更复杂的指针变量赋值:
int x, y, *px = &x, *py = &y;
y = *px + 5; //表示把x的内容加5并赋给y,*px+5相当于(*px)+5
y = ++*px; //px的内容加上1之后赋给y,++*px相当于++(*px)
y = *px++; //相当于y=(*px)++
py = px; //把一个指针的值赋给另一个指针
关于*和&的谜题
假设int类型的变量a,pa是指向它的指针,则
*&a: 理解为 *(&a),表示先取a的地址相当于pa,在对地址解引用,最表表示的是a
&*pa: 理解为&(*pa),表示先解引用pa,相当于a,在取a的地址,最终表示的pa
*
的总结
- 表示乘法,用于算数运算中
- 在定义指针变量时使用,以和普通变量区分
- 在使用指针变量时,表示解引用指针指向的数据
3.指针变量的运算
指针时一个用数值表示的地址,因此可以对指针执行算数: ++,–,+,-和比较运算==,<, >
值得注意的是,每次+或-,地址的增加或减少字节数与定义指针变量的类型有关:
int a = 10, *pa = &a, *paa = &a;
double b = 99.9, *pb = &b;
char c = '@', *pc = &c