指针的三种访问成员的方式
参照自P304,谭浩强《C程序设计》第四版
#include<stdio.h>
int main()
{
struct stu//自己定义的stu类型
{
int num1 = 1;
int num2 = 2;
int num3 = 3;
}member;
stu *p = &member;
//member 即 成员名,
printf("%d\n",member.num1);
printf("%d\n",(*p).num2);
printf("%d\n",p->num3);
return 0;
}
//参照自P304,谭浩强《C程序设计》第四版
C++中“->”和“.”在使用中有什么区别呢(出自https://zhidao.baidu.com/question/415177703.html)
->是指针指向其成员的运算符 .是结构体的成员运算符。
最大的区别是
【->】前面放的是【指针】,而【.】前面跟的是【结构体变量】。
struct A
{
int a;
int b;
};
A *point = malloc(sizeof(struct A));
point->a = 1;//指针
A object;
object.a = 1;//结构体变量
动态内存分配
参照自P286,谭浩强《C程序设计》第四版
==============(除了sizeof函数,都要用上<stdlib.h>库)============
malloc和free函数简介
malloc函数
原型:void *malloc(unsigned int size);
简介:该函数在内存的动态存储区中分配一块长度为size字节的连续区域;如果分配成功,则函数的返回值为该区域的首地址;如果分配失败,则返回空指针值NULL。
malloc(100);//开辟100字节的临时分配域,返回值为其第一个字节的地址
free函数
原型:void free(void *p);
简介:该函数将最近一次用malloc或calloc开辟的动态内存空间释放掉(p是最近一次调用malloc或calloc函数时得到的返回值),free函数无返回值。
free(p);//释放p所指向的已分配动态空间
举个例子,用它就可以动态地生成随意大小的数组了
int nLen=50;
char *szBuf ="hello";
//动态
unsigned char *new_buf=(unsigned char *)malloc(nLen);
memcpy(new_buf , szBuf,nLen) ;
//静态对比
unsigned char* x=new unsigned char[nLen] ;
memcpy(x, szBuf ,nLen);
calloc和realloc函数
calloc函数
原型:void *calloc(unsigned n,unsigned size);
简介:"数组似的"开辟空间
p=calloc(50,4);//开辟50*4个字节的临时分配域,把起始地址赋给指针变量p
realloc函数
原型: void *realloc(void *p, unsigned int size);
简介:“改变”已分配的“空间大小”
realloc(p,50);//将p所指向的已分配的动态存储空间改为50字节
注:unsigned int 无符号整数类型,(说白了就是不让你取负数= =)
sizeof函数
原型:sizeof有三种语法形式,如下:
1 2 3 |
|
简介:sizeof是计算对象所占的字节个数,通常用来查看变量或结构体等所占的字节个数。
比如:
1 2 3 4 5 6 7 8 9 |
|
又如:
#include<stdio.h>
void main()
{
int a=sizeof(int);
printf("%d", a);
}
输出是4,因为 int 类型占4个字节。
一般用法:
#include<stdio.h>
#include<stdlib.h>
void main()
{
float z = 1;
int * b= (int*)malloc(sizeof(z));//b初始化时给它分配内存【整形指针型,z的大小(此处为float大小)的内存】
}
野指针
野指针指向一个已删除的对象或未申请访问受限内存区域的指针。
比如定义一个指针后没给他赋值或者malloc一个空间,就使用之。
#include<stdio.h>
#include<stdlib.h>
void main()
{
int z = 1;
int x = 2;
//int * a ;
//printf("%d", a);//整形指针a什么都没有就使用,出错
//int * b ;//b初始化时没给它内存,出错
//*b = z;
//printf("%d", *b);
int * b= (int*)malloc(sizeof(z));//b初始化时给它分配内存【整形指针型,z的大小的内存】
*b = z;
printf("%d\n", *b);//成功
int * c = &z;//最常用方法,分配内存;直接指向了z
printf("%d\n", *c);
c = &x;
printf("%d\n", *c);
printf("%d\n", z);
}
例:建立动态链表
参考 书上P313
c的<malloc、free>版
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct Student)//这句话说以后的LEN都是Student类型 的长度
struct Student//自己定义的stu类型
{
int num;
struct Student *next;
};
int n;
struct Student *creat()//此函数返回值为指向链表头的指针
{
struct Student *head;
struct Student *p1,*p2;
n = 0;
p1 = p2 = (struct Student *)malloc(LEN);//(……)是强制转换类型运算符,就把malloc开辟出LEN长的地方变为struct Student *类型
printf("请输入学号(以0结束) 如 10\n");
scanf("%d", &p1->num);
getchar();
head = NULL;
while (p1->num != 0)//只要学号输入不是0,可以无限延展
{
n = n + 1;
if (n == 1) head = p1;//p1所记录的为链表头【仅第一次】
else p2->next = p1;//p2的下一个指向【将要】新输入的p1的地址========
p2 = p1;//p2指向【现在】p1的地址=================================
p1 = (struct Student *)malloc(LEN);//p1搞了个【新】地址,p2记得就是刚才p1所在的地址了,p1“延展了”
printf("请输入学号(以0结束) 如 10\n");
scanf("%d", &p1->num);
getchar();
}
p2->next = NULL;//链表结束了
return head;//返回值为指向链表头的指针
}
int main()
{
struct Student *pt;
pt = creat();//pt指向creat函数运行完后的“head”地址
while (pt != NULL)//输出链表元素,直至尽头
{
printf("\n num:%d", pt->num);
pt = pt->next;//当前“读指针”,指向下一个
}
return 0;
}
//参照自P313,谭浩强《C程序设计》第四版
c++的<new、delete>版
//动态链表(new的使用)
#include <iostream>
using namespace std;
struct A
{
int data; A* next;
};
A * head = NULL;
void main()
{
cout << "随便输入整数,遇到0结束,然后遍历链表输出"<<endl;
int b;
A *p1, *p2;
p1 = new A;
head = p1;
while (cin >> p1->data && p1->data != 0)
{
p2 = p1;
p1 = new A;
p2->next = p1;
}
delete p1;
p2 ->next = NULL;
cout << "之前输入的有:" << endl;
p1 = head;
while (p1 != NULL)
{
cout<<p1->data<<endl;
p1=p1->next;
}
delete p1;
}