当前位置: 首页 > news >正文

C/C++指针与数组(一)

预备知识
1、数据的存储
在这里插入图片描述

2、基本内建类型
1)类型的大小

C++ offers a flexible standard with some guaranteed minimum sizes, which it takes from C:

  • A short integer is at least 16 bits wide.
  • An int integer is at least as big as short.
  • A long integer is at least 32 bits wide and at least as big as int.
  • A long long integer is at least 64 bits wide and at least as big as long.

Many systems currently use the minimum guarantee, making short 16 bits and long 32 bits.This still leaves several choices open for int. It could be 16, 24, or 32 bits in width and meet the standard. It could even be 64 bits, providing that long and long long are at least that wide.
参考:C++ Primer Plus Sixth Edition

#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{cout << "sizeof(char)=" << sizeof(char) << endl;cout << "sizeof(short)=" << sizeof(short) << endl;cout << "sizeof(int)=" << sizeof(int) << endl;cout << "sizeof(float)=" << sizeof(float) << endl;cout << "sizeof(long)=" << sizeof(long) << endl;cout << "sizeof(long long)=" << sizeof(long long) << endl;cout << "sizeof(double)=" << sizeof(double) << endl;return 0;
}

在这里插入图片描述
2)类型代表的数据的大小

#include<iostream>
#include <climits> // use limits.h for older systems
using namespace std;
int main(int argc, char *argv[])
{char n_char = CHAR_MAX;short n_short = SHRT_MAX; // symbols defined in climits fileint n_int = INT_MAX; // initialize n_int to max int valuefloat n_float = FLT_MAX;long n_long = LONG_MAX;long long n_llong = LLONG_MAX;double n_double = DBL_MAX;cout << "Value Ranges:\tMinimum\t\t\tMaximum" << endl;cout << "char:\t\t" << CHAR_MIN << "\t\t\t" << CHAR_MAX << endl;cout << "short:\t\t" << SHRT_MIN << "\t\t\t" << n_short << endl;cout << "int:\t\t" << INT_MIN << "\t\t" << n_int << endl;cout << "float:\t\t" << FLT_MIN << "\t\t" <<  n_float << endl;cout << "long:\t\t" << LONG_MIN << "\t\t" << n_long << endl;cout << "long long:\t" << LLONG_MIN << "\t" <<n_llong << endl;cout << "double:\t\t" << DBL_MIN << "\t\t" << n_double << endl;return 0;
}

在这里插入图片描述

一、指向单一对象的指针和该指针的加减算术运算

#include<iostream>
#include <climits> // use limits.h for older systems
using namespace std;
int main(int argc, char *argv[])
{char chr;short sht = 1; // symbols defined in climits fileint in = 2; // initialize n_int to max int valuefloat fl = 3.0f;long lo = 4l;long long lolo = 5ll;double dou = 6.0;char* pChr = &chr;short* pSht = &sht;int* pIn = &in;float* pFl = &fl;long* pLo = &lo;long long* pLolo = &lolo;double* pDou = &dou;cout << "char类型指针及其算术运算:\t" << (void*)(pChr - 1) << '\t' << (void*)(pChr) << '\t' << (void*)(pChr + 1) << endl;cout << "short类型指针及其算术运算:\t" << pSht - 1 << '\t' << pSht << '\t' << pSht + 1 << endl;cout << "int类型指针及其算术运算:\t" << pIn - 1 << '\t' << pIn << '\t' << pIn + 1 << endl;cout << "float类型指针及其算术运算:\t" << pFl - 1 << '\t' << pFl << '\t' << pFl + 1 << endl;cout << "long类型指针及其算术运算:\t" << pLo - 1 << '\t' << pLo << '\t' << pLo + 1 << endl;cout << "longlong类型指针及其算术运算:\t" << pLolo - 1 << '\t' << pLolo << '\t' << pLolo + 1 << endl;cout << "double类型指针及其算术运算:\t" << pDou - 1 << '\t' << pDou << '\t' << pDou + 1 << endl;return 0;
}

