一、
const int* f(); //函数 表示该返回值所指向的值不能被修改
int* res=f(); // 错误
const int* res=f(); //正确
const int& f() {return 8;}
int& f(int a) { return a; }
int main() {
f() = 89;//错误 函数调用表达式不能作为左值。
f(3) = 90;//正确
return 0;
}
int a = 3, b = 4;
int* p = &a;
p = &b;
*p = 20;
const int* p1 = &a; //修饰指针所指向的值,此指针可以修改,但是此指针指向的值不能被修改
p1 = &b;
//*p1 = 20;
int const* p2 = &a; // 同上 (可以认为此二者的const均修饰 *)
p2 = &a;
//*p2 = 20;
int* const p3 = &a; //仅修饰指针,指针不能修改,但是指针指向的值可以被修改
//p3 = &b;
*p3 = 20;
const int* const p4 = &a; // 均修饰,指针不能修改,且其指向的值也不能被修改
//p4 = &b;
//*p4 = 20;
const int len = 9;
int array[len]; // cpp 允许,而 c 不允许
printf("%d\n");//打印出内存中的随机值
int a=90;
int b = printf("%d\n", a);
printf("%d\n", b); // b为3 它为printf打印出字符的个数! 负值表示出错。
char a[20];
printf("%d\n", a[0]); // 正确,打印出随机值
int b;
printf("%d\n", b); // 运行时错误,b 未初始化
//和普通变量一样,应该在声明时来初始化 const 数据,因为一旦声明为const,便不能再给它赋值。
const int m[4]={1,2,3,4};
int n[4]={1}; // n 中值为: 1 0 0 0
// 由于数组一旦有部分元素被初始化,其余元素就会被初始化为 0,所以:对一个数组初始化全为 0 的方式如下
int nn[4]={0};
int mm[]={3,4};// 数组大小为2;
int len=sizeof(mm)/sizeof(int);// 或者:sizeof(mm)/sizeof(mm[0]);
#define N 5 // c
constexpr auto N1 = 5; // cpp 常量表达式
int main() {
int i[N]; // c 初始化数组大小
int ii[3 * 7]; // c 初始化数组大小
const int j = 8;
int k[j];// const 只能在cpp中 初始化数组大小
return 0;
}
int sq[2][3] = { 5,6,7,8 }; //不带小括号的从第一行顺序初始化
/* 5 6 7
* 8 0 0
*/
int s[2][3] = { {5,6},{7,8} };
/* 5 6 0
* 7 8 0
*/
int a[7] = { 5,6,7,8 };
int* p = &a[0];
int* p1 = a;
printf("%d\n", *p);
printf("%d\n", *(p+1)); //指针加1,指针的值递增它所指向类型的大小(以字节为单位)。
printf("%d\n", p[1]);
p + 2 == &p[2]; // 相同的地址
*(p + 2) == p[2]; // 相同的值
*(p + 2); // p 第3个元素的值
*p + 2; // p 第1个元素的值加2 * 的运算符优先级比算术运算符要高。
int zippo[3][2] = { 0,1,2,3,4,5 };
printf("%d\n", zippo[2][1]);
printf("%d\n", *(*(zippo + 2) + 1));
// *(zippo+2) zippo[2][0] 的地址
// *(zippo+2)+1 zippo[2][1] 的地址
//*(*(zippo+2)+1) zippo[2][1] 的值
int(* p)[2] = zippo; // 指向二维数组的指针 采用的括号的原因是因为 [] 比 * 的优先级高。
printf("%d\n", **p); // 等同于 zippo[0][0]
printf("%d\n", *(*(p + 2)+1)); // 等同于 zippo[2][1]
//int* p[2]; //此时 p 是一个存放 int* 的一维数组,数组长度为 2.
// int array[8][4]; //将该数组作为函数参数
int fun1(int(*p)[4]);
int fun2(int p[][4]);
int fun1(int p[][]);// 错误的传参
int fun3(int* p);
int fun4(int p[]);
//一般而言,声明一个指向N维数组的指针时,只能省略最左边方括号中的值:
//第1对方括号只用于表明这是一个指针,而其他的方括号则用于描述指针所指向数据对象的类型。
//下面的 ar 表示其指向一个12×20×30的int数组。
int fun5(int ar[][12][20][30]);
int fun6(int(*ar)[12][20][30]);
//一、未初始化的指针
int* pp;
printf("%p\n", pp); //报错 pp未初始化
printf("%d\n", *pp); // 报错 pp未初始化
*pp=9; //报错 pp未初始化
/*
pp未被初始化,其值是一个随机值,所以不知道 9 将储存在何处。这可能不会出什么错,也可能会擦写数据或代码,或者导致程序崩溃。
创建一个指针时,系统只分配了储存指针本身的内存,并未分配储存数据的内存。
要么设置它的值为NULL,要么让它指向已有变量/数组的地址,要么让它指向 malloc/new 分配的内存。
*/
//二、指针被释放之后,仅仅释放掉其指向的内存,指针本身并未被释放掉。
int* uu = new int;
delete uu;
uu = NULL; //建议 delete/free 之后,令指针值为 NULL
int* fun() {
int a = 9;
return &a;
}
int main() {
//三、指针操作超出了变量的作用范围,
int* res = fun(); // 此时 a 所在的内存已经被释放掉了。
return 0;
}
// 通用指针 void* : 可指向任何指针,但解引用时需要先进行转换。
int a = 3;
int* p;
void* v = &a;
printf("%d\n", *v);// 报错,不知道 v 指向内容的长度。
p = (int*)v;
printf("%d\n", *p);
double dd = 9.87;
int iii = dd;//错误
int i=(int)dd; //正确
// 隐式类型转换
double dd = 9.87;
int iii = dd;
// 指针只能显式类型转换
double* a = new double(8.98);
int* b = a; //报错,无法转换
int* b = (int*)a;
delete a;
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。