关于c语言学习的小总结(主要是指针)杂记

经过1个半月的学习,差不多已经学完了c,下面是我的一些杂记,主要是指针方面,希望能够给
小白一些参考;

<stdio.h> 带着就对了
<math.h> 好像涉及数学的都要带 例如sqrt
<string.h>一类 str,
#define 提前对某个值赋值;
scanf % & 确定整数/小数/等等,然后赋值 结尾是printf(“xxx %d/f/…”,xxx);

int 假设 一般是int x,x,x…; 数字
float 单精度(带小数且较小较精确)
double 双(带。。。较大)
char 用来表示字母一般‘x’

default 剩下的
%d 整数
%f 带有小数
%c 带有英文字母
%t 相当于tab
%s 文字,英文字句
%m.nf (m指输出数据共几行,n指的是小数点占几行)

pow(x,n) 意思是x的n次方
= 赋值 ==等于
|| 并,或 (2假) && 与,且(2真)
! 非(真改为假)

x=(int)a/b 就是硬把a/b的值搞成整数 int可改为float double , 强制类型转换

********** d[i]=’\0’;//在d数组的有效字符后加‘\0’

for/while() 一个整体
{
}

double 后面的定义%lf

gets/puts(a)

sizeof 输出字节长度

****************函数的递归
我的理解就是在一个函数中继续调用这个函数
例如 int age(int n)
{int c;
if(n==1)
c=10;
else
c=age(n-1)+2; 当n=5时,age(4)+2,然后将4代入,age(3)+2+2。。。。。。。

static(静态局部变量)在函数调用结束后不消失而继续保留
auto (自动变量)可以省略
register(寄存器变量)加快运行速度
extern 扩展外部变量的作用域 见书206
内部(静态)外部函数 static extern 不能/能被其他文件调用

指针:

*************************************************************************/
//声明了一个普通变量 a
int a;
//声明一个指针变量,指向变量 a 的地址
int pa;
//通过取地址符&,获取 a 的地址,赋值给指针变量
pa = &a;
//通过间接寻址符,获取指针指向的内容
printf("%d", pa);(pa=a) 注意
输出时要带

*****************************************************************//
**************************指向数组的指针
**如以下语句:
int nums[10], p;
1
上面语句定义了一个数组 nums,在定义时分配了 10 个连续的int 内存空间。
而一个数组的首地址即为数组名nums,或者第一个元素的首地址也是数组的首地址。
那么有两种方式让指针变量 p 指向数组 nums:
//数组名即为数组的首地址
p = nums;
//数组第一个元素的地址也是数组的首地址
p = &nums[0];
上面两句是
等价
的。
p + 1,此操作为指针加整数操作,即向前移动一个单元。
此时 p + 1 指向 nums[0]的下一个元素,即 nums[1]。通过p + x整数可以移动到想要操作的元素(此整数可以为负数)。
如上面,p,(p + 0)指向 nums[0]、p + 1 指向 nums[1]、、、类推可得,p+i 指向 nums[i],由此可以准确操作指定位置的元素

//由上面推导出
(p + i) = nums[i],所以我们可以通过 for 循环变量元素
for(i = 0; i < 5; i++){
printf(“nums[%d] = %d”, i, *(p + i));

      /公式:    *(a+i)=a[i]             可以运用循环对其赋值
                     *(a[i]+j)=a[i][j]                                          
                     *(a+i)+x=&a[i][x]=a[i]+x

p=a及p=&a[0] p++=a[0]++ 因为数组不能++,只能用指针p++

例如: 例如p=a[0],p++ 使p依次指向下一个元素 在二维数组中 a[1] *(a+1) a[1]+0表示的是1行0列的数
for(i=0;i<10;i++,p++)
printf("%d",*p)

**************int(p)[4]表示int a[4] 指针变量p指向包含4个整型元素的一维数组 通常在二维数组里运用,表示有列*指针里有4个元素

#include<stdio.h>
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (p)[4],i,j;//指针变量p指向包含4个整型元素的一维数组
p=a;//p=&a[0] 从首数组开始
************************************
scanf("%d,%d",&i,&j);
printf(“a[%d,%d]=%d\n”,i,j,((a+i)+j));//a[i][j];
return 0;
}

指针字符***

chara=“love”;=chara a=“love”;
关于字符串的运用,可直接用公式*(a+i)=a[i] ,也可用*p形式。见书257

***************字符指针变量与字符数组关系:前者 存放地址,值可以改变,后者由若干个元素组成,每个元素放一个字符,并且值是固定的;

例如 char*a="i love china!";
      a=a+7;         输出从a指向的字符开始的字符串;
     输出结果是 china!;

可变格式输出函数;见265;

函数指针***//

int max(int,int); 函数声明;
int (*p)(int,int); 定义指向函数的指针变量p; 类型名 (*指针变量名)(函数参数表列); 就是将 函数名 改为 *指针变量名。
p=max; 使p指向max函数;
c=(*p)(a,b); 通过指针变量调用max函数;

int max(intx,inty)

在一定情况下,*p可以指向多个函数:

n==1 p=max

n==2 p=min c=(*p)(a,b)

if(n==1)输出c max
else 还是输出c min 见269;

指向函数的指针作函数参数;

int fun(int x,int y,int(*p)(int,int))
int max/min/add(int,int); 注意不能p=max/。。。。。。

fun(a,b,max/min/add);


int max()

int min()

iny add()

*****返回指针值的函数 类型名 *函数名(参数表列); float *xxx( )

  1. 用函数指针作为函数的返回值

在上面提到的指针函数里面,有这样一类函数,它们也返回指针型数据(地址),但是这个指针不是指向int、char之类的基本类型,
而是指向函数。对于初学者,别说写出这样的函数声明,就是看到这样的写法也是一头雾水。比如,下面的语句:

int (*ff(int))(int *, int);

我们用上面介绍的方法分析一下,ff首先与后面的“()”结合,即:

int (*(ff(int)))(int *, int); // 用括号将ff(int)再括起来

也就意味着,ff是一个函数。

接着与前面的“*”结合,说明ff函数的返回值是一个指针。然后再与后面的“()”结合,也就是说,该指针指向的是一个函数。

这种写法确实让人非常难懂,以至于一些初学者产生误解,认为写出别人看不懂的代码才能显示自己水平高。而事实上恰好相反,
能否写出通俗易懂的代码是衡量程序员是否优秀的标准。一般来说,用typedef关键字会使该声明更简单易懂。在前面我们已经见过:

int (*PF)(int *, int);

也就是说,PF是一个函数指针“变量”。当使用typedef声明后,则PF就成为了一个函数指针“类型”,即:

typedef int (*PF)(int *, int);

这样就定义了返回值的类型。然后,再用PF作为返回值来声明函数:

PF ff(int);

指针数组和多重指针***/ 类型名 *数组名 [数组长度];int *p[4] //注意不是int (*p)[4]这是指向一维数组的指针变量

比较适合指向若干个字符串 就是数组前加个*而已

int a[2][3]={{1,4,6},{12,4,7}};
int *p[2]; 指针数组p[2]指向a数组的2个地址

p[0]=&a[0];//&a[0][0] 起始 p[1]=&a[1];//&a[1][0]
printf("%d\n",(p[0]+1)); //a[0][1] printf("%d\n",(p[1]+2)); //a[1][2]

**********************************数据类型 *q///类型名**指针变量名
int * *q 两个指针 一般当前面有个指针,且下面还要用道指针指向这个指针时

#include<stdio.h>
int main()
{
char name[]={“follow”,“basic”,“great”,“for”,“com”}; 注意: int a[5]={1,2,3,4,5};
charp; int num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]}; //因为指针数组的元素只能存放地址.
int i; 不能是 int
name[5]={1,2,3,4,5};
for(i=0;i<5;i++)
{
p=name+i; //指针p要指向指针数组name.
printf("%s\n",p); 输出指针数组一个 int
p int
q[2] int a[3]
} **p —> *q[0] —> 3 q[0]=&a[0] q[1]=&a[1]…
return 0; **(p+1) —> *q[1] —> 6 p=q//p=&q[0] 指向首地址
} 9