在这里插入图片描述

实际上,由于指针退化,下面所说的各种类型的指针还可以指向对应类型的数组,但此处暂时认为其指向单一对象的指针。由于内存地址在计算机中用十六进制表示,注意十六进制与十进制算术运算的异同。

pChr的类型为char*,即pChr指向一个char类型的对象,而这个对象占1个字节,所以对它-1或者+1,指针只向前或者向后移动1个字节。

pSht的类型为short*,即pSht指向一个short类型的对象,而这个对象占2个字节,所以对它-1或者+1,指针只向前或者向后移动2个字节。

pIn的类型为int*,即pIn指向一个int类型的对象,而这个对象占4个字节,所以对它-1或者+1,指针只向前或者向后移动4个字节。

pFl的类型为float*,即pFl指向一个char类型的对象,而这个对象也占4个字节,所以对它-1或者+1,指针只向前或者向后移动4个字节。

pLo的类型为long*,即pLo指向一个long类型的对象,而这个对象也占4个字节,所以对它-1或者+1,指针只向前或者向后移动4个字节。

pLolo的类型为long long*,即pLolo指向一个long long类型的对象,而这个对象占8个字节,所以对它-1或者+1,指针只向前或者向后移动8个字节。

pDou的类型为double*,即pDou指向一个double类型的对象,而这个对象也占8个字节,所以对它-1或者+1,指针只向前或者向后移动8个字节。

二、指向对象数组的指针和该指针的加减算术运算
1、指向一维数组的指针和该指针的加减算术运算

#include<iostream>
#include <climits>
using namespace std;
int main(int argc, char *argv[])
{char chr[5] = { 'a', 'b', 'c', 'd', 'e' };short sht[5] = { 1, 2, 3, 4, 5 };int in[5] = { 1, 2, 3, 4, 5 };float fl[5] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f };long lo[5] = { 1l, 2l, 3l, 4l, 5l, };long long lolo[5] = { 1ll, 2ll, 3ll, 4ll, 5ll };double dou[5] = { 1.0, 2.0, 3.0, 4.0, 5.0 };char(*pChrArr)[5] = &chr; //声明并定义char(*)[5]类型指针,此指针指向该整个数组short(*pShtArr)[5] = &sht; //声明并定义short(*)[5]类型指针,此指针指向该整个数组int(*pInArr)[5] = &in; //声明并定义int(*)[5]类型指针,此指针指向该整个数组float(*pFlArr)[5] = &fl; //声明并定义float(*)[5]类型指针,此指针指向该整个数组long(*pLoArr)[5] = &lo; //声明并定义long(*)[5]类型指针,此指针指向该整个数组long long(*pLoloArr)[5] = &lolo; //声明并定义longlong(*)[5]类型指针,此指针指向该整个数组double(*pDouArr)[5] = &dou; //声明并定义double(*)[5]类型指针,此指针指向该整个数组cout << "char(*)[5]类型指针及其算术运算:\t\t" << (void*)(pChrArr - 1) << '\t' << (void*)(pChrArr) << '\t' << (void*)(pChrArr + 1) << endl;cout << "short(*)[5]类型指针及其算术运算:\t" << pShtArr - 1 << '\t' << pShtArr << '\t' << pShtArr + 1 << endl;cout << "int(*)[5]类型指针及其算术运算:\t\t" << pInArr - 1 << '\t' << pInArr << '\t' << pInArr + 1 << endl;cout << "float(*)[5]类型指针及其算术运算:\t" << pFlArr - 1 << '\t' << pFlArr << '\t' << pFlArr + 1 << endl;cout << "long(*)[5]类型指针及其算术运算:\t\t" << pLoArr - 1 << '\t' << pLoArr << '\t' << pLoArr + 1 << endl;cout << "longlong(*)[5]类型指针及其算术运算:\t" << pLoloArr - 1 << '\t' << pLoloArr << '\t' << pLoloArr + 1 << endl;cout << "double(*)[5]类型指针及其算术运算:\t" << pDouArr - 1 << '\t' << pDouArr << '\t' << pDouArr + 1 << endl;return 0;
}

