(本人用的编写软件为visual studio)
目录
关于指针(保存地址的变量)
(本人用的编写软件为visual studio)
1、初始定义一个指针:int*p=&i;(p来保存i的地址)
(注意的是*在此不是运算符,*p是作为一整个变量)
(并且指针内不放实际的值,而只放入其他变量的地址)
2、指针函数:void f(int*p);
函数f()中得到的是地址,如f(&i)
3、读取指针:
printf("%p",p);——读取的是p对应量的地址
printf("%d",*p);——读取的是p对应量的地址的值
4、函数变量的数组相当于指针,甚至可以完全等效(数组是特殊的指针)
void(int a[],int min,int max){}
//数组赋值不需要在括号内填数字,原因在于其是个指针,已经指代整个数组
(注意的是由于数组相当于指针,因此不可以在函数中使用sizeof())
int a[10]; int*p=a; //无需&取地址
int a[10]; int*p=&a[0]; //数组单元表达变量,需要用&取地址
5、指针与const
int*const q=&i;//q是const,不能再指向其他变量,而*q仍然能够赋值而改变i
(*q=26;可以进行;而q++;无法进行,因为q作为指针已经固定指向了i)
6、指针的运算
(1)sizeof(char)=1,sizeof(int)=4(一个字符含有1个字节,一个int类型的单元含有4个字节)
#include<stdio.h>
int main() {
int a = 1;
char c = '5';
printf("%d,%d\n", sizeof(a),sizeof(c));
return 0;
}
/*输出4,1*/
(2)当a[]在*p中:
*p=a[0];//没有定义的话就默认
*(p+1)=a[1];
*(p+n)=a[n];
(3)*p++表示的含义为取出p所指的数据,之后把p移至下一位(++的优先级比*高)
#include<stdio.h>
int main() {
int a[5]={5,6,8,9,4}; //(2)
int* p=a;
for (int i = 0; i < 5; i++) {
printf("%d ", *(p+i));
}
printf("\n");
for (int i = 0; i < 5; i++, *p++) { //(3)
int b = *p;
printf("%d ", b);
}
return 0;
}
/*输出:5 6 8 9 4
5 6 8 9 4*/
7、void*p(表示不知道指向什么类型的指针)(void表示不返回输出值)
int i;
int*p=&i;
void*q=(void*)p; (void*表示定义了p指向void——通常用于直接访问某个地址)
((void*)p并没有改变p所指的变量类型,i仍然是int类型,而通过p使得p访问void类型的i)
8、指针有什么用呢?
(1)传入较大数据时用作参数
(2)传入数组后对数组进行操作即改变数组
#include<stdio.h>
int bigger(int *p);
int main()
{
int a[5] = { 1,2,3,4,5, };
int* p = a;
bigger(p);
for (int i = 0; i < 5; i++) {
printf("%d", a[i]);
}
return 0;
}
int bigger(int *p) {
int b[5];
int i = 0;
for (int i = 0; i < 5; i++) {
*(p+i) = *(p + i)+1;
}
return p;
}
//输出结果为23456
(3)函数返回不止一个结果(如下:通过指针同时返回max_n,min_n)
#include<stdio.h>
void compare(int* max, int* min, int* max_n, int* min_n);
int main()
{
int max[5] = { 1,2,3,9,8, };
int min[5] = { 8,5,4,3,6, };
int max_n, min_n;
compare(max, min,&max_n,&min_n);
printf("max is %d\nmin is %d", max_n, min_n);
return 0;
}
void compare(int *max,int *min,int *max_n,int *min_n) {
*max_n = max[0];//用指针将数组导入函数后直接按之前一样的方式使用,而其他变量需要用*x来表示值
*min_n = min[0];
for (int i = 0; i < 5; i++) {
if ( *max_n<max[i]) {
*max_n = max[i];
}
}
for (int i = 0; i < 5; i++) {
if (*min_n > min[i]) {
*min_n = min[i];
}
}
}
/*输出为max is 9
min is 3*/
(4)需要用函数来修改不止一个变量
动态内存分配(动态控制数组大小)
1、用malloc将空间分给指针(使*a变为数组)
#include<stdlib.h>
int *a;
a=(int*)malloc(number*sizeof(int));
2、最后用free(a)来进行还值
(注意malloc与free应时刻对应在一起,如果不还值,当malloc分配的空间过大时会导致内存流失。malloc了什么就free什么)
#include<stdio.h>
#include<stdlib.h>
int main()
{
int number;
scanf_s("%d", &number);
int* a;
a= (int*)malloc(number * sizeof(int));
for (int i = 0; i < number; i++) {
a[i] = i;
}
for (int i = 0; i < number; i++) {
printf("%d\n", a[i]);
}
free(a);
return 0;
}
/*输入5
输出0
1
2
3
4*/
关于结构(struct)
1、格式
struct point { //声明了一个结构类型point
int x;
int y; //x,y为该结构里的成员
}; (分号容易忘记)
struct point p1,p2;(p1,p2都是point结构,里面含有x,y的值)
或者
struct (point) {
int x;
int y;
}p1,p2;(p1,p2可以为无名结构,里面也有想x,y)
2、结构初始化
#include<stdio.h>
int main() {
struct date {
int month;
int day;
int year;
};struct date today = { 03,25,2014 };
struct date thismonth = { .month = 7,.year = 2014 };//其中.day未赋值,默认为0printf("%i-%i-%i\n", today.year, today.month, today.day);
printf("%i-%i-%i", thismonth.year, thismonth.month, thismonth.day);
return 0;
}/*输出结果为:2014-3-25
2014-7-0*/
(注意的是在printf中,%i与%d的输出结果相同。但是在scanf_s中,%d只能读取十进制数,也就是说八进制0、十六进制0x会被忽略,而%i能读取十进制、十六进制或八进制类型的整数值)
3、结构成员
结构成员可以是不同类型的
#include<stdio.h>
int main() {
struct date {
int month;
int day;
int year;
double time;
};
struct date today = { 03,25,2014 ,12.30};
printf("%i-%i-%i-%.2f\n", today.year, today.month, today.day,today.time);
return 0;
}
today.day中的“.”,是用来访问其成员
4、结构运算
赋值:将一个结构类型中的成员的值给另一个成员
例如:struct date today={7,25,2014};
struct date day;
day=today(将today中的所有成员的值赋给了day相应成员)
或者day.year=2015;(可直接赋值给相应结构的成员)
#include<stdio.h>
int main(){
struct date {
int month;
int day;
int year;
double time;
};
struct date today = {03,25,2014,12.30};
struct date tomorrow;
tomorrow = today;
tomorrow.day = 26;
printf("today is %i-%i-%i-%.2f\n", today.year, today.month, today.day, today.time);
printf("tomorrow is %i-%i-%i-%.2f\n", tomorrow.year, tomorrow.month, tomorrow.day, tomorrow.time);
return 0;
}
/*输出结果为today is 2014-3-25-12.30
tomorrow is 2014-3-26-12.30*/
5、结构指针
指针指向一个结构变量时需要用&来取到其地址(与数组不一样,数组可以作为地址直接被取到)
struct date*p=&myday;
(*p).month=12;
p->month=12;
#include<stdio.h>
struct date {
int month;
int day;
int year;
}myday;int main() {
struct date* p = &myday;
struct date* q = &myday;
(*p).month = 12;
printf("%p\n", (*p).month); //printf("%p\n", p->month);
q->month = 12;
printf("%p\n", (*q).month); //printf("%p\n", q->month);
return 0;
}
//输出的地址一样
输出的形式为 printf("%p\n", (*p).month),也可以是 printf("%p\n", p->month)
6、结构与函数
int calculate(struct f number)(整个f类型的number结构可作为参数的值传入函数中)
(此时,是在函数内新建了一个结构变量,并复制调用者的结构的值,同时也可以返回一个结构)
(与此同时,函数运行完之后,原来main函数的原结构中的成员值不发生改变)
#include<stdio.h>
void calculate(struct f any);
struct f {
int x;
int y;
};
int main() {
struct f first = { 2,5 };
calculate(first);
printf("first结构中的x=%d y=%d", first.x, first.y);
return 0;
}
void calculate(struct f any) {
int num;
scanf_s("%d", &num);
for (int i = 0; i < num; i++) {
any.x = any.x + 1;
any.y = any.y + 1;
}
printf("any结构中的x=%d y=%d\n", any.x, any.y);
}
/*输入2,输出结果为:
any结构中的x=4 y=7
first结构中的x=2 y=5*/
(其原因相当于结构的成员值传入函数的并不是自己本身,而是本身的值)
若想要改变函数内结构的值,方法是在这个输入函数中,创建一个临时的结构变量,然后把这个结构返回给调用者
#include<stdio.h>
struct number {
int x;
int y;
};
struct number getstruct(void);//getstruct是个函数,返回的是结构
int main()
{
struct number first = { 1,2 };
first = getstruct();
printf("\n%d %d", first.x, first.y);//改变了first中成员的值
}
struct number getstruct(void)//getstruct是个函数,返回的是结构
{
struct number p;//在结构中传入一个结构
scanf_s("%d", &p.x);
scanf_s("%d", &p.y);
printf("%d %d", p.x, p.y);
return p;//结束后将该结构传回主函数中,对应12行
}
/*输入4 5
输出4 5
4 5*/
结构数组
struct date dates[100];
struct date dates[]={ {4,5,2005}, {2,4,2005} };(里面的括号表示该数组的单元,如 {4,5,2005}表示dates[0])
结构中的结构
struct dateandtime{
struct date sdate;
struct time stime;
};(结构中可以加入不同类型的结构)
嵌套的结构
struct point{
int x;
int y;
};
struct rectangle{
struct point pt1;
struct point pt2;
};
如果有变量struct rectangle r; 就可以有r.pt1.x ,r.pt1.y ,r.pt2.x r.pt2.y
如果有变量定义:struct rectangle r,*rp; rp=&r;
则这四种形式等价:r.pt1.x = rp->pt1.x = (r.pt1).x = (rp->pt1).x
(但是rp->pt1->x不行,因为pt1不是指针)
//输入平面内的两个点,求出两点的长度,x为任意数,y为整数
#include<stdio.h>
#include<math.h>//开方的头文件,再使用sqrt()函数
struct pointx {
double x;
};
struct pointy {
int y;
};
struct point {
struct pointx getx;
struct pointy gety;
};
double lenofline(double x, int y, double xx, int yy);//注意返回的值是double
int main() {
struct point fir;
struct point sec,*zhiy;
zhiy = &sec;
scanf_s("%lf %d", &fir.getx.x, &fir.gety.y);
scanf_s("%lf %d", &sec.getx.x, &sec.gety.y);
double len2 = lenofline(fir.getx.x, fir.gety.y, sec.getx.x, sec.gety.y);
printf("%f", len2);
return 0;
}
double lenofline(double x,int y, double xx,int yy) {
double len;
len = sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
return len;
}
/*
3.5 6
4.6 8
2.28254
*/
//本段代码纯属用来测试知识点,实现该功能有更简单的方法,本人只想到这个例子了