用指针数组作main函数的形参 int main(int argc, char *argv[]) 在dev里作项目;

动态内存分配与指向它的指针变量

开辟动态存储区 #include<stdlib.h>
malloc voidmalloc(unsigned int size); 在内存的动态存储区分配一个长度为size的连续空间 malloc(100) a=(int )malloc(nsizeof(int)) 将nsizeof(int)个内存给a
calloc void*calloc(unsigned n,unsigned size); 在内存的动态存储区分配n个长度为size的连续空间 p=calloc(50,4) 50x4个字节的临时分配域;

relloc voidrelloc(voidp,unsigned int size); 重新分配动态存储区; relloc(p,50) 将p所指向的已分配的动态空间改为50字节;

free void free(void*p); 释放动态存储区 free(p)释放指针p所指向的已分配的动态空间;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student
{
char *name; //改 char name [];
int score;
}*pstu;

int main()
{

pstu=(struct student*)malloc(sizeof(struct student));   ///将地址转成struct student* 型
 改:char *p=NULL;
strcpy(pstu->name,"tom");
pstu->score=99;
 改:char *p=NULL;
printf("name =%s,score =%d\n",pstu->name,pstu->score);
free(p);     
return 0;

}

原式是一个野指针问题,为了避免出现野指针,通常我们需要将指针初始化为NULL,用完后也为其赋值为NULL。
结构体成员指针往往会被我们忽视,注意它也需要初始化,且需要为结构体指针分配足够的内存,真是就用到了malloc这个宏,使用方法如下:

给指针变量赋初值:

方法一:char * p = (char * )malloc(sizeof(char));

方法二:char * p = NULL;

给数组赋初值:

方法一: int a[10] = {0};

方法二: memset(a, 0, sizeof(a));

memset函数有3个参数:第一个是要被设置的内存起始地址;第二个是要被设置的值;第三个是要被设置的内存大小,单位为字节;

给结构体指针赋初值:

方法一: pstu = (struct student *)malloc(sizeof(struct student));

常见错误: pstu = (struct student *)malloc(sizeof(struct student *));

使用完指针后务必记得释放指针所指向的内存,否则不知道什么时候我们又改变了指针的值,使其变成了野指针!

这里就需要free§这个函数的帮忙了,它可以切断指针与指向内存的联系。但是需要注意的是free对于同一指针变量只能使用一次。不然会导致出错或者内存泄漏。

释放完内存后另指针的值变为NULL!

如下:

free§;

p = NULL;

结构体指针/// 例如struct student*pt //pt可以指向struct student类型的变量或数组元素

  struct xxxxxa

{
xxxx
xxxx
xxxx
};
struct xxxxa t;
struct xxxxa *p;
p=&t;
下面用t.xxxx



printf("…",(*P).xxxx,(*P)xxxx…)

void指针*

  void*指针变量

在输出时要强制转换类型 一般是printf("%d",p) 如果是void 则 printf("%d",(int *)p);
#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5}; const变量 常量化变量的值 固定一个变量的值
int i,n;
void p; const <数据类型> 变量名=[表达式]
const <数据类型>
<指针变量名称>[=<指针变量表达式>]
p=a;
n=sizeof(a)/sizeof(int); <数据类型>const<指针变量名>[=<指针运算表达式>]
for(i=0;i<n;i++)
printf("%d",
((int *)p+i); 结尾要强制转换
puts("");
return 0;
}

#include<stdio.h>
int main()
{
int a[]={1,2,3,4,5};
int i,n;
void *p;
int *q;
p=a;
q=(int )p; 或者中途转换
n=sizeof(a)/sizeof(int);
for(i=0;i<n;i++)
printf("%d",
(q+i);
puts("");
return 0;
}

***共用体,枚举
我的理解 :共用体放在结构体中; 枚举 就是把可能的值一一列出来,变量的值只限于列举出来的值; union 共用体名 enum 枚举名 {枚举元素列表}
struct xxx enum color{red,yellow,blue,white,black}; 定义枚举类型
{ enum color i,j,k,pri; 定义枚举变量;变量只能在类型里运用;
xxx …
xxx
union
{
xxxx

};
};

用typedef声明新类型名 typedef int real ;//指定real为类型名,作用与int相同;

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四夕兴言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值