在这里插入图片描述

指向一维数组的指针的声明及定义格式:typename (*pointer) [n] = &arrayname; 即指针pointer指向一个含有n个元素的typename类型的一维数组,该数组名称为arrayname。

指向一维数组的指针的类型为typename (*) [n]

pChrArr的类型为char(*)[5],即 pChrArr指向一个包含5个char类型对象的数组,这个单一对象占1个字节,但是该数组占1*5个字节,所以对它-1或者+1,指针只向前或者向后移动5个字节。

pShtrArr的类型为short(*)[5],即pShtArr指向一个包含5个short类型对象的数组,这个单一对象占2个字节,但是该数组占2*5个字节,所以对它-1或者+1,指针只向前或者向后移动10个字节。

pInArr的类型为int(*)[5],即pInArr指向一个包含5个int类型对象的数组,这个单一对象占4个字节,但是该数组占4*5个字节,所以对它-1或者+1,指针只向前或者向后移动20个字节。

pFlrArr的类型为float(*)[5],即pFlArr指向一个包含5个char类型对象的数组,这个单一对象也占4个字节,但是该数组占4*5个字节,所以对它-1或者+1,指针只向前或者向后移动20个字节。

pLoArr的类型为long(*)[5],即pLoArr指向一个包含5个long类型对象的数组,这个单一对象占4个字节,但是该数组占4*5个字节,所以对它-1或者+1,指针只向前或者向后移动20个字节。

pLoloArr的类型为long long(*)[5],即pLoloArr指向一个包含5个long long类型对象的数组,这个单一对象占8个字节,但是该数组占8*5个字节,所以对它-1或者+1,指针只向前或者向后移动40个字节。

pDouArr的类型为double(*)[5],即pDouArr指向一个包含5个double类型对象的数组,这个单一对象占8个字节,但是该数组占8*5个字节,所以对它-1或者+1,指针只向前或者向后移动40个字节。

2、指向二维数组的指针和该指针的加减算术运算

