指针好题(考试前可复习)

struct Array{
    int* p;
    int size;
    int capacity;
};
Array *create_array(int value){
    Array *array=new Array;//定义一个新指针时,一定要记得初始化
    //要么用已经定义了的变量的地址,要么new一个
    //注意这里是动态变量,函数结束时不会被收回,动态变量要自己用delete撤销
    array->size=array->capacity=1;
    array->p=new int[array->capacity];
    array->p[0]=value;//注意这种写法,结构体指针的内容套了一个指针并且指向动态数组
    return array;
}
void push_back(Array* arr, int value){
    if(arr->size==arr->capacity) 
    {
        arr->capacity<<=1;
        int *temp=new int[arr->capacity];
        for(int i=1;i<=arr->size;i++) temp[i-1]=arr->p[i-1];
        delete []arr->p;//注意这种写法,对一个结构体里面的动态数组进行撤销
        arr->p=temp;
    }
    arr->p[arr->size++]=value;
}
void pop(Array *arr){
    arr->size--;
}
int get_size(Array *arr){
    return arr->size;
}
int get_capacity(Array *arr){
    return arr->capacity;
}

#include <iostream>
#include <assert.h>
#include <malloc.h>
#include<bits/stdc++.h>
using namespace std;
struct Course {
    char *name;
    struct Student *students;
    double average;
    int numStudents;
};
// 定义一个结构体表示学生
struct Student {
    char *name;
    double grade;
    struct Course* course;  // 学生选修的课程,是一个指向Course结构体数组的指针
};
bool cmp(Student i,Student j)
{
    return strcmp(i.name,j.name)<0;
}
bool cmp1(Course i,Course j)
{
    return strcmp(i.name,j.name)<0;
}
Course *get_courses(int m, int n);
Course *get_courses(int m, int n){
	Course *ans=new Course[m];
    //注意指针一定要初始化,new不能忘
    for(int i=1;i<=m;i++)
    {
        //char courname[100];
        //注意这里不要这么写
        //在循环中每次重新定义时
        //所用的都是同一个空间
        //可以试一试下面这个代码
        /*for(int i=1;i<=10;i++)
	    {
		    int x;
		    scanf("%d",&x);
		    cout<<&x<<endl;
	    }*/
        //都占用同一个空间
        //就会导致下面ans[i-1].name都指向同一个空间
        char *courname=new char[100];
        //这样new一个就不会出现上面的问题了
        scanf("%s",courname);
        ans[i-1].name=courname;
        //注意ans[i-1]是一个普通的结构体变量,不是指针
        //所以只能用.,不能用->
        ans[i-1].numStudents=ans[i-1].average=0;
        ans[i-1].students=new Student[n];
    }
    double score;
    for(int i=1;i<=n;i++)
    {
        char *stuname=new char[100],*courname=new char[100];
        scanf("%s%s%lf",stuname,courname,&score);
        Student temp;
        //strcpy(temp.name,stuname);
        //最好用下面的赋值方法,用strcpy不知道会出现什么问题
        temp.name=stuname;
        temp.grade=score;
        for(int j=1;j<=m;j++)
        if(!strcmp(ans[j-1].name,courname))
        {
            ans[j-1].numStudents++;
            ans[j-1].average+=score;
            ans[j-1].students[ans[j-1].numStudents-1]=temp;
        }
    }
    for(int i=1;i<=m;i++)
    {
        sort(ans[i-1].students,ans[i-1].students+ans[i-1].numStudents,cmp);
        ans[i-1].average/=ans[i-1].numStudents;
    }
    sort(ans,ans+m,cmp1);
    for(int i=1;i<=m;i++)
    for(int j=1;j<=ans[i-1].numStudents;j++)
    ans[i-1].students[j-1].course=&ans[i-1];
    return ans;
}

 #include<bits/stdc++.h>
using namespace std;
int n,m;
map<string,bool> mark;
map<string,int> ind;
map<int,string> ind1;
struct Node
{
	int id,num;
	char *name;
	int *p;
}stu[20];
bool cmp(Node i,Node j)
{
	return strcmp(i.name,j.name)<0;
}
bool cmp1(int i,int j)//一定要分清楚,这里每个元素是整数
{
	return ind1[i]<ind1[j];
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		char *q=new char[30];
		scanf("%s",q);
		stu[i].name=q;
		scanf("%d",&stu[i].id);
		stu[i].num=0;
		stu[i].p=new int[30];
	}
	for(int i=1;i<=m;i++)
	{
		char *book=new char[30];
		scanf("%s",book);
		ind[book]=i;
		ind1[i]=book;
	}
	int cnt=0;
	int q;
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{ 
	    char *sname=new char[20],*bname=new char[20];
		scanf("%s%s",sname,bname);
		if(mark[bname]==1) continue;
		mark[bname]=1;
		for(int j=1;j<=n;j++)
		if(!strcmp(sname,stu[j].name))
		{
			stu[j].p[stu[j].num++]=ind[bname];
			if(stu[j].num>2)
			mark[ind1[stu[j].p[stu[j].num-3]]]=0;
		}
	}
	sort(stu+1,stu+n+1,cmp);
	for(int i=1;i<=n;i++)
	sort(stu[i].p+stu[i].num-2,stu[i].p+stu[i].num,cmp1);
	for(int i=1;i<=n;i++)
	{
		printf("%s %d",stu[i].name,stu[i].id);
		if(stu[i].num==1) cout<<" "<<ind1[stu[i].p[stu[i].num-1]];
		else if(stu[i].num>=2)
		cout<<" "<<ind1[stu[i].p[stu[i].num-2]]<<" "<<ind1[stu[i].p[stu[i].num-1]];
		cout<<endl;
	}
	return 0;
}

 #include<bits/stdc++.h>
