大一菜鸟,前来立贴!!!!
橹主乃是一渣渣二本电子信息工程专业,上半年基本荒废,本人偏喜欢偏软件方向,C语言认真从新开始!!开学第一天:(晚上)3月9号
1,VC编译时尽量保留#include"stdafx,h"头文件//楼主一般保留cpp格式
2,在C语言中除英文的其他文件只能出现在字符中
3,错误提示意义
C2065 'xxx' : undeclared identifier 变量名或函数名错误,没包涵对应的头文件
C1083 Cannot open include file: 'xxx.h': No such file or directory 该包涵的文件不存在或者文件名字书写错误
C1010 unexpected end of file while looking for precompiled header directive #include"stdafx,h"代码不可以删除
C2018 unknown character '0xa3' 代码中出现不可识别字符(主要中文)
C2106 left operand must be l-value 主要指不可以对函数返回值赋值
C2166 l-value specifies const object 主要指给常量赋值,当常量在等号左边的提示
C2196 case value '100' already used switch语句中case分值已经存在
C2051 case expression not constant switch语句中case分值必须是常量,不能是变量
C2057 expected constant expression 定义数组是,元素个数制定必须使用常量
C2734 const object must be initialized在定义const常量是必须初始化
C2628 did you forget a ';'? 当定义结构体类型时,必须在结尾加分号结束
C2460 uses 'xxx', which is being defined 定义结构体类型时,使用了自身结构体做成员变量
4,const为定义常量,只能在定义时同时赋值,而且必须在定义时赋值
5,快速将十进制转化为二进制的放法:用2的倍数进行组合,如15=8+4+2+1(1111)13=8+4+1(1101)
6,将二进制转为十进制的方法:2的倍数相加,1011(8+2+1=11)
7,一字节为一个八位的二进制数,四个二进制的组合刚好是1个十六进制0到F的组合
8,单精度float(后缀f)小数加整数大约只能存储六位到七位,双精度double小数加整数大约只能储存12—14位
9,C语言中还有一种特殊常量,字符常量(0—127)ascll码表(键盘)
10,转义字符:
'\t'制表键,8的整数倍对齐,编码9
'\\'两个反斜线才是一个反斜线的编码92
'\"'双引号34
'\''单引号39
接下来认认真真从论坛打了一个小程序
#include "stdafx.h"
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>//定义杂项函数及内存分配函数
//system("color **")包含在 #include<stdilib.h>头文件,第一个为背景,第二个则为前景
//Sleep 执行挂起一段时间,使用头文件#include<windows.h>中(sleep存放头文件:winbase.h)
int main(int argc, char* argv[])
{
system("color 1F");//蓝色,亮白色
Sleep(1500);
printf("武\n");
system("color 2E");//绿色,淡黄色
Sleep(1500);
printf("套\n");
system("color 3D");//湖蓝色,淡紫色
Sleep(1500);
printf("套\n");
system("color 4C");//红色,淡红色
Sleep(1500);
printf("逗\n");
system("color 5A");//紫色,淡紫色
Sleep(1500);
printf("比\n");
system("color 6B");//黄色,淡黄色
Sleep(1500);
printf("~\n");
return 0;
}
附加一些百度:
2,system("color **")包含在 #include<stdilib.h>头文件。
颜色属性由两个十六进制数字指定 -- 第一个为背景,第二个则为前景。每个数字可以为以下任何值之一:
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 湖蓝色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
希望楼主能继续下去
开学第二个晚上3月十号
从六点开始,楼主用的是vc6.0,适才逛了诳论坛,楼主看的是吕鑫的视频,希望有兴趣的可以相互交流一下,楼主毕竟是个菜鸟,许多没理解到位的地方还请指正,谢谢。
下面是楼主今天晚上的收获:
11,头文件为:#include <math.h>的pow() 函数用来求 x 的 y 次幂(次方),其原型为:double pow(double x, double y);
12,字符常量为单个字符(单引号),字符串常量是内存中连续的多个字符的地址
13,常量在内存中一般没有地址(特殊的字符串常量除外)
14,内存从ox0000 0000到0xffff ffff(一个十六进制数由8位二进制数组成(84218421))也就是0到4G-1的范围(一字节(bite)有八位二进制数组成)
15,栈空间是从0x0012 ff7c-0x0012 ff80(大约一兆(一兆大概100万字节))
16,每个字符占一个字节
17,一位只能表达0.1
二位只能表达0.1.2.3(2*2(排列组合))
三位:0-7
......
八位:(十六进制)0-255
18,单字节变量(单子节八位):char(因为第一位给去确定正负(0正1负)故还有7位,2^7-1=127)因此取值范围为—128到127
unsigned char 从0到255
char 0-127与unsigned无区别,128以后是负数(-128到-1)(注意不是-127)
19,双子节变量(双字节十六位2^16=65536)
unsigned short 0-65535
short 0到32767(32k-1) -32678到-1(-32k)
20,四字节变量
unsinged long 0-4G-1(近43亿)
long —2G到-1 0到2G-1
21,printf注意
a)必须带入一个控制字符串,控制字符串可以有0到多个%开头控制字符组成
b)每含有一个%开头控制符,必须对应在后面一个逗号后的一个常量或变量
c)如果一个%控制符没有对应一个数值和变量,将随机打印一些数值
d)如果一个%s控制符没有对应好一个有效字符串地址,程序可能崩溃
22,控制字符种类
%c:带入一个数字(0-127)打印出ascll文本
%s: 输入或输出一个字符串
%x:十六进制 %o:八进制
%f:单精度浮点数(小数点部分保留6位) %lf:双精度浮点数
23,占位控制
a)对于整数在%后加一个数字就是用于打印时控制占位宽度,负号代表左对齐
b)对于字符串在%s后加一个数字就是用于打印时控制占位宽度,负号代表左对齐
c)对于浮点数在%后加一个数字就是用于打印时控制占位宽度,负号代表左对齐
控制符可以用小数点管理浮点数的位数(缺省是6位)
d)浮点数总的位数大于占位符的话,占位符无效
24,scanf在使用空格做间隔符时,可以用回车代替空格输入(dos窗口内)
25,其他的一些输入输出函数
a)putchar 代入一个数字打印出ascll码文本
getchar在键盘上输入一个文本返回字符对应编码
b)putch 无回显输入函数,代入一个数字打印出ascll码文本
getch 输入之后不回显(不回显示在屏幕上)不等待回车,碰任何键就会返回给程序输入的字符编码
c) puts 输出一行单纯的文字
gets 获取一行文字
d)putc 用于代入一个文件指针(putc既可以向屏幕输出字符,也可以向文件输出(可将屏幕当成一种特殊的文件stdin))
getc 既可以从键盘输入字符,也可以从文件中输入字符
26,case错误:
c2196:case value 'xx'already used 代表有重复的case分支
c2051: case expression not canstant 代表使用了变量做case分支
(case语句条件合并任意一个成立则执行)
附加函数百度:
3,原型:extern void gotoxy(int x, int y);
用法:#include <system.h>
功能:将光标移动到指定位置说明:gotoxy(x,y)将光标移动到指定行y和列x。
设置光标到文本屏幕的指定位置,其中参数x,y为文本屏幕的坐标
4,COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标。其定义为:
typedef struct _COORD
{
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate
} COORD;
楼主最近对俄罗斯方块比较感兴趣,不过指针链表啥后面的东西基本就是屎,所以得慢慢来,希望大神在楼主不懂的时候可以帮帮楼主,谢谢
有些地方楼主不是太懂,希望指正,今晚没有练习代码。看的时间看太长了
希望楼主自己能继续下去。
开学的第三个晚上 3月11号
楼主今天课比较少,今天晚上主要自己尝试不看视频代码画菱形等图案,楼主的思维还是弱爆了,花费好长时间先想在借鉴才解决几个,再者楼主真的是菜鸟,学习也没那么 神速,虽然是电子信息工程这种工科专业,但是,学校毕竟渣,加之课也少,最近不上晚自习,所以空余时间不少,楼主虽然上半年基本荒废,但还是对C语言大体框架还是有了解的,但是后面的指针链表啥都弱爆了,橹主准备前面专拣模糊的不会的看,没事多百度,但楼主的编程能力还是弱爆了,不扯了,上今天收获
27,system函数
所属头文件#include<process.h>/#include<stdlib.h>,参数为字符串
int system( const char *command );
可以用来执行指定路径下的可执行文件,也可以调用一些DOS命令,在这里使用和在CMD的命令行中执行这条命令的效果相同
比如:system("C:\\MT_Sqlconn.exe > C:\\out.log");
意思是,执行C:\\MT_Sqlconn.exe,并把这个文件的输出结果重定向到 C:\\out.log文件中
也可以调用一些dos命令,如system("cls");清屏,等于在DOS上使用cls命令
28,常用dos命令:
CLS 清除屏幕。 DATE 显示或设置日期。
COLOR 设置默认控制台前景和背景颜色 DEL 删除至少一个文件。
MD 创建目录 DIR 显示一个目录中的文件和子目录。
CD 显示当前目录的名称或将其更改 ECHO 显示消息,或将命令回显打开或关上
EXIT 退出 CMD.EXE 程序(命令解释程序)。 pause 暂停,中文版的按任意键继续
。。。。。总之百度
29,条件简写 if(n!=0)可简写为if(n) if(n==0)可简写为if(!n)
30, vc中getchar有个毛病:第一次使用正常,回车后再次执行会出现将上一次回车符号取下来,可以使用两次getchar来避免获取到的"\n"带来的问题
也可以使用fflush函数清理缓存(stdio.h头文件)如fflush(stdin);//stdin就是键盘输入的标准缓冲
31,嵌套循环一般先写里面,再写外面
32,sizeof用于常量或者变量的空间测量(字节数)不是运行时的计算.。而是编译时的计算,得出结果为常量(这句不是太明白)(字符串常量得出的尺寸包涵'\0')
33,简单的双分支if语句也可以使用?:组合符号来实现
34,一般认为前++--会快一些,
35,a)<<按位左移,相当于乘2 移几位,相当于乘以几个2
>>按位右移,相当于除2 如10=8+2 1010<<1=10100=20
b)十进制每多几个o,就是乘以几个10,所以二进制每多几个0就是乘以几个2
十进制每少几个o,就是除以几个10,所以二进制每少几个0就是除以几个2
c)有符号变量当在最高位是1的时候(负数),做右移运算,移动后高位填充的是1
如果使用无符号变量做右移,移动后高位填充的是0
36,一个符号才是按位符号,两个是复合逻辑与或符号!!!(非就是取反)
&按位与,相同位两数字都为1才1
|按位或,只要相同位有一个为1就是1(没有重叠就是加法)
~按位取反(单目运算),取反
^按位异或:相同位相同便为1,不同则为0
37,当主调函数给出的实际参数数量不足或过多时,会出现以下错误提示
function does not tak x parametr
下面是楼主先自己想后借鉴才写出来的渣渣代码
#include "stdafx.h"
#include<stdio.h>
#include<process.h>
/*
i行从下到上依次增加,故可以内循环一次完成一行,跳出内循环增加行数
j列从做到右依次增加(从1开始)故从内循环跳出时应让j列归1,
然后进入内循环依次增加
因为每一行的列数等于的所在行数i,故判断条件应为列j<=行i
*/
/*int main(int argc, char* argv[])
{
system("color 37");//调dos窗口颜色
int i=1,j=1;//i行,j列
while(i<10)
{
j=1;
while(j<=i)//第一次应该循环一次,第二次应该二次。。。。。。
{
printf("%d*%d=%d ",j,i,i*j);
++j;
}
printf("\n");
++i;
}
return 0;
}*/
/*打印图形*/
/*三角形*/
int main()
{
system("color 37");//调dos窗口颜色
int i=1,j=1;
i=1;
while(i<=7)
{
j=1;
while(j<=i)
{
printf("* ");
++j;
}
printf("\n");
++i;
}
while(i>1)
{
--i;
j=1;
while(j<i)
{
printf("* ");
++j;
}
printf("\n");
}
printf("\n");
printf("\n");
/*菱形*/
i=1; j=1;
while(i<=7)
{
j=1;
while(j<=7-i)
{
printf(" ");
++j;
}
while(j<=7)
{
printf("* ");
++j;
}
printf("\n");
++i;
}
i=1; j=1;
while(i<=7)
{
j=1;
while(j<=i)
{
printf(" ");
++j;
}
while(j<=7)
{
printf("* ");
++j;
}
printf("\n");
++i;
}
return 0;
}
希望楼主能继续下去
开学的第四个晚上:3月12号
楼主问下,结完贴后还能继续写吗??楼主今天被这些内存变量整的挺懵的,我得好好想想,现在对这些感觉还是挺蒙蔽的,上今天的,没代码,现在头有点大
38,在嵌套循环中,如果把内层循环写成一个独立的函数,可增加代码清晰度
39,入栈和退栈的过程:
a)一个执行文件的启动来源于操作系统(os)内核
b)当双击一个执行文件时,就是把双击文件的路径和文件名通知到os,os接收到之后按照路径和文件名加载执行文件
c)内核加载了执行文件后,立即调用main函数进入用户代码区
d)退栈过程类似弹簧弹起和压缩过程,栈内存使用时流动性的
40,一个main函数系统大概分配一兆的栈空间,若超过一兆,则不能继续进行下去)
41,头文件#include<ctype.h>的一些函数
a)isdigit 定义 int isdigit(char c) 说明:检查参数c是否为阿拉伯数字0到9。
返回值 若参数c为阿拉伯数字,则返回TRUE,否则返回NULL(0)。
b)isalpha 头文件加入<cctype>或者<iostream> (C语言使用<ctype.h>)
定义int isalpha(int ch )说明:判断字符ch是否为英文字母,若为小写字母,返回2,若为大写字母,返回1。若不是字母,返回0
c)isupper 用来测试大写字母, islower测试字符是否为小写字母 头文件#include<cctype>(旧版本的编译器使用<ctype.h>
d)一般is开头的函数的意思就是测试什么是神马
42,Toupper功能: 将字符c转换为大写英文字母(原来就是大写返回原值)
Tolower功能: 把字符转换成小写字母,非字母字符不做出处理
头文件:在VC6.0可以是ctype.h或者stdlib.h,常用ctype.h
说明:俩个函数和函数int _tolower( int c );功能一样,但是_tolower在VC6.0中头文件要用ctype.h
43,sprintf函数: 往往作为浮点数或者正数数字向字符串转化的函数
比如把打向dos窗口的数字存入一个字符串数组中
swprintf函数:把格式化数据写入一个流中
由于sprintf只能输出字符,字符串和整型数据,要输出任意类型应该用swprintf
44,大写字母与小写字母ascll码相差32 (a97 A65)
45,#include <stdlib.h>
atoi 是把字符串转换成长整型数的一个函数
atof 是把字符串转换成浮点数的函数
46,内存总共的空间是0-0xffff ffff(32位空间)但栈空间只有1兆(main)
不能随便用指针指向一个空间赋值,这样会造成程序崩溃,
47,在定义 int *p 时,p占有内存空间是系统分配,但是位于栈区
(栈区变量空间的存在依赖于变量的生命周期,如一个子函数的结束,该子函数里声明定义的变量也会随之结束)。
存放系统随机给的一个值(实际上就是一个地址) ,这个值对应着的一处空间,并非为空。
48,内存分区有:1:栈,2:全局(静态)区,3:堆,4:字符串常量区。(代码区是可选的答案)
a)栈(stack):C语言函数内部变量和形式参数等。
在进入函数时候自动分配,在离开函数自动清除变量储存区
b)全局/静态区:存放全局变量和静态变量的储存区
全局变量也称外部变量,是在函数外部定义的变量,(公用变量,任意调用)
静态变量(与全局变量被分配到同一块内存中)静态局部变量只限于定义处函数使用,但是离开函数后数值一直保留,直到程序退出前不会被清楚
c)堆(heap):由调用函数malloc函数分配的内存块,
一般每一次malloc函数分配的内存块,最后都要调用一次free函数释放这个内存块(没有释放会在程序结束,操作系统会自动收回)
d)常量储存区:就是存放程序内所有字符串常量内存区域
这个内存区域上储存内容不允许修改,知道程序退出
49,vc中memory中出现CD的都是被占用申请的空间
50,栈空间内存比较小,往往从main函数开始,每调用一个函数增加一些栈空间的使用
51,对于全局变量,在任意函数中修改,在其他函数中仍可以打印调用(修改)
52,在没有申请过的内存空间是不能随便使用的,如栈想要使用空间,就得向堆内申请
53,一般常量为数字以直接扔给cpu使用(字符串常量除外),一般常量不是存在内存中
所以一般这些地址空间是不能被使用的,
字符串常量内存空间虽然可以被使用,但这部分空间只可以被读出来,而不能被写进去
54 在 Debug 模式下,
VC 会把未初始化的栈内存全部填成 0xcc,当字符串看就是 烫烫烫烫……
会把未初始化的堆内存全部填成 0xcd,当字符串看就是 屯屯屯屯……
可以让我们方便地看出那些内存没初始化
55,在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量。
56,全局变量和静态局部变量在main函数调用之前已经被初始化
每次调用该函数静态局部变量就不会初始化了数,因为它要长期保存最好一次进入函数的赋值,知道程序退出才会被删除
57,全局变量的声明和调用
a)全局变量定义尽量在源代码文件最上方
b)如果全局变量在主调函数下方,不能被主调函数可见,则可以使用全局变量声明
c)全局变量声明类似函数声明。声明格试变量定义前面加extern 关键字 如:extern int g_nest;
d)切记,全局变量的声明不能被初始化赋值
希望楼主能继续下去
开学的第五个晚上: 3月13号
今天晚上感觉楼主看的不认真,不在状态,也行是感觉对后面有点懵比吧,所以楼主得在内存原理和指针原理这块停留研究了,楼主现在还是对这些东西比较迷茫,楼主赶紧后面的确实有点吃力,对函数变量,全局静态变量,以及内存原理,指针不是太懂,有什么不对的地方还请大神指正
58,全局变量加static代表该文件私有,不提供给其他源文件引用
59,array数组:是一组具有相同数据类型的有序变量集合,在内存中表现为一块连续的储存区域
60,数组的中括号内必须是常量,但可以使用常量表达试,如sizeof
61,变量的时候定义时赋值叫初始化
62,sizeof(array)等价于sizeof(a)=sizeof(数据类型)*个数
求数组个数:int i=sizeof(array)/sizeof(int)
最好的求数组元素个数方法:sizeof(array)/sizeof(array【0】)
62,数组做参数其实就是一个指针变量
63,指针变量和数组变量的区别
a)指针变量可以随时向任何地址,可以++或--操作,数组变量地址是不可变的
b)sizeof(指针变量)一定是4个字节,数组大小不定
64,指针概念:
a)定义:一个内存变量或者数组变量的内存地址就是指针
b)在32位操作系统中,任何变量的地址都是一个0-4G之间的数字
65,指针变量
a)指针变量:存放指针(内存地址)变量称为指针变量
b)任何类型的指针变量的空间大小都是4字节
c)指针变量记录的内存地址,也称为它指向的地址
66,指针变量的定义:
a)变量类型*指针变量名称【=地址】
如 :int i=0; int*p=&i;
b)同时定义两个以上的指针变量时,每个变量前面都要加*
int*p1,p2;//p2是int类型(p1都是int*类型)
int*p1,*p2//p2才是int*类型
67,指针指向数组是不用加地址符号&,因为数组本身就是地址
68,指针变量不可以直接用数字赋值,只有一个数字可以给指针变量赋值,就是0(空地址)
69,各种不同类型之间的指针变量之间不能直接赋值
指针变量不可以直接用整数常量或者变量赋值
70,使用*符号:对指向的内存地址上的内容进行读或写操作
a)当指针变量指向了一个内存地址,就可以通过*或者【】,来读写所指向内存地址上的数据
b)读写操作所覆盖的内存空间的长度,要依据这个指针变量的来源类型的长度来决定
c)指针的降级;使用了*或者【】都能是指针变量降级为他的来源类型
冒泡算法,搞明白了,但不知道该怎么解释
#include "stdafx.h"
#include<stdio.h>
int main(int argc, char* argv[])
{
#define COUNT sizeof(a)/sizeof(a[0]-1)
int a[]={13,11,22,55,34,88,15,5};
int i=0;
while(i<COUNT)//7 0<7
{
int j=0;
while(j<COUNT-i) //j<7
{
if(a[j]<a[j+1]) //13<11
{
int t=a[j]; //t=13
a[j]=a[j+1];//a[0]=11
a[j+1]=t; //a[1]=13
}
++j; //j=1
}
++i;
}
return 0;
}
楼主这两天心理有点懒散了,不能啊
希望楼主能继续下去
开学的第六个晚上 3月14日
楼主今天一天都不在状态,楼主今年没有参加任何电子类比赛,因为知道自己太弱,不过楼主真的让指针给整的懵逼了,谁能给楼主指点指点啊,晕了,现在感觉头懵懵的,可能还是太懒,懒的打代码,楼主太眼高手低,楼主感觉这两天的激情远不如刚开始那三天了,楼主不想三天打鱼,两天晒网,可能楼主写的太长了,估计没人看的,虽然楼主是用来激励自己的,楼主感觉这几天惰性又上来了,楼主想要认认真真的做一件事,楼主不要半途而废,楼主要坚持下去,楼主不愿意一辈子就是个渣渣,加油自己,楼主就是一条狗!!!阿拉是条狗!!!!
。。。。。。我操,今天记事本关机时忘保存了,反正记的也不懂,好多也不懂,真心对不住自己,楼主一定要养成一个21天的习惯
加油,渣渣狗!!
希望楼主能继续下去。
开学的第七个晚上: 3月15号
楼主今天没看视频。而是选择看书和百度,忽然对指针和变量明白了一点,楼主个又一次感受到了百度的伟大与牛逼,不过今天还是没有敲代码体会,楼主大概今天认真学习了大概两个半小时吧,楼主晚上又是状态不再,楼主感觉自己激情就是那种三天打鱼两天晒网型,明天又是一个新的星期一,加油吧,楼主自己!!!
71,全局变量和全局静态变量的区别
a)若程序由一个源文件构成时,无区别
b)全局静态变量对组成该程序的其他源文件是无效的
c)具有外部链接的静态:可以在所有的源文件里调用,除了本文件,其他文件可以通过extern的方式引用
72,静态全局变量的作用:
a)不必担心其他源文件使用相同变量名,彼此相互独立
b)在某源文件中定义的静态全局变量不能被其他源文件使用或修改
c)只能在本文件中使用,具有内部链接的静态,不允许在其他文件里调用
73,也就是说全局变量和静态全局变量的区别在于作用域不同,
也就是说在一个项目里有多个源程序文件
非静态全局变量可以在所有的源文件里调用
静态全局变量只能在本文件里调用
74,在全局变量前面加一个static,则该变量只在这个源文件中可用,称为全局静态变量
75,全局变量是在所有函数体的外部定义的,程序的所在部分(甚至其它文件中的代码)都可以使用。
如果在一个文件中使用extern关键字来声明另一个文件中存在的全局变量,那么这个文件可以使用这个数据。
76,内存中供用户使用的储存空间可分为3部分(用户区):程序区 静态储存区 动态储存区
全局变量全部存放在静态储存卡中
77,c的储存类别包涵四种: 自动的(auto),静态的(static),寄存器的(register),外部的(extern)
78,在c中,每个变量和函数都有两个属性:数据类型与数据储存类别
79,自动(auto)变量:局部变量(动态分配空间,存在动态储存区) 用关键字auto声明(可省略)
静态(static)局部变量:有时希望局部变量值在函数调用后不消失继续保留,用关键字static声明
寄存器(register)变量:就是直接放在cpu寄存器中的变量 用关键字register声明
80, 指针就是地址(门牌号),可以通过这个地址(门牌号)找到这个地方的内容
一个变量的地址(门牌号)称为该变量的指针,换言说,门牌号就是指针
如果一个变量专门来存放另一个变量的地址(门牌号),就称为指针变量(相当于我找一个地方存放另一个房间的门牌号,我可以通过这个地方找到那个门牌号所在的房间)
指针变量就是一个用来存门牌号的盒子,指针就是一个破门牌号
81,指针变量只能存放指针,换言说,这个盒子只能放门牌号,0也是地址(空)
82,野指针就是指向被释放的或者访问受限的垃圾内存指针,并不是NULL(空)指针
形成原因:
a)指针变量没被初始化(因为任何指针变量刚被创建的时候不会自动成为空指针的,它的缺省值是随机的,也就是会乱指一气)
b)指针p被释放(free)或者删除(delete)后,没置为空指针,
它们(free,delete)只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
所以释放后的指针应立即将指针置为NULL,防止产生“野指针”。
c)指针操作超越了变量的作用范围
83,数组名不代表整个数组,只代表数组首元素的地址,切记,指针就是地址
84,指针p+1并并不是将p值(地址)简单加一,而是加上一个数组所占用的字节数
85,p1与p2若指向同一数组,若执行怕p2-p1,结果是p2-p1的值(两个地址只差)除以数组元素的长度
结果意义:表示p2与p1之间所差元素的个数、
两地址相加是无任何意义的
86,数组指针式指向数组地址的指针,其本质为指针
指针数组是数组元素为指针的数组,其本质为数组
87,所谓数组元素的指针就是数组元素的地址(门牌号)(指针就是门牌号)
数组名代表的是数组中的首元素(指针就是首元素的地址)
88,C语言 *p 和p的区别:
这就好比p(指针变量)用来存放地址,也就是门牌号
*是解引用的操作符,可理解成打开该门,*p意思就是打开p号门,取出数据
希望楼主能继续下去
开学的第八个晚上:3月16号 (星期一)
楼主今天几乎又没有好好学,研究了贪吃蛇,发现结构体不懂真他妈白痴,楼主指针还是不会用,结构体链表还是基本不会,哎,该怎么办呢,从明天开始,敲代码体会吧,感觉在看别人的,自己不亲身体会,还是不行,楼主不能松懈退宿,加油
下面是论坛一个女的神写的贪吃蛇代码,楼主今天研究了一部分,可是下面的就不懂了,还是基础太弱
#include "stdafx.h"//mfc标准头文件,可忽略,在vc里方便通过编译
#include<stdio.h>//基本库
#include<stdlib.h>//系统库
#include<windows.h>//光标定位、字符颜色函数库
#include<time.h>//时间函数库
#include<conio.h>//键值读入函数库
#define width 60//宽度
#define height 25//高度
struct ssnake
{
int f;//蛇身有效标志
int x;
int y;//蛇身坐标
};
void color(int b)//颜色函数
{
/*
GetStdHandle是一个Windows API函数。
它用于从一个特定的标准设备(标准输入、标准输出或标准错误)
中取得一个句柄。
STD_OUTPUT_HANDLE(标准输出的句柄)
SetConsoleTextAttribute是API设置字体颜色和背景色的函数
FOREGROUND_BLUE 字体颜色:蓝(其他颜色加相应单词)
*/
HANDLE hConsle;//创建控制台句柄 hconsle为自定义变量名
hConsle=GetStdHandle((STD_OUTPUT_HANDLE));//获取标准输出的句柄,
SetConsoleTextAttribute(hConsle,b);//设置控制台字体属性(颜色),b就是颜色值
}
void HideCursor()//隐藏光标
{/*
GetConsoleCursorInfo 检索有关指定的控制台屏幕缓冲区的光标的可见性和大小信息。
*/
HANDLE hOut;
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info={1,0};//后边1代表光标可见0代表光标不可见 控制台光标信息
SetConsoleCursorInfo(hOut,&cursor_info);//设置控制台光标信息
}
void gotoxy(int x,int y)//设置字符显示位置
{/*
COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标
SetConsoleCursorPosition是API中定位光标位置的函数。
如果用户定义了 COORD pos,那么pos其实是一个结构体变量,
其中X和Y是它的成员,通过修改pos.X和pos.Y的值就可以实现光标的位置控制。
*/
HANDLE hOut;
hOut=GetStdHandle(STD_OUTPUT_HANDLE);
COORD loc={x,y};
SetConsoleCursorPosition(hOut,loc);
}
void drawmap(char*mp,char*omp,ssnake*snp)//定义结构体指针snp
{//画场景
char pel[]="◆■●";//pel图元
int i,j,k;
for(i=0;snp[i].f>0;i++)
{
j=4;
if(i==0) j=2;
mp[snp[i].x*height+snp[i].y]=j;
}
}
希望楼主能继续下去
开学的第九个晚上 3月17号(星期二)
楼主今天整整一个下午敲了半天的书上的例子,并一边百度着,但还是发现没有问真人效果来的效果一些,楼主觉得今天挺充实的,对指针多少了解了一些,没有那么懵比了,楼主今天被一个指针问题折腾了好长时间,最后,在学长的帮助下解决了,虽然还没有彻底懂,但多少明白了些,哈哈,
/*
int main(int argc, char* argv[])
{
//int *p,w;这里定义了一个整型指针跟数据.它们各被分配了一个存储单元,也就是地址,但是这个地址是不一定的,不可控制的.
//w=9;在这里把9赋给了W,这时W的地址值就是9了.
//【地址是不一定的,地址值就是地址里面存的数值】
//每一个数据都有一个唯一的地址,而地址值()是由用户赋予的.是可控的
//【指针就是地址(门牌号),*就是用来操作地址上的内容(房间里面的东西)】
int a=100,b=10;
int*pointer_1,*pointer_2;//定义两个指针变量(定义两个放门牌号的地方)
pointer_1=&a;//把a的门牌号放在1箱子内
pointer_2=&b;//吧b的门牌号放在2箱子内
printf("a=%d,b=%d\n ",a,b);
printf("*pointer_1=%d,pointer_2=%d\n",*pointer_1,*pointer_2);//【使用*符号:对指向的内存地址上的内容进行读或写操作】
return 0;//这就是利用*把pointer_1指向的地址上的数据用%d的形式打印出来
}
*//*int main()
{
int*p1,*p2,*p,a,b;
puts("please enter two integer numbers(By space interval);");//puts 输出一行单纯的文字 integer 整数 space空格 interval间隔
scanf("%d %d",&a,&b);
p1=&a; p2=&b;//把a的门牌号放在pi盒子中
if(a<b)
{p=p1;p1=p2;p2=p;}//等价于{p1=&b;p2=&a;} p1=p2此时p2为&b 就等价于p1=&b
printf("a=%d,b=%d\n",a,b);
printf("max=%d,min=%d\n",*p1,*p2);//相当于*等于p1指向地址的数据用%d打印出来
return 0;
}*/
/*void swap(int*p1,int*p2)//swap交换
{
int temp;//temp 临时 *p1此时相当于*inpoter_1
temp=*p1; //*对p1指地址上的数据进行读写 *是对p1地址上所存的数据进行操作,p1最开始是没有赋任何值的,但此时实参的值已经传递给了形参,
// p1通过该值指向pointer_1的地址(相当于初始化),所以,此时操作p1的地址就相当于对pointer_1的地址进行操作
*p1=*p2; //使p1地址上所存的数据等于p2上所存的数据 *p1也就相当于a 因为a已经赋值,所以地址单元(门牌号)也就是确定的,
//我可以改变房间里面的数据 这就相当于我对一个已经确定的储存单元进行复制
*p2=temp//这个就相当于我对p2所指的地址里面的数据换为temp的值 这个应该属于*符号的写入功能
} //如a=b 就是把b值赋值在a数据所在的地址内
//int *temp;//未赋值,野指针
//*temp=*p1; //有问题
// p1=*p2;
//p2=*temp;这样是错误的,因为*temp并未赋值,所以储存单元室未知的,对一个未知单元进行复制是不可预料的
int main()
{
int a,b;
int*pointer_1,*pointer_2;
puts("please enter a and b(By space interval): ");
scanf("%d %d",&a,&b);
pointer_1=&a; pointer_2=&b;
if(a<b){swap(pointer_1,pointer_2);}
printf("max=%d,min=%d\n",a,b);
return 0;
}*/
//C语言中实参变量和形参变量之间数据传递是单向的值传递形式
//不能通过改变指针形参的值而使指针实参的值改变
/*void swap(int*p1,int*p2)//这个形参影响补了实参:因为这个传入的是指针的内容,并不是指针本身
{
int *p;
p=p1; // 改变的是形参的内容,但是没有对实参的地址进行任何操作,所以实参值并没有改变
p1=p2;//想要改变实参,就应该对实参的地址以及地址里面的内容进行操作
p2=p
}*/
/*实参只能把值传递给形参,形参不能把值传递给实参*/
/*指针变量做参数的作用是,将一个变量的地址传送到另一个函数中*/
/*void exchange(int*q1,int*q2,int*q3)
{
void swap(int*pt1,int*pt2);
if(*q1<*q2) swap(q1,q2);
if(*q1<*q3) swap(q1,q3);
if(*q2<*q3) swap(q2,q3);
}
void swap(int*pt1,int*pt2)//pt1通过实参的传递先指向q1,在指向p1的地址,从而找到&a
{
int temp;
temp=*pt1;//相当于把pt1指向地址的数值赋值给temp
*pt1=*pt2;//相当于把pt2指向地址的数组赋值到pt1指向的地址中
*pt2=temp;//相当于把temp的数组赋值到pt2所指向的地址中
}
int main()
{
int a,b,c,*p1,*p2,*p3;
puts("please enter three numberd: ");
scanf("%d %d %d",&a,&b,&c);
p1=&a; p2=&b; p3=&c;
exchange(p1,p2,p3);
printf("the order is:%d,%d,%d\n",a,b,c);
return 0;
}*//*
int main()
{
int a[10];//定义数组
int i;
printf("please enter 10 integer numbers: "); //integer 整数
for(i=0;i<10;i++)
scanf("%d",a+i);
for(i=0;i<10;i++)
printf("%d",*(a+i));//通过数组名和元素序号计算元素地址,在找到该元素
printf("\n");//(a+i)【是a数组中序号为i的元素的地址】,*(a+i)是对该地址的数据进行读写,也就是(a+i)的值
}*//*
int main()
{
int a[10];
int *p,i;
puts("please enter 10 interger numbers:");
for(i=0;i<10;i++)
scanf("%d",a+i);
for(p=a;p<(a+10);p++)//(a+10)就是a【10】
printf("%d",*p);//p=a就是指针变量p指向a数组的首元素 p++就是就是使p指向下一元素a【1】
}*//*
int main()
{
int*p,i,a[10];
p=a;
printf("please enter 10 interger numbers: ");
for(i=0;i<10;i++)//
scanf("%d",p++);//第一次应为a[0]
p=a;//经过上个for循环后,p已经指向数组末尾了,如果进行下一个循环不加p=a的话,p将指向a数组下面的储存单元,后果是不可预料的
for(i=0;i<10;i++,p++)
printf(" %d",*p);//将p指向的地址上面的数据用十进制打印
return 0;
}*/
/*当指针指向数组时,可以下标为p[i],编译系统对下标的处理方法是转换为地址的
把p[i]处理成*(p+i),但前提必须弄清p当前指向的是什么。如p当前指向a[3],则p[2]代表的是a[3+2]
*p++等价于*(p++) 由于*与++同优先级,故结合方向为自右而左
*(p++)是先取的*p值,在使p加1,而*(++p)是先使p加1,然后取*p的值
*(p--)是先取的*p值,在使p减1 p+1就是使p指向下一个数组元素
++(*p)表示p所指的元素值加1 相当于++a[0]
*(--p),--号在变量的前面,表示先对变量进行--操作,
希望楼主能继续下去
开学的第十个晚上 3月18号
楼主今天虽然效率不过,不过对指针的理解更加深了一点,楼主总是先敲完代码,在去想去看,这是一个不好的习惯耶,昨天的《行尸走肉》和今天的《闪电侠》都很精彩,哈哈
/*当用数组做参数时,形参是用来接收从实参传递过来的数组元素的地址的
实际上c编译都是将形参数组名作为指针变量来处理的*/
//形参数组名并不是一个固定的地址,而是按指针变量来处理
//存放地址的变量称为指针变量。指针变量是一种特殊的变量,它不同于一般的变量,一般变量存放的是数据本身,而指针变量存放的是数据的地址。
/*
void inv(int x[],int n)//形参 int x[]接收的是实参传递过来的数组首元素的地址 而形参n接收的是实参传递过来的值 此时的int x[]就是a[0]
//因为我操作的是实参的地址,所以不需要返回值
{
int temp,i,j,m=(n-1)/2;//n=10 取整m就是4
for(i=0;i<=m;i++)//也就是循环5次,每次前面与后面互换
{
j=n-1-i;//j第一次为9,i第一次为0,依次增加 n-1=9
temp=x[i];x[i]=x[j];x[j]=temp;
}
return;
}
void inv(int*x,int n)//*x相当于*a也就是a[0] //*p也就是指针变量p所指向的变量 *p=*n理解为将指针变量n所指向的变量的地址上的数据赋值给指针变量p所指向的变量
{
int*p,temp,*i,*j,m=(n-1)/2;
i=x;j=x+n-1;p=x+m;//i=x可理解为将指针i指向指针x(也就是将x内的门牌号放入i内)
//指针i指向a[0],指针j指向a[0+9] ,指针p指向a[0+4]
for(;i<=p;i++,j--)
{temp=*i;*i=*j;*j=temp;}
// return;
}
int main()
{
int i,a[10]={3,7,9,11,0,6,7,5,4,2};
printf("The original array:\n");//original原始的
for(i=0;i<10;i++) //undeclared identifier 未说明标示符
printf("%d",a[i]);
printf("\n");
inv(a,10);//inv矩阵求逆
printf("the array has been inverted:\n");//inverted 反向的
for(i=0;i<10;i++)
printf("%d",a[i]);
printf("\n");
return 0;
}*//*
void inv(int*x,int n)
{
int*p,m=(n-1)/2,temp,*i,*j;
i=x;j=x+n-1;p=x+m;//指针i通过指向x从而指向了p
for(;i<=p;i++,j--)
{temp=*i;*i=*j;*j=temp;}//把指针p指向地址上的值赋值给变量temp
return;//对指针变量i进行操作,*j就是通过*对指针变量j所指向地址上面的值进行操作 *i就是对i所指地址上面的值进行写入
}
int main()
{ //如p是指针变量,只是一个变量 而*p就相当于a[0]
int i,arr[10],*p=arr;//把数组arr[0]的地址赋值给指针变量p //使指针变量p指向数组arr
printf("The original arry:\n");
for(i=0;i<10;i++,p++)
scanf("%d",p);//第一次为p相当于arr[0] 最后应为(p+9)即a[9]
printf("\n");
p=arr;//重新使指针变量p指向a[0]
inv(p,10);
printf("the array has been inverted:\n");
for(p=arr;p<arr+10;p++)//(a[0];a[0]<a[10];a[0++]);
printf("%d",*p);
printf("\n");
return 0;
}*/
//*P=a是指将a的值赋给P所指向的内存单元(如果同类型,不同类型编译器将报错)】】】】】】】】】】】】】
//p=&a是指使指针p指向a,即将a的内存地址赋给p】】】】】】】】】】】】】】】】】】】】】】】】】】】】
//p=a一般情况下是p为指针,a为p基类型的数组,这样之后p可以进行a相等的下标运算】】】】】】】】】】】】
/*
void sort(int x[],int n)//sort 分类,排顺序
{
int i,j,k,t;
for(i=0;i<n-1;i++)//i<9
{
k=i; //k=0,1,2,3---9
for(j=i+1;j<n;j++) //(j=1;j<10;j++)
if(x[j]>x[i]) k=j; //如果x[1]>x[0] k=1 x[2]>x[1] k=2
if(k!=i) //第一次检测k不等于0
{t=x[i];x[i]=x[k];x[k]=t;}//交换x[1]与x[0]的值 交换x[2]与x[1]的值
}
}
int main()
{
int i,*p,a[10];
p=a;//a就是a[0] a[0]就是一个地址,这就相当于p=&a 也就是使指针p指向a[0],也就是将a[0]的内存地址赋给p
printf("please enter 10 interger number:");
for(i=0;i<10;i++)
scanf("%d",p++);//a[0]-a[9]
p=a;//使指针p重新指向a[0],也就是将a[0]的地址赋给p
sort(p,10);
for(p=a,i=0;i<10;i++)
{
printf("%d",*p);
p++;
}
printf("\n");
return 0;
}*/
希望楼主能继续下去
开学的第十一个晚上 3月19号
加油啊,楼主,再坚持坚持,指针就能过去了,了解一遍啊,C语言,坚持!!!!
//二维数组中 请务必记住a[i]和*(a+i)是等价的 a[i]+j就是a[i][j]的值
//所以*(*(a+i)+j)是与a[i][j]等价的 //i是行数 j是列数 *符号才是对指针变量指向地址的值进行读写操作
/*int main()
{
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
printf("%d,%d\n",a,*a);//a就是a[0],a[0]就是一个地址,就是将a[0]的地址以十进制的形式打印 *a就是使指针变量指向数组a[0]的地址,等价于a[0](数组a[0]就是一个地址)
printf("%d,%d\n",a[0],*(a+0));//0行0列元素的地址
printf("%d,%d\n",&a[0],&a[0][0]);
printf("%d,%d\n",a[1],a+1);//a+1等价a[1],因为数组就是一个地址,所以不加*号打印出来也是地址的十进制形式
printf("%d,%d\n",&a[1][0],*(a+1)+0);//一行一列元素的地址
printf("%d,%d\n",a[2],*(a+2));//2行0列元素地址
return 0;
}*/
/*
%4d是printf的格式化参数,表示输出一个整型数值,输出宽度为4,且右对齐,如:
printf( "%4d", 1 );
1 //输出1的前边有3个空格,补齐4位的宽度
printf( "%4d", 11);
11 //输出11前边有2个空格,补齐4位的宽度
printf( "%4d", 11111 );
11111 //因为超过了4位,所以前边没有空格
如果要左对齐,则改为 %-4d
*//*
int main()
{//a[1][0]地址值比a[0][1]大
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
int*p; //a[0]+12就是a[0][12]
//p++每次增加四个字节,比如从a[0][0]到a[0][1]
//二维数组也是地址上市连续的,第一行最后一个元素是与第二个首个元素地址是相连的p+1就是指向下一个yuansu
for(p=a[0];p<a[0]+12;p++)//把a[0][0]的值赋值给指针变量p
{ //使p依次指向下一个元素
if((p-a[0])%4==0) printf("\n");//p移动四次后换行
printf("%4d",*p);
}
printf("\n");
return 0;
}*//*
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4],i,j;//指针变量p指向包含四个整形元素的一维数组 (*p)[0] (*p)[1] (*p)[2] (*p)[3]
p=a;//p指向二维数组的零行
printf("please enter row and colum:");//row 行 colum 圆柱上 列
scanf("%d %d",&i,&j);
printf("a[%d,%d]=%d\n",i,j,*(*(p+i)+j));//*(p+i)等价于a[i][0]
return 0;
}*//*
int main()
{
int a[4]={1,3,5,7};// subscript requires array or pointer type 下标需要数组或指针类型(一般是数组忘记打分号)
int (*p)[4];
p=&a;//p指向一维数组
printf("%d\n",(*p)[2]);
return 0;
}*//*
void average(float*p,int n)//*score指向*p n=12 *score就是score[0][0]
{
float*p_end;
float sum=0,aver;
p_end=p+n-1;//最后一个元素p+11
for(;p<=p_end;p++)
sum=sum+(*p);//第一次*p就是scor[0][0]的值
aver=sum/n;
printf("average=%5.2f\n",aver);
}
void search(float(*p)[4],int n)//实参score的值(代表该数组0行的起始地址)传给p,是p指向score[0]
{int i;//float(*p)[4]就是一个指向包含4个元素到底一维数组指针变量
printf("The score of No.%d are:\n",n);//No就是 numero数目,号码
for(i=0;i<4;i++)
printf("%5.2f",*(*(p+n)+i));
printf("\n");
}
int main()
{
float score[3][4]={65,67,70,60,80,87,90,81,90,99,100,98};
average(*score,12);//score得分
search(score,2);//search 搜索
return 0;
}*/
//%5.2f是表示五位有效数字且小数点后有两位数字的浮点型数据
/*void search(float(*p)[4],int n)//形参p是指向包含4个float型元素的一维数组到底指针变量 n为3
{
int i,j,flag;//flag 标示 变弱
for(j=0;j<n;j++)//
{flag=0;
for(i=0;i<4;i++)//*(p+j)就是score[j]
if(*(*(p+j)+i)<60) flag=1;//score[j][i]值<60
if(flag==1)
{
printf("No.%d fails,his scores are:\n",j+1);
for(i=0;i<4;i++)
printf("%5.1f",*(*(p+j)+i));//score[i][j]
printf("\n");
}
}
}
int main()
{
float score[3][4]={{65,57,70,60},{58,87,90,81},{90,99,98,100}};
search(score,3);
return 0;
}*/
// C语言中的数据类型没有字符串型,但是它提供了进行整串输入和输出的格式说明符%s.
//%c是按字符格式输入和输出(单个) %s是按字符串格式输入和输出 (多个)
/*int main()
{
char string[]="I love china!";
printf("%s\n",string);//用%s格式声明输出string 可以输出整个字符串
printf("%c\n",string[7]);//用%c格式输出一个字符数组的元素
return 0;
}*//*
//C语言中只有字符变量,没有字符串变量
int main()
{char*string="I Love China!";//定义一个字符指针变量并赋值初始化
printf("%s\n",string);
return 0;
}*/
//字符常量占一个字节的内存空间。
//字符串常量占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符"\0" (ASCII码为0)。这是字符串结束的标志。
/*int main()
{
char a[]="I am a student.",b[20];
int i;
for(i=0;*(a+i)!='\0';i++)//检测字符串是不是处理完
*(b+i)=*(a+i);//*(b+i)等价于b[i],即对b[i]地址上数据进行操作
*(b+i)='\0';
printf("string a is:%s\n",a);
printf("string b is:");
for(i=0;b[i]!='\0';i++)
printf("%c",b[i]);
printf("\n");
return 0;
}*//*
int main()
{
char a[]="I am boy.",b[20],*p1,*p2;
p1=a;p2=b;//p1,p2分别指向a数组和b数组中的第一个元素
for(;*p1!='\0';p1++,p2++)//p1,p2每次加一
*p2=*p1;//将p1所指向的元素的值赋值给p2所指向的元素
*p2='\0';//加结束符
printf("string a is:%s\n",a);
printf("string b is:%s\n",b);
return 0;
}*//*
void copy_string(char from[],char to[])//数组a,b首元素的值
{int i=0;
while(from[i]!='\0')
{to[i]=from[i]; i++;}//把b数组的值对应复制给a数组
to[i]='0';
}
int main()// unexpected end of file found 文件未结束
{
char a[]="I am a teacher.";
char b[]="You are astudent";
printf("string a=%s\n string b=%s\n",a,b);
printf("copy string a to string b:\n");
copy_string(a,b);
printf("\n string a=%s\n string b=%s\n",a,b);
return 0;
}*//*
int main()
{
char a[]="I am a teacher.";
char b[]="You are astudent";
char*from=a,*to=b;
printf("string a=%s\n string b=%s\n",a,b);
printf("\ncopy string a to string b:\n");
copy_string(from,to);
printf("stirng a=%s\nstirng b=%s\n",a,b);
return 0;
}*//*
void copy_string(char*from,char*to)//a,p
{
for(;*from!='\0';from++,to++)//指针a,p依次加以
{*to=*from;}//把指针p指向数组的值赋值给指针a指向所在数组地址上
*to='\0';//加结束符
}
int main()
{
char*a="I am a teachaer";
char b[]="you are student.";
char*p=b;
printf("string a=%s\nstring b=%s\n",a,b);
printf("\ncopy string a to string b:\n");
copy_string(a,p);
printf("string a=%s\n string b=%s\n",a,b);
return 0;
}*///一个汉字占两个字符
//字符数组由若干个元素组成,每个元素放一个字符,而字符指针变量中存放的是地址(字符串第一个字符的地址),
//可以字符指针变量赋值,但不能对数组名赋值
//编译时为字符数组分配若干储存单元,以存放各元素的值,而对字符指针变量,只分配一个储存单元
//指针变量是可以改变的,但数组名代表一个固定的值(数组首元素的地址),不能改变
//字符数组中个元素的值是可以改变的(可以对他们再赋值),但字符指针变量指向的字符串常量中内容是不可以被取代的
//用指针变量指向一个格式字符串,可以用它代替printf函数格式字符串
/*如 char*format;//格式
format="a=%d,b=%f\n";
printf(format,a,b);
因此只有改变指针变量format所指向的字符串,就可以改变输入输出格式,这种printf函数称为可变格式输出函数*/
希望楼主能继续下去
[ 本帖最后由 逛奔的蜗牛 于 2015-3-19 21:26 编辑 ]