#include<iostream>
#include <climits>
using namespace std;
int main(int argc, char *argv[])
{char chr[5][5] = { { 'a', 'b', 'c', 'd', 'e' },{ 'f', 'g', 'h', 'i', 'j' },{},{},{}} //未初始化的元素置空short sht[5][5] = { { 1, 2, 3, 4, 5 },{ 6, 7, 8, 9, 10 },{},{},{}}; //未初始化的元素置0int in[5][5] = { { 1, 2, 3, 4, 5 },{ 6, 7, 8, 9, 10 },{},{},{}}; //未初始化的元素置0float fl[5][5] = { { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },{},{},{}}; //未初始化的元素置0long lo[5][5] = { { 1l, 2l, 3l, 4l, 5l, },{ 6l, 7l, 8l, 8l, 10l },{},{},{}}; //未初始化的元素置0long long lolo[5][5] = { { 1ll, 2ll, 3ll, 4ll, 5ll },{ 6ll, 7ll, 8ll, 9ll, 10ll },{},{},{}}; //未初始化的元素置0double dou[5][5] = { { 1.0, 2.0, 3.0, 4.0, 5.0 },{ 6.0, 7.0, 8.0, 9.0, 10.0 },{},{},{}}; //未初始化的元素置0cout << "chr[4][4]:\t" << chr[4][4]<< endl;cout << "sht[4][4]:\t" << sht[4][4] << endl;cout << "in[4][4]:\t" << in[4][4] << endl;cout << "fl[4][4]:\t" << fl[4][4] << endl;cout << "lo[4][4]:\t" << lo[4][4] << endl;cout << "lolo[4][4]:\t" << lolo[4][4] << endl;cout << "dou[4][4]:\t" << dou[4][4] << endl << endl;char(*pChrArr)[5][5] = &chr; //声明并定义char(*)[5][5]类型指针,此指针指向该整个二维数组short(*pShtArr)[5][5] = &sht; //声明并定义short(*)[5][5]类型指针,此指针指向该整个二维数组int(*pInArr)[5][5] = &in; //声明并定义int(*)[5][5]类型指针,此指针指向该整个二维数组float(*pFlArr)[5][5] = &fl; //声明并定义float(*)[5][5]类型指针,此指针指向该整个二维数组long(*pLoArr)[5][5] = &lo; //声明并定义long(*)[5][5]类型指针,此指针指向该整个二维数组long long(*pLoloArr)[5][5] = &lolo; //声明并定义longlong(*)[5][5]类型指针,此指针指向该整个二维数组double(*pDouArr)[5][5] = &dou; //声明并定义double(*)[5][5]类型指针,此指针指向该整个二维数组cout << "char(*)[5][5]类型指针及其算术运算:\t" << (void*)(pChrArr - 1) << '\t' << (void*)(pChrArr) << '\t' << (void*)(pChrArr + 1) << endl;cout << "short(*)[5][5]类型指针及其算术运算:\t" << pShtArr - 1 << '\t' << pShtArr << '\t' << pShtArr + 1 << endl;cout << "int(*)[5][5]类型指针及其算术运算:\t" << pInArr - 1 << '\t' << pInArr << '\t' << pInArr + 1 << endl;cout << "float(*)[5][5]类型指针及其算术运算:\t" << pFlArr - 1 << '\t' << pFlArr << '\t' << pFlArr + 1 << endl;cout << "long(*)[5][5]类型指针及其算术运算:\t" << pLoArr - 1 << '\t' << pLoArr << '\t' << pLoArr + 1 << endl;cout << "longlong(*)[5][5]类型指针及其算术运算:\t" << pLoloArr - 1 << '\t' << pLoloArr << '\t' << pLoloArr + 1 << endl;cout << "double(*)[5][5]类型指针及其算术运算:\t" << pDouArr - 1 << '\t' << pDouArr << '\t' << pDouArr + 1 << endl;return 0;
}

指向二维数组的指针的声明及定义格式:typename (*pointer) [i][j] = &arrayname; 即指针pointer指向一个含有i个一维数组,并且每个一维数组含有j个的typename类型对象,共i*j个元素。该数组名称为arrayname。

指向二维数组的指针的类型为typename (*)\ [i][j]

pChArr的类型为char(*)[5][5],即 pChArr指向含有5个一维数组,并且每个一维数组都含有5个char类型单一对象(共25个元素),这个单一对象占1个字节,但是该二维数组占1*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动25个字节。

pShtArr的类型为short(*)[5][5],即pShtArr指向含有5个一维数组,并且每个一维数组都含有5个short类型单一对象(共25个元素),这个单一对象占2个字节,但是该二维数组占2*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动50个字节。

pInArr的类型为int(*)[5][5],即pInArr指向含有5个一维数组,并且每个一维数组都含有5个int类型单一对象(共25个元素),这个单一对象占4个字节,但是该二维数组占4*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动100个字节。

pFlArr的类型为float(*)[5][5],即pFlArr指向含有5个一维数组,并且每个一维数组都含有5个float类型单一对象(共25个元素),这个单一对象也占4个字节,但是该二维数组占4*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动100个字节。

pLoArr的类型为long(*)[5][5],即pLoArr指向含有5个一维数组,并且每个一维数组都含有5个long类型单一对象(共25个元素),这个单一对象占4个字节,但是该二维数组占4*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动100个字节。

pLoloArr的类型为long long(*)[5][5],即pLoloArr指向含有5个一维数组,并且每个一维数组都含有5个long long类型单一对象(共25个元素),这个单一对象占8个字节,但是该二维数组占8*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动200个字节。