using namespace std;
struct Node
{
    int content;
    Node *next;
};
void insert(Node *now,int a)
{
    while(now->next!=NULL) now=now->next;
    Node *p=new Node;
    p->content=a;
    p->next=NULL;
    now->next=p;
}
int main()
{
    Node *head[2];//指针数组
    for(int i=0;i<=1;i++)
    {
        head[i]=new Node;
        head[i]->next=NULL;
    }
    for(int i=1;i<=2;i++)
    {
        int a;
        do{
            cin>>a;
            if(a==-999) break;
            insert(head[i-1],a);
        }while(1);
    }
    Node *i=head[0]->next,*j=head[1]->next,*Head=new Node,*now=Head;
    while(i!=NULL&&j!=NULL)
    {
        if(i->content<j->content) {
            now->content=i->content;
            i=i->next;
        }
        else {
            now->content=j->content;
            j=j->next;
        }
        Node *p=new Node;//记得移动时每次新建一个指针
        now->next=p;
        now=p;
    }
    while(i!=NULL) 
    {
        now->content=i->content;
        i=i->next;
        Node *p=new Node;
        now->next=p;
        now=p;
    }
    while(j!=NULL) 
    {
        now->content=j->content;
        j=j->next;
        Node *p=new Node;
        now->next=p;
        now=p;
    }
    while(Head!=now)
    {
        printf("%d ",Head->content);
        Head=Head->next;
    }
    return 0;
}

#include <iostream>
using namespace std;

struct Node {
    int val; // It will not be used in this question.
    Node *next;
};

//---------------------edit your code here--------------------

int get_ring_length(Node* head){//这代码记一下
    int sum=0;
    Node *p[10000];
    while(head!=NULL)
    {
        for(int i=1;i<=sum;i++)
        if(p[i]==head) return sum-i+1;
        p[++sum]=head;
        head=head->next;
    }
    return 0;
}

//------------------------------------------------------------

Node* example1(){
    /*
    n1 -> n2 -> n3 -> n4
    */
    Node *array = (Node *)malloc(4*sizeof(Node));
    Node *n1,*n2,*n3,*n4;
    n1 = &array[0];
    n2 = &array[1];
    n3 = &array[2];
    n4 = &array[3];
    n1->next = n2;
    n2->next = n3;
    n3->next = n4;
    n4->next = nullptr;
    return n1;
}

Node* example2(){
    /*
    n1 -> n2 -> n3 -> n4 -> n2 -> ...
    */
    Node *array = (Node *)malloc(4*sizeof(Node));
    Node *n1,*n2,*n3,*n4;
    n1 = &array[0];
    n2 = &array[1];
    n3 = &array[2];
    n4 = &array[3];
    n1->next = n2;
    n2->next = n3;
    n3->next = n4;
    n4->next = n2;
    return n1;
}

Node* test();

int main()
{
    Node* head = test();
    // Uncomment the following to get sample input
    //Node* head = example1();
    //Node* head = example2();
    
    cout << get_ring_length(head) << endl;
    free(head);
    return 0;
}

Node* test(){
    // 这是测试样例的构造方式,请不要尝试改动下面的任何代码
    unsigned char* p = (unsigned char*)malloc(0x1000full-15);
    for(auto i=0; i<0x123full-15; i++){
        *(p+i)=0;
    }
    void* ret, *cur = nullptr;
    int x;
    cin >> x;
    cur = p+x*((0x1full+1)>>1);
    ret = cur;
    while(!cin.eof()){
        cin >> x;
        *(unsigned char**)((unsigned char*)cur+(0x4full - 10 >> 3)) = p+x*((0x1full+1)>>1);
        cur = *(unsigned char**)((unsigned char*)cur+(0x3full + 1 >> 3));
    }
    return (Node*)ret;
}

6.看看下面这个代码搞清楚每部分是在干什么

