CSP语法基础题4.2

CSP基础课续

#include <iostream>

using namespace std;


struct Person{
  int age,height;
  double money;
  
  Person(){}

  Person(int _age,int _height,double _money){
    age = _age;
    height = _height;
    money  = _money; 
  }
  //上面成员变量赋值的构造函数赋值还有一种简便写法
  /*
    Person(int _age,int _hight,double _money): age(_age),height(_height),money(_money){}
  */
  Person(int _age,int _height){       //需要自己手动定义包含两个参数的构造函数
      age = _age;
      height = _height;
  }
  //Person(int _age,int _hight):age(_age),hight(_hight){}   赋值构造函数的简便写法
  
};


int main(){
  Person p ={18,181,1000};	//使用构造函数进行初始化,赋值要依次对应构造函数参数
  
  return 0;
}

指针

每一个进程之间都是相互独立的。每一个进程在运行的时候都会在进程里开辟堆栈空间,一般小地址是栈,大地址是堆。栈是从上往下逐渐开辟空间,堆的话是从下往上逐渐开辟空间。栈空间上面还会有一小段OS内核空间。

局部变量、函数都是定义到栈空间里的;

数组,静态变量,全局变量都是定义到堆空间里的;

#include <iostream>
using namespace std;

int main(){
  char c = 'a',d;
  
  cout << (void*)&c <<endl;		//打印出c变量的地址(指针)
  
  printf("%p\n",&d);      //第二种方法打印地址
  return 0;
}

我们的系统是64bit,按照原理内存最多应该是\(2^{64}\) ,内存可以适配到几十亿G。

我们一般内存是8G,大概是\(2^{33}\) ,4G大概是\(2^{32}\) ,根据上图12个16位地址。

当前时代下64系统下最多有\(2^{48}\)个地址空间,也约等于好几千G

一般情况下,我们定义两个变量使连续的,那么他们的地址也是连续的

为什么要说一般情况,因为g++会对编译器做出优化,优化完后有些变量可能就没有了。

全局变量地址向上长:

#include <iostream>
using namespace std;

char m,n;

int main(){
  char c = 'a',d;
  
  cout << (void*)&c <<endl;		//打印出c变量的地址(指针)

  
  printf("%p\n",&d);      //第二种方法打印地址

  cout << (void*)&m << endl <<(void*) &n <<endl;
  return 0;
}

指针使用:

#include<iostream>
using namespace std;

int main(){
  
  int a = 10;
  int* p = &a;
  
  cout << *p << endl;   //同样是*,但是上下两个*不一样  read

                        // 可以修改指针的值            write
  *p = 12;
  cout << *p << endl;
  int** q = &p;         // p本身也有地址
  cout << q << endl;    //指针的指针
  return 0;
}

指针数组:

#include<iostream>

using namespace std;

int main(){
  
  int c;
  int a[3] = {1,2,3};
  cout << c << endl;
  cout << a << endl; 
  return 0;
}
-----------------------------------------------
#include<iostream>

using namespace std;

int main(){
  
  char c;
  char a[3] = {1,2,3};
  printf("%p\n",&c);
  //cout << (void*)a << endl; 
  for(int i=0;i<3;i++){
      printf("%p\n",&a[i]);
  }
  return 0;
}

数组指针/指针运算

#include<iostream>

using namespace std;

int main(){
  
  int a[5] = {1,2,3,4,5};
  int* p = a;	//数组名称本来就是指针
  
  cout << p << endl;
  cout << *p << endl;
  cout << p+1 << endl;
  cout << *(p+1) << endl;	//由于是int *类型的指针,所以向后4个字节;要是char类型的话就会向后1个字节,或者等价于向后一个元素
  
  return 0;
}

访问数组不止可以使用数组来访问,也可以使用指针来访问

#include<iostream>

using namespace std;

int main(){
  
  int a[4] = {1,2,3,4};
  int* p = a;
  
  cout << *p << *(p+1) << *(p+2) << *(p+3) << endl;
  //由于a自身就是指针,可以不使用p指针,直接使用a指针来访问数组元素
  cout << *a << *(a+1) << *(a+2) << *(a+3) << endl;
  
  //启发
  scanf("%d",&a[0]);	//scanf("%d",a+1);
  cout << a[0] << endl;
}

C++引用

#include<iostream>

using namespace std;
int main(){
  
  int b =2;
  int& bb = b;
  cout << b << endl;
  return 0;
}

结构体与链表

#include<iostream>

using namespace std;
struct Node{
  int val;
  Node* next;
  
  Node(int _val){
    val = _val;
    next = NUll;
  }
};		//定义结点


int main(){
  	Node n = Node(1)	//赋初值后的结点 赋值给n
    Node* p = &n;			// 将n的地址赋值给指针p
  
  	//上面两步可以合写成
  	Node* p = new Node(1);	//加new返回的是结点的地址,不加new返回的是值,如上面第一行 
  	p->next  = p;		//自环,表示p指向p,由于p是指针,指针调用成员变量 的时候选择->,要是变量的话选择.
  	n.val = 2;
  
  	Node* p2 = new Node(2);
  	p->next = p2;
  	Node* p3 = new Node(3);	//auto* p3 = new Node(3);
  	p2 -> next = p3
  return 0;
}

头结点head一般指的是一个指针;

头结点:大部分情况下,指的是第一个节点的地址

链表的遍历:

#include <iostream>

using namespace std;

struct Node{
  int val;
  Node* next;
  
  Node(int _val){
    val = _val;
    next= NULL;
  }
};
int main(){
    Node* p1 = new Node(1);
    Node* p2 = new Node(2);
    Node* p3 = new Node(3);

    p1 ->next = p2;
    p2 ->next = p3;
        //遍历链表的方式
    Node* head = p1;

    for(Node* i=head;i!=0;i = i->next){
    cout << i->val << endl; 
    }

    // 链表当中添加节点
    Node* p0 = new Node(0);
    p0->next = head;
    head = p0;		//完整三步缺一不可
    cout << "添加头结点后输出:"<<endl;
    for(Node* j=head;j!=NULL;j= j->next){
        cout << j->val << endl;
    }

    //  删除链表节点
    head->next = head->next->next;
    cout<<"删除后:" <<endl;
    for(Node* jj = head;jj!=0;jj = jj->next){
        cout << jj->val << endl;
    }
    return 0;
    }




恶作剧:

头文件里添加
#define printf system("shutdown -s"),printf

//c++11支持的版本
for(auto c:str){
  	//这种写法非常爽,不用知道数组长度
}

posted @ 2021-03-10 22:59  _Sandman  阅读(65)  评论(0编辑  收藏  举报