pDouArr的类型为double(*)[5][5],即pDouArr指向含有5个一维数组,并且每个一维数组都含有5个double类型单一对象(共25个元素),这个单一对象占8个字节,但是该二维数组占8*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动200个字节。

3、指向三维数组的指针和该指针的加减算术运算

#include<iostream>
#include <climits>
using namespace std;
int main(int argc, char *argv[])
{char chr[5][5][5] = {	{ { 'a', 'b', 'c', 'd', 'e' },{ 'f', 'g', 'h', 'i', 'j' },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0short sht[5][5][5] = {	{ { 1, 2, 3, 4, 5 },{ 6, 7, 8, 9, 10 },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0int in[5][5][5] = { { { 1, 2, 3, 4, 5 },{ 6, 7, 8, 9, 10 },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0float fl[5][5][5] = {	{ { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0long lo[5][5][5] = {	{ { 1l, 2l, 3l, 4l, 5l, },{ 6l, 7l, 8l, 8l, 10l },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0long long lolo[5][5][5] = { { { 1ll, 2ll, 3ll, 4ll, 5ll },{ 6ll, 7ll, 8ll, 9ll, 10ll },{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} },{ {},{},{},{},{} }}; //未初始化的元素置0double dou[5][5][5] = { { { 1.0, 2.0, 3.0, 4.0, 5.0 },{ 6.0, 7.0, 8.0, 9.0, 10.0 },{},{},{} },{ {}, {}, {}, {}, {} },{ {}, {}, {}, {}, {} },{ {}, {}, {}, {}, {} },{ {}, {}, {}, {}, {} }}; //未初始化的元素置0char(*pChrArr)[5][5][5] = &chr; //声明并定义char(*)[5][5]类型指针,此指针指向该整个二维数组short(*pShtArr)[5][5][5] = &sht; //声明并定义short(*)[5][5]类型指针,此指针指向该整个二维数组int(*pInArr)[5][5][5] = &in; //声明并定义int(*)[5][5]类型指针,此指针指向该整个二维数组float(*pFlArr)[5][5][5] = &fl; //声明并定义float(*)[5][5]类型指针,此指针指向该整个二维数组long(*pLoArr)[5][5][5] = &lo; //声明并定义long(*)[5][5]类型指针,此指针指向该整个二维数组long long(*pLoloArr)[5][5][5] = &lolo; //声明并定义longlong(*)[5][5]类型指针,此指针指向该整个二维数组double(*pDouArr)[5][5][5] = &dou; //声明并定义double(*)[5][5]类型指针,此指针指向该整个二维数组cout << "char(*)[5][5][5]类型指针及其算术运算:\t\t" << (void*)(pChrArr - 1) << '\t' << (void*)(pChrArr) << '\t' << (void*)(pChrArr + 1) << endl;cout << "short(*)[5][5][5]类型指针及其算术运算:\t\t" << pShtArr - 1 << '\t' << pShtArr << '\t' << pShtArr + 1 << endl;cout << "int(*)[5][5][5]类型指针及其算术运算:\t\t" << pInArr - 1 << '\t' << pInArr << '\t' << pInArr + 1 << endl;cout << "float(*)[5][5][5]类型指针及其算术运算:\t\t" << pFlArr - 1 << '\t' << pFlArr << '\t' << pFlArr + 1 << endl;cout << "long(*)[5][5][5]类型指针及其算术运算:\t\t" << pLoArr - 1 << '\t' << pLoArr << '\t' << pLoArr + 1 << endl;cout << "longlong(*)[5][5][5]类型指针及其算术运算:\t" << pLoloArr - 1 << '\t' << pLoloArr << '\t' << pLoloArr + 1 << endl;cout << "double(*)[5][5][5]类型指针及其算术运算:\t\t" << pDouArr - 1 << '\t' << pDouArr << '\t' << pDouArr + 1 << endl;return 0;
}

在这里插入图片描述

指向三维数组的指针的声明及定义格式:typename (*pointer)\ [i][j][k] = &arrayname; 即指针pointer指向一个含有i个二维数组,并且这i个二维数组每个都含有j个一维数组,并且这j个一维数组中每个都含有k个单一类型的的typename类型对象,共i*j*k个元素。该数组名称为arrayname。

指向三维数组的指针的类型为typename (*)\ [i][j][k]

pChrArr的类型为char(*)[5][5][5],即 pChrArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个char类型单一对象,共125个元素,这个单一对象占1个字节,但是该三维数组占1*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动125个字节。

pShtArr的类型为short(*)[5][5][5],即pShtArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个short类型单一对象,共125个元素,这个单一对象占2个字节,但是该三维数组占2*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动250个字节。

pInArr的类型为int(*)[5][5][5],即pInArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个int类型单一对象,共125个元素,这个单一对象占4个字节,但是该三维数组占4*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动500个字节。

pFlArr的类型为float(*)[5][5][5],即pFlArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个float类型单一对象,共125个元素,这个单一对象占4个字节,但是该三维数组占4*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动500个字节。

pLoArr的类型为long(*)[5][5][5],即pLoArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个long类型单一对象,共125个元素,这个单一对象占4个字节,但是该三维数组占4*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动500个字节。

pLoloArr的类型为long long(*)[5][5][5],即pLoloArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个long long类型单一对象,共125个元素,这个单一对象占8个字节,但是该三维数组占8*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动1000个字节。

pDouArr的类型为double(*)[5][5][5],即pDouArr指向含有5个二维数组,并且每个二维数组都含有5个一维数组,并且每个一维数组中都含有5个double类型单一对象,共125个元素,这个单一对象占8个字节,但是该三维数组占8*5*5*5个字节,所以对它-1或者+1,指针只向前或者向后移动1000个字节。

4、指向n维数组的指针和该指针的加减算术运算

类推地,指向n维数组的指针的声明及定义格式:typename(*pointer) [a(0)][a(1)][a(2)]…[a(n)](共有n个[],每个[]中都要有数字) = &arrayname; 即指针pointer指向一个含有a(0)个n-1维数组,并且这a(0)个n-1维数组中每个都含有a(1)个n-2维数组,并且这a(1)个n-2维数组中每个都含有a(2)个n-3维数组…并且这a(n-1)个一维数组中每个都含有a(n)个单一类型的typename类型对象,共a(0)*a(1)*a(2)…*a(n)个元素。该数组名称为arrayname。

指向n维数组的指针的类型为typename(*)[a(0)][a(1)][a(2)]…[a(n)]

pTypenameArr的类型为typename(*)[a(0)][a(1)][a(2)]…[a(n)],即 pTypenameArr指向一个含有a(0)个n-1维数组,并且这a(0)个n-1维数组中每个都含有a(1)个n-2维数组,并且这a(1)个n-2维数组中每个都含有a(2)个n-3维数组…并且这a(n-1)个一维数组中每个都含有typename类型单一对象,共a(0)*a(1)*a(2)…*a(n)个元素。这个单一对象占sizeof(typename)个字节,但是该n维数组占sizeof(typename)*a(0)*a(1)*a(2)…*a(n)个字节,所以对它-1或者+1,指针只向前或者向后移动sizeof(typename)*a(0)*a(1)*a(2)…*a(n)个字节。

参考
《C语言程序设计》(第3版)(谭浩强,清华大学出版社)
《C++程序设计教程》(第3版)(王珊珊,臧洌,张志航,机械工业出版社)
《C++ Primer Plus》(Six Edition)(Stephen Prata)
《C和指针》(Kenneth A. Reek)
广大的CSDN社友们的文章

相关文章:

C/C++指针与数组(一)

预备知识 1、数据的存储 2、基本内建类型 1&#xff09;类型的大小 C offers a flexible standard with some guaranteed minimum sizes, which it takes from C: A short integer is at least 16 bits wide.An int integer is at least as big as short.A long integer is a…...

Android使用移动智能终端补充设备标识获取OAID

官网http://www.msa-alliance.cn/col.jsp?id120首先到官网注册账号&#xff0c;申请下载相关sdk和授权证书2.把 oaid_sdk_x.x.x.aar 拷贝到项目的 libs 目录&#xff0c;并设置依赖&#xff0c;其中x.x.x 代表版本号3.supplierconfig.json 拷贝到项目 assets 目录下&#xff0…...

极目智能与锐算科技达成战略合作,4D毫米波成像雷达助力智能驾驶落地

近日&#xff0c;智能驾驶方案提供商武汉极目智能技术有限公司&#xff08;以下简称“极目智能”&#xff09;宣布与毫米波成像雷达公司锐算&#xff08;上海&#xff09;科技有限公司&#xff08;以下简称“锐算科技”&#xff09;达成战略合作&#xff0c;双方将合作开发基于…...

OpenCV基础(一)

1.认识图像&#xff08;彩色图中每一个像素点都包含三个颜色通道RGB&#xff0c;数值范围为0~255&#xff0c;0代表黑色&#xff0c;255代表白色&#xff09; import cv2 #opencv 读取的格式为BGRimg cv2.imread(cat.png) #读取图像 cv2.imshow(cat, img) #显示图像img&#x…...

pinia 的使用(笔记)

文章目录1. Pinia 与 Vuex 的区别2. pinia 安装与搭建3. pinia 的使用3.1 基本使用3.2 订阅状态3.3 订阅 actions1. Pinia 与 Vuex 的区别 Pinia 是 Vue 的状态管理库&#xff0c;相当于 Vuex 取消了 mutations&#xff0c;取消了 Module 模块化命名空间现在的 pinia 采用的是…...

DolphinDB 机器学习在物联网行业的应用:实时数据异常率预警

数据异常率预警在工业安全生产中是一项重要工作&#xff0c;对于监控生产过程的稳定性&#xff0c;保障生产数据的有效性&#xff0c;维护生产设备的可靠性具有重要意义。随着大数据技术在生产领域的深入应用&#xff0c;基于机器学习的智能预警已经成为各大生产企业进行生产数…...

新建vite+vue3+ts项目,以及解决过程中遇到的问题

目录 一、新建vitevue3ts项目 二、解决过程中遇到的问题 解决报错&#xff1a;Module ‘“xx.vue“‘ has no default export. 解决报错&#xff1a;Error [ERR_MODULE_NOT_FOUND]: Cannot find package ‘uuid’ imported from xxx的解决 解决报错&#xff1a;[plugin:vi…...

pyppeteer中文文档

目录 1.命令 ​​​​​​2.环境变量 3.Launcher&#xff08;启动器&#xff09; 4.浏览器类 5.浏览器上下文类 6.页面类 7.Worker 类 8.键盘类 9.鼠标类 10.Tracing类 11.对话框类 12.控制台消息类 13.Frame 类 14.执行上下文类 15.JSHandle 类 16.元素句柄类…...

(二十四)操作系统-吸烟者问题

文章目录一、问题描述二、问题分析1&#xff0e;关系分析2&#xff0e;整理思路3&#xff0e;设置信号量三、实现四、总结一、问题描述 假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它&#xff0c;但是要卷起并抽掉一支烟&#xff0c;抽烟者需要…...

ReentranLock(可重入锁)

一、ReentranLock ReentranLock属于JUC并发工具包下的类&#xff0c;相当于 synchronized具备如下特点 ● 可中断 ● 可以设置超时时间 ● 可以设置为公平锁&#xff08;防止线程出现饥饿的情况&#xff09; ● 支持多个条件变量 与 synchronized一样&#xff0c;都支持可重…...

Kafka 入门 (一)

Kafka 入门&#xff08;一&#xff09; Apache Kafka起源于LinkedIn&#xff0c;后来于2011年成为开源Apache项目&#xff0c;然后于2012年成为First-class Apache项目。Kafka是用Scala和Java编写的。 Apache Kafka是基于发布订阅的容错消息系统。 它是快速&#xff0c;可扩展…...

linux内核开发入门二(内核KO模块介绍、开发流程以及注意事项)

linux内核开发入门二&#xff08;内核KO模块介绍、开发流程以及注意事项&#xff09; 一、什么是内核模块 内核模块&#xff1a;ko模块&#xff08;Kernel Object Module&#xff09;是Linux内核中的可加载模块&#xff0c;它可以动态地向内核添加功能。在运行时&#xff0c;可…...

设计模式(十七)----行为型模式之模板方法模式

行为型模式用于描述程序在运行时复杂的流程控制&#xff0c;即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务&#xff0c;它涉及算法与对象间职责的分配。 行为型模式分为类行为模式和对象行为模式&#xff0c;前者采用继承机制来在类间分派行为&…...

【嵌入式Linux内核驱动】01_内核模块

内核模块 宏内核&微内核 微内核就是内核中的一部分功能放到应用层 内核小&#xff0c;精简&#xff0c;可扩展性好&#xff0c;安全性好 相互之间通信损耗多 内核模块 Linux是宏内核操作系统的典型代表&#xff0c;所有内核功能都整体编译到一起&#xff0c;优点是效…...

Spring——数据源对象管理和Spring加载properties文件

前面一直都是在管理自己内部创建的对象&#xff0c;这个是管理外部的对象。 这里先使用阿里巴巴的druid来演示。需要在pom.xml中添加如下的依赖 <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1…...

Zeek安装、使用与压力测试

Zeek安装与压力测试Zeek安装、简单使用与压力测试环境Zeek安装zeek简单运行安装PF_RING修改Zeek配置文件&#xff0c;使用PF_RING&#xff0c;实现集群流量压力测试查看zeek日志Zeek安装、简单使用与压力测试 科研需要&#xff0c;涉及到Zeek的安装、使用和重放流量压力测试评…...

【javaEE初阶】第三节.多线程 (进阶篇 ) 死锁

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、"死锁"出现的典型场景二、产生 "死锁" 的必要条件 三、解决 "死锁" 问题的办法 总结前言 今天对于多线程进阶的学习&#…...

基于密集连接的轻量级卷积神经网络,用于使用边云架构的露天煤矿服务识别

遥感是快速检测非法采矿行为的重要技术工具。由于露天煤矿的复杂性&#xff0c;目前关于露天煤矿自动开采的研究较少。基于卷积神经网络和Dense Block&#xff0c;我们提出了一种用于从Sentinel-2遥感图像中提取露天煤矿区域的轻量级密集连接网络-AD-Net&#xff0c;并构建了三…...

无刷高速风筒方案介绍--【PCBA方案】

疫情三年过去&#xff0c;春节后&#xff0c;一个新的开始&#xff0c;大家满怀希望畅谈今年好气象。 三年来一波一波的封城、隔离、核酸&#xff0c;经济压抑到了无以复加的地步&#xff0c;也导致了诸多社会问题的出现。消费力被磨平&#xff0c;人们小心翼翼的生活。 常跟…...

花括号展开II[栈模拟dfs]

栈模拟dfs前言一、花括号展开II二、栈模拟dfs总结参考资料前言 递归调用&#xff0c;代码非常的简洁。但是可以通过显式栈来模拟栈中的内容&#xff0c;锻炼自己的代码能力&#xff0c;清楚知道栈帧中需要的内容。 一、花括号展开II 二、栈模拟dfs 每碰到一个左括号&#xf…...

【网络】每天掌握一个Linux命令 - iftop

在Linux系统中&#xff0c;iftop是网络管理的得力助手&#xff0c;能实时监控网络流量、连接情况等&#xff0c;帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...