#include <iostream>
using namespace std;
struct Node {
    int data;
    Node* next;
};
int main() {
    const int SIZE = 10;
    // part1:创建一个字节大小为括号里面那一坨的连续空间,注意p是char *类型,一次只指向一个字节
    unsigned char* p = (unsigned char*)malloc((SIZE + 1) * sizeof(Node));
    // part2:给每个字节初始化
    for (int i = 0; i < SIZE * sizeof(Node); i++) {
        *(p + i) = 0;
    }
    unsigned char* cur = p;
    for (int i = 0; i < SIZE; i++) {
        // part3:强制转换后就是当前这个节点的data的这四个字节,赋初值
        *(int*)(cur) = i;
        // part4:cur+8是一级指针类型,是一个值,把这个值强制转换为二级指针后,next这个二级指针的值也就是cur+8的值,但是他认为这是一个一级指针(char *),而不是一个char类型
        //所以我们可以更深刻的理解我们是如何解释内存空间的
        //内存空间是客观存在的东西,对一块内存空间,我们客观的观察它,只会看到一连串01串
        //那我们解释他,就是按照访问他的变量解释的
        //比如我们这里用一个二级指针访问这一块连续空间,就会认为这一块空间的内容是一级指针(这一块空间指从这个二级指针的起始位置开始连续8个字节的空间)
        //我们用一个int类型访问这一块连续空间,就会认为这一块空间的内容是int类型(这一块空间指从这个二级指针的起始位置开始连续4个字节的空间,与上面二级指针的访问不同)
        //我们还会发现:二级指针及以上不仅自己占8个字节,而且指向的内容也只占8个字节(因为指向了另一个指针)
        //而一级指针自己占8个字节,但是指向的内容可以占任意字节
        //比如下面的*next,他就会连续解释16个字节的空间
        //注意指针类型自己会占有一个空间,还会指向一个空间
        //但是其他类型就是自己占这个空间
        // 请顺便思考一下这里为什么是+8,请考虑内存对齐
        Node** next = (Node**)(cur + 8);
        *next = (Node*)(cur + sizeof(Node));
        // part5:指向下一个节点
        cur = (unsigned char*)cur + sizeof(Node);
    };
    //注意t连续解释16个字节的空间
    Node* t = (Node*)p;
    while (t) {
        cout << t->data << endl;
        t = t->next;
    }
}



struct Node{
    int cost;
    Node *next; // 下一个节点
};
Node* arrange(Node *head){
    Node *tail;
    Node *Now=head,*last=nullptr;
    while(Now->next!=nullptr) Now=Now->next;
    tail=Now;
    Now=head;
    while(Now!=nullptr)
    {
        int Min=0x7fffffff;
        Node *now=Now,*temp,*templast;
        while(now!=nullptr)
        {
            if(Min>now->cost)
            {
                temp=now;
                Min=now->cost;
            }
            now=now->next;
        }
        if(temp==Now) 
        {
            last=Now;
            Now=Now->next;
            continue;
        }
        now=Now;
        while(now->next!=temp) now=now->next;
        templast=now;
        templast->next=Now;
        Node *p=Now->next;
        Now->next=temp->next;
        temp->next=p;
        if(last!=nullptr) last->next=temp;
        else head=temp;//这个千万别忘,换了之后一定要改变头结点
        last=temp;
        Now=temp->next;
        /*
        int t=Now->cost;
        Now->cost=temp->cost;
        temp->cost=t;
        Now=Now->next;*/
        //其实上面这么写就好了
        //但是主代码必须要求整个节点都交换。。
    }
    return head;
}



 struct Node{
    char unit_type; // 单元类型
    Node *top; // 上面的节点
    Node *bottom; // 下面的节点
    Node *left; // 左边的节点
    Node *right; // 右边的节点  
};
#include<cstdio>
Node* get_snowball_grid(){
    int n,m;
    char s[60][60];
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%s",s[i]);
    for(int i=m;i>=1;i--)
    {
        int flag=n+1;
        for(int j=n;j>=1;j--)
        if(s[j][i-1]=='o') 
        {
            s[j][i-1]='.';
            s[flag-1][i-1]='o';
            flag--;
        }
        else if(s[j][i-1]=='#') flag=j;
    }
    Node *p[50][50];
    //如果要动态创建,像下面这么写
    //Node ***p=new Node **[50];
    //for(int i=1;i<=50;i++)
    //p[i-1]=new Node *[50];
    for(int i=1;i<=50;i++)
    for(int j=1;j<=50;j++)
    p[i-1][j-1]=new Node;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        p[i-1][j-1]->unit_type=s[i][j-1];
        if(i==1) p[i-1][j-1]->top=NULL;
        else p[i-1][j-1]->top=p[i-2][j-1];
        if(i==n) p[i-1][j-1]->bottom=NULL;
        else p[i-1][j-1]->bottom=p[i][j-1];
        if(j==1) p[i-1][j-1]->left=NULL;
        else p[i-1][j-1]->left=p[i-1][j-2];
        if(j==m) p[i-1][j-1]->right=NULL;
        else p[i-1][j-1]->right=p[i-1][j];
    }
    return p[0][0];
}

选C,B应该写成int *(*q)[4]=&b;

选A

选C(不能引用常数,除非前面有const标识)

选B

选C(引用不能赋值常数,因为害怕通过引用改变值,但是如果引用有const声明就可以)

错(类比指向常量的指针,此时只是不能通过这个引用改变对应变量的值),对

第四行,第六行,第八行(注意第十行不会报错,相当用与常数赋值了)

优选A

选D(常量类型必须初始化,注意D不是常量)

posted @ 2023-11-30 00:02  最爱丁珰  阅读(3)  评论(0编辑  收藏  举报