C语言编程的问题:哪里出错了,指针搞得我好乱,题目要求还要用上SPRINTF函数~~乱了乱了,求高人指点

作者&投稿:勾姬 (若有异议请与网页底部的电邮联系)
用C语言编写程序,求1到10的阶乘之和:S=1!+2!+3!+4!+5!+6!+7!+8!+9!+10!~

#include
#include
int main()
{
int i=0;
int j=0;
int mul=1;
int sum=0;
for(i=1;i<=10;i++)//和循环
{
mul=1;//每次循环前都需要初始化为1,要不然最后结果会变大
for(j=1;j<=i;j++)//阶乘循环
{
mul=mul*j;
}
sum=sum+mul;
}
printf("%d",sum);
system("pause");
return 0;
}
C11标准:
2011年12月8日,国际标准化组织(ISO)和国际电工委员会(IEC)再次发布了C语言的新标准,名叫ISO/IEC 9899:2011 - Information technology -- Programming languages -- C ,简称C11标准,原名C1X。这是C语言的第三个官方标准,也是C语言的最新标准。



扩展资料
C语言特点
1、高级语言:它是把高级语言的基本结构和语句与低级语言的实用性结合起来的工作单元。
2、结构式语言:结构式语言的显著特点是代码及数据的分隔化,即程序的各个部分除了必要的信息交流外彼此独立。这种结构化方式可使程序层次清晰,便于使用、维护以及调试。
C 语言是以函数形式提供给用户的,这些函数可方便的调用,并具有多种循环、条件语句控制程序流向,从而使程序完全结构化。
3、代码级别的跨平台:由于标准的存在,使得几乎同样的C代码可用于多种操作系统,如Windows、DOS、UNIX等等;也适用于多种机型。C语言对编写需要进行硬件操作的场合,优于其它高级语言。
4、使用指针:可以直接进行靠近硬件的操作,但是C的指针操作不做保护,也给它带来了很多不安全的因素。C++在这方面做了改进,在保留了指针操作的同时又增强了安全性,受到了一些用户的支持,但是,由于这些改进增加语言的复杂度,也为另一部分所诟病。
Java则吸取了C++的教训,取消了指针操作,也取消了C++改进中一些备受争议的地方,在安全性和适合性方面均取得良好的效果,但其本身解释在虚拟机中运行,运行效率低于C++/C。一般而言,C,C++,java被视为同一系的语言,它们长期占据着程序使用榜的前三名。
参考资料来源:百度百科-c语言

选自《CSDN 社区电子杂志——C/C++杂志》
http://emag.csdn.net2005 年1 月 总第1 期 - 93 -
本文作者:steedhorse(晨星)
printf 可能是许多程序员在开始学习C 语言时接触到的第二个函数(我猜第一个是main),说
起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf 了解多
吗?在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。
由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,
后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。所以本文着重介绍sprintf,有时
也穿插着用用pritnf。
sprintf 是个变参函数,定义如下:
int sprintf( char *buffer, const char *format [, argument] ... );
除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:
格式化字符串上。
printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的
格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终
函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。
格式化数字字符串
sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代
itoa。如:
//把整数123 打印成一个字符串保存在s 中。
sprintf(s, "%d", 123); //产生"123"
可以指定宽度,不足的左边补空格:
sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"
当然也可以左对齐:
sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"
也可以按照16 进制打印:
sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一
种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。
sprintf(s, "%08X", 4567); //产生:"000011D7"
上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。
这里要注意一个符号扩展的问题:比如,假如我们想打印短整数(short)-1 的内存16 进制表
示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打
印它:
short si = -1;
sprintf(s, "%04X", si);
产生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个参数之外,后面的
参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈
时被压进来的到底是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,
导致参数压栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就把32 位整数
-1 的8 位16 进制都打印出来了。如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是
符号扩展(扩展时二进制左边补0 而不是补符号位):
sprintf(s, "%04X", (unsigned short)si);
就可以了。或者:
unsigned short si = -1;
sprintf(s, "%04X", si);
sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和16 进制都不会打
印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。
控制浮点数打印格式
浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保
留小数点后6 位数字,比如:
sprintf(s, "%f", 3.1415926); //产生"3.141593"
但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表
示打印的宽度,n 表示小数点后的位数。比如:
sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"
sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "
sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"
注意一个问题,你猜
int i = 100;
sprintf(s, "%.2f", i);
会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:
sprintf(s, "%.2f", (double)i);
第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i
相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,
于是可怜的保存整数i 的那4 个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。
不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手
工编排的结果是否正确。?
字符/Ascii 码对照
我们知道,在C/C++语言中,char 也是一种普通的scalable 类型,除了字长之外,它与short,
int,long 这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。(或许当年该把
这个类型叫做“byte”,然后现在就可以根据实际情况,使用byte 或short 来把char 通过typedef 定
义出来,这样更合适些)
于是,使用”%d”或者”%x”打印一个字符,便能得出它的10 进制或16 进制的ASCII 码;反过
来,使用”%c”打印一个整数,便可以看到它所对应的ASCII 字符。以下程序段把所有可见字符的
ASCII 码对照表打印到屏幕上(这里采用printf,注意”#”与”%X”合用时自动为16 进制数增加”0X”
前缀):
for(int i = 32; i < 127; i++) {
printf("[ %c ]: %3d 0x%#04X
", i, i, i);
}
连接字符串
sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连
接字符串,从而在许多场合可以替代strcat,但sprintf 能够一次连接多个字符串(自然也可以同时
在它们中间插入别的内容,总之非常灵活)。比如:
char* who = "I";
char* whom = "CSDN";
sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "
strcat 只能连接字符串(一段以’\0’结尾的字符数组或叫做字符缓冲,null-terminated-string),
但有时我们有两段字符缓冲区,他们并不是以’\0’结尾。比如许多从第三方库函数中返回的字符数
组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’\0’来结
尾。如果直接连接,不管是sprintf 还是strcat 肯定会导致非法内存操作,而strncat 也至少要求第
一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数
时可以指定宽度,字符串也一样的。比如:
char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
如果:
sprintf(s, "%s%s", a1, a2); //Don't do that!
十有八九要出问题了。是否可以改成:
sprintf(s, "%7s%7s", a1, a2);
也没好到哪儿去,正确的应该是:
sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"
这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空
格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字
符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:
sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"
在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是
静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种
动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一
个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一
样被提供出来,于是,上面的例子可以变成:
sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
或者:
sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:
sprintf(s, "%-*d", 4, 'A'); //产生"65 "
sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X
sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"
打印地址信息
有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32 位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:
sprintf(s, "%u", &i);
不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:
sprintf(s, "%08X", &i);
然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:
sprintf(s, "%p", &i);
我觉得它实际上就相当于:
sprintf(s, "%0*x", 2 * sizeof(void *), &i);
利用sprintf 的返回值
较少有人注意printf/sprintf 函数的返回值,但有时它却是有用的,spritnf 返回了本次函数调用
最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf 调用结束以后,你无须再调用一次
strlen 便已经知道了结果字符串的长度。如:
int len = sprintf(s, "%d", i);
对于正整数来说,len 便等于整数i 的10 进制位数。
下面的是个完整的例子,产生10 个[0, 100)之间的随机数,并将他们打印到一个字符数组s 中,
以逗号分隔开。
#include
#include
#include
int main() {
srand(time(0));
char s[64];
int offset = 0;
for(int i = 0; i < 10; i++) {
offset += sprintf(s + offset, "%d,", rand() % 100);
}
s[offset - 1] = '
';//将最后一个逗号换成换行符。
printf(s);
return 0;
}
设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字
符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat 效率高,因为strcat 每次调用
都需要先找到最后的那个’\0’的位置,而在上面给出的例子中,我们每次都利用sprintf 返回值把这
个位置直接记下来了。
使用sprintf 的常见问题
sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访
问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通
常用眼睛再把出错的代码多看几眼就看出来了。
?? 缓冲区溢出
第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问
题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。
?? 忘记了第一个参数
低级得不能再低级问题,用printf 用得太惯了。//偶就常犯。:。(
?? 变参对应出问题
通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤
其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”,编译器会觉得你
欺她太甚了(编译器是obj 和exe 的妈妈,应该是个女的,:P)。
strftime
sprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也
是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为
了在出现问题时可以推卸责任吧。这里举个例子:
time_t t = time(0);
//产生"YYYY-MM-DD hh:mm:ss"格式的字符串。
char s[32];
strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));
sprintf 在MFC 中也能找到他的知音:CString::Format,strftime 在MFC 中自然也有她的同道:
CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。
后记

下面是我收集的指针很好的文档,讲的很深入,楼主如果有兴趣,那么你可以看一下,如果不知道在哪里,你可以随时来问我。 。 。

第一章。的指针的概念

指针是一个特殊的变量,它的值存储在一个内存地址被解释为。

四个方面:类型,指针类型,指针所指向的,必须了解需要找出指针的指针,该指针的值,或者叫指针指向的内存区域,指针本身占据的内存区域。让我们分别说明。
站作为一个例子来声明几个指针:
示例:
(1)INT *;
(2)的char *指针;
(3)数组指针;
(4)INT(*)[3];
(5)诠释*(*)[4];

1。指针的类型。
语法的角度看,只要你删除的指针声明语句中的指针名,其余为指针类型。这是指针本身的类型。让我们来看看一个指针类型的例子:
(1)*指针/ /指针的类型诠释*
(2)的char *指针; / /指针的类型是char *
(3)*指针/ /类型的指针的数组
(4)INT(*)[3]; / /指针类型为int(*)[3]
(5)诠释*(*)[4]; /?? /指针的类型诠释*(*)[4]
怎么样?识别指针的类型的方法是不是很简单?

2。键入指针百分点。
当你通过指针来访问的指针所指向的内存区,指针所指向的类型的编译器,将修补的内存区域的内容看的东西。
在语法上,您需要到左边的是指针指向的指针的指针声明语句中的指针声明符*删除的类型的名称和名称。例如:
(1)*指针/ /指针指向int类型
(2)的char *指针; / /指针所指向的类型是char
(3)数组指针; / /指针指向的类型是int *
(4)INT(*)[3] / /指针指向int型()[3]
(5)诠释*(*)[4]; /?? /指针所指向的类型诠释*()[4]
指针运算,指针所指向的类型的显著作用。
的类型的指针类型(即,指针本身的类型)和指针指向两个概念。当你变得更加熟悉C,你会发现,“指针”类型混合在一起的概念转化为一种类型的“指针”和“指针所指向的类型”两个概念,重点精通指针之一。我读了很多书,发现一些不良写的书,把这两个概念指针搭配在一起,所以看看书不一致百思不得其解。

3。指针值,或所谓的区或地址的指针所指向的内存。
指针的值是指针本身所存储的值,并且该值作为地址,而不是一般的值将是编译器。 32个程序,所有类型的指针的值是一个32位的整数,因为所有的32个程序存储器地址是32位长。
指出由指针是从指针存储器地址,长度的sizeof(类型的指针所指向)的存储区域的值所表示的存储器区域。后来,我们说的指针的值是XX,相当于说的指针面积?存储器地址XX为首的,我们说一个指针块
内存区域是等效的指针的值是该存储区的第一地址。
的指针和该指针指向所指向的内存区域的类型是两个完全不同的概念。例如,指针所指向的类型了,但由于指针还未初始化,所以它所指向的内存区不存在,或者是毫无意义的。
每遇到一个指针后要问:是什么类型的指针?指针的类型是什么呢?在什么地方呢?
4。占用的存储器区域指针本身。
指针本身占了多大的内存?你只要用函数sizeof(指针类型)测试,以知道。在32位平台上,指针本身占据4个字节。
指针本身所占据的内存的概念是有用的,以确定是否一个指针表达式的左值。

第二章。指针的算术运算

指针可以是正或负的整数。此指针操作通常的数值减法的意义和重要性,是不一样的。例如:
例二:
1。的char [20];
2。诠释* =;
...
...
3。指针+ +;
在上面的例子中,int *类型的指针的指针,它指向的类型int,它被初始化为指向整型变量a。第三句的下一个指针,指针加1,编译器的方式来处理:值的指针的指针加的sizeof(int),在32位程序,再加上4。地址是字节,所以增加一个4字节的地址向高地址的指针变量的地址所指向的地址。
由于char类型的长度是一个字节,所以原来的指针四个字节起点的0号单元的阵列,这一次指向的数组a的从第4号单元开始的四个字节。
我们可以用一个指针和一个循环来遍历一个数组,看一个例子:
例三:
int数组[20];
诠释* =阵列;
...
/ /代码省略整数数组赋值。
...
(i = 0; <20; i + +)
{
(*)+ +;
指针+ +;
}
这种情况下,值的整数数组中的每个单元加1。每个周期的指针,指针加1,
给每个回路可访问的下一个单元的阵列。
看看这个例子:
示例:
1。的char [20];
2。诠释* =;
...
...
3。指针+ = 5;
在这个例子中,因此ptr +编译器这样的处理:指针指针加5倍的sizeof(int)的值,在一个32位的程序耦合用5×4 = 20。地址(以字节为单位)现在ptr指向的地址,以解决比指出,的指针加5至移动地址向高地址20个字节。在这个例子中,您没有添加前5 ptr指向数组中的第0号单元开始的四个字节,加5,ptr指向数组a的合法范围之外。虽然这种情况将问题中的应用,但是它的语法是可能的。这也反映了灵活性的指针。
上面的例子中,ptr是零下五,那么这个过程是大致相同的,不同的指针的值是零下5倍的sizeof(int),新的ptr指向解决比原来的指针指向的地址向低地址移动20个字节。

总结,一个指针ptrold与一个整数n,其结果是一个新的指针ptrnew,类型和ptrold ptrnew相同类型,指出的类型和ptrnew ptrold点的相同类型。 ptrnew的增加值比实际值的ptrold正一个sizeof(ptrold点式)的字节。也就是说,所指向的存储器区域的比sizeof(ptrold点的类型)的一个n字节的存储器区域移动到更高的地址ptrold点ptrnew。
后的指针ptrold减去一个整数n,导致一个新的指针ptrnew,ptrnew类型和ptrold所指向的类型和相同类型的ptrnew ptrold点的类型相同的。比减少ptrold的n值乘以者sizeof(ptrold点的类型)的字节,这就是说,为value ptrnew ptrnew比的存储器区域由ptrold移动指向朝向低地址所指向的内存区域的n sizeof(ptrold点式)的字节。

第三章。计算?放大器;

地址运算符,* ...书中被称为“间接的运算符。
及一个计算的结果是一个指针,指针类型是一个类型*指针指向的类型是一个类型,指针指向解决这个问题,那就是地址。
* P运算结果各不相同。短* P,P点的东西,这个东西有这些特点:它的类型是P点的类型,它占用的地址是由p指向的地址。
示例:
A = 12;
INT B;
* p;
数组指针;
P = &A; / /的结果,一个是指针类型是int *的点int类型的,地址指向的地址的。
* P = 24 ;/ / * p的结果,它的类型是int,它占用的地址是由p指向的地址,显然,* p是变量a。
PTR =即标准普尔/ /&P的结果是一个指针,指针的类型是P *的类型,在这里诠释
*。指针所指向的类型的p型,诠释*。该指针指向的地址的地址指针p。
* PTR = &B; / / * ptr是一个指针,&B的结果是一个指针,两个指针的类型和类型的点是一样的,所以和b来给* ptr指向的分配是没有问题的。
* PTR = 34 ;/ /结果是ptr ptr指向的东西,这里是一个指针,这是指
针再做一次*运算符,结果是一个int类型的变量。

第四章。指针表达式。

如果最后一个表达式的结果是一个指针,那么表达式被称为指针表达式。
下面是一些指针表达式的例子:
实施例6:
整数A,B;
int数组[10];
* PA;
PA = &A; / /&a是一个指针表达式。
数组指针= &pa; / /&pa是一个指针表达式。
* PTR = &B; / ~~ / *指针&B是指针表达式。
PA =阵列;
PA + + ;/ /这是一个指针表达式。
实施例7:
字符*改编[20];
字符**帕尔改编;/ / ARR为指针,arr是一个指针表达式
字符*海峡;
STR = *帕尔帕尔;/ / *指针表达式
海峡= *(幼鱼+1);/ / *(幼鱼+1)是一个指针表达式
海峡=(帕尔+2);/ / *(帕尔+2)是一个指针表达式

作为结果的指针的表达是一个指针的指针具有四个要素:类型的指针,该指针指向指针本身的存储器指针表达式所占用的存储区的指针的类型。
那么,当一个指针表达式的结果是已经明确的指针的指针本身所具有的指针表达式所占用的内存是一个左值,否则就不是一个左值。
7&A的案件是不是一个左值,因为它不占据了清晰的记忆。 * ptr是一个左值*指针的指针已经占用的内存,其实* ptr就是指针PA PA具有自己的内存,那么* ptr当然也有它自己的位置。

第一章。数组和指针之间的关系

如果该语句声明一个数组不太了解,前一段时间发布的文字我吗? LT; <如何理解复杂的类型声明>> C和C + +。
数组的数组名其实也可以看作是一个指针。看下例:
实施例8:
int数组[10] = {0,1,2,3,4,5,6,7,8,9},值;
...
...
值=数组[0] ;/ /也可以写为:价值= *阵列;
值=阵列[3] ;/ /也可以被写为:值= *(阵列3);
值=阵列[4] ;/ /也可以被写为:值= *(阵列4);
在上面的例子中,一般的数组名的数组代表数组本身,类型为int [10],但如果
rray被看作是一个指针,它指向数组的0个单位,int *类型的点的数组类型是整数类型的单元。 *等于0的数组,这并不奇怪。同样,阵列3是一个指针到的前三个单元的数组的指针,所以*(阵列3)等于3。等等。
实施例9:
字符*海峡[3] = {
“你好,我是一个样!”
“嗨,早上好”。
“世界您好”
};
个char [80];
的strcpy(,str的[0]);/ /也可写成像strcpy(*海峡);
的strcpy(,str的[1]);/ /也可写成像strcpy(*(海峡+1));
的strcpy(,str的[2]);/ /也可写成像strcpy(*(海峡+2));
另外,在上述的例子中,str是一个三单元阵列,阵列的每个元素是一个指针,这些指针分别指向一个字符串。的数组名str的指针的指针,它指向数组第0号单元,它的类型是char **,它指向的类型是char *。
* str是一个指针,它的类型是char *,它指向的类型是char,它指向的地址的字符串“您好,这是一个简单的,”第一个字符的地址,'H'的地址。
STR +1是一个指针,它指向数组的1号单元,它的类型是char **,它指向的类型是char *。
*(STR +1)是一个指针,它的类型是char *,它指向的类型是char,它指向“嗨,早上好。”的第一个字符“H”,依此类推。

下面总??结的名称的数组的数组。声明一个数组类型的数组的数组名数组[N],有两方面的含义:第一,它代表整个数组,它的类型是TYPE [N];其次,它是一个指针的指针类型TYPE *指针类型类型,这是一个数组单元的类型,指针指向的内存区域的单位是一个阵列0号,这个指针占用一个单独的内存区,注意,数组的0个单位占用内存区域是不同的。指针的值不被,这是类似于数组+ +表达式是错误的。
数组名数组可以扮演不同的角色,在不同的表达式。
表达式sizeof(数组),数组名数组代表数组本身,所以这个时候sizeof函数
测量得到的整个阵列的大小。
表达式*数组,数组中起着指针,所以此表达式的结果是数组的第0号单元的值。测量的大小(*数组)的数组元素的大小。
表达阵列+ N(其中n = 0,1,2,...),阵列发挥是一个指针,所以改编
AY + n的结果是一个指针类型TYPE *,它指向的类型TYPE,它指向数组的第n个单元。因此中,sizeof(数组+ n)的测量的指针类型的大小。
实施例10:
int数组[10];
(*)[10];
PTR = &array;
例如ptr是一个指针,它的类型是int(*)[10],他指出,输入数据类型为int [10]
我们用整个数组的首地址来初始化它。声明指针和数组,该数组代表数组本身。

本节中,sizeof()函数,然后我来问sizeof(指针名字)的实测研究
实际上的指针所指向的类型的指针类型或尺寸的大小?答案是前者。例如:

(*)[10];
在32位程序,主要有:
如sizeof(int(*)[10])== 4
SIZEOF([10])== 40
sizeof(指针)的== 4
事实上,sizeof(对象)的测量对象类型的大小,而不是任何类型的大小。

第六章。指针和结构的关系的类型

你可以声明一个指向结构类型对象的指针。
实施例11:
结构mystruct
{
诠释一;
INT B;
诠释三;
}
MyStruct SS = {20,30,40} ;/ /声明结构体SS,和ss的三个成员的初始
成20,30和40。
MyStruct * = &ss; / /声明一个指针,指向一个指针,指向一个结构体SS。它的类型是
MyStruct *,它指向的类型MyStruct。
* PSTR(*)&ss; / /声明一个指针,指向一个指针,指向一个结构体SS。但是,
类型和PTR类型和它是不同的。

如何可以通过一个指针PTR SS三个成员变量?
答:
PTR-> A;
PTR-> B;
PTR-> C;
请问如何访问SS三个成员变量的指针PSTR?
答:
* PSTR ;/ /获取的党卫队成员。
*(PSTR 1);/ / b的党卫队成员。
*(PSTR 2)/ /访问C SS的成员。
虽然我在我的MSVC + +6.0上调代码,但要知道,这样使用p
str的访问结构的成员是非正式的,为了解释为什么非正式的,让我们来看看如何通过指
针访问的各种元素的数组:
实施例12:
int数组[3] = {35,56,37};
* PA =阵列;
访问数组的数组的指针PA三个单位的方法:
* PA ;/ /浏览0件
*(PA +1);/ /获取第1个单位
*(PA +2);/ /获取的2号机组
从格式上来看,倒是格式的形式化方法,通过指针访问结构成员。
所有的C / C + +编译器总是安排阵列单元,每个数组元素存储在连续的存储区域,单位和单位之间没有空隙。然而,在存储的各个成员对象的结构,在一个特定的编译器环境中,可能需要字对齐或双字对齐,对齐两个相邻的成员之间加上一定的吗? “填充字节此引线可能之间的间隙的各个成员的字节的数目
因此,在12例PSTR的一个成员变量的对象SS A的结构,不能保证*(PSTR 1)将能够访问结构的成员。因为可能有一些成员之间的成员的b可能*(PSTR 1),只是访问这些填充字节的填充字节。这也证明了指针的灵活性。如果你的目的是想看看在成员之间的各种结构到底有没有填充字节
嘿,这的确是一个好办法。
指针来访问正确的结构应该是这样的方法使用指针的指针例1??2。

第七章。指针和功能之间的关系的

你可以声明一个指针,一个指向函数的指针。
诠释FUN1(char *,则INT);
(* pfun1)(char *,则INT);
pfun1 = FUN1;
....
....
=(* pfun1)(“ABCDEFG”,7);/ /通过函数指针调用函数。
作为一个参数的函数的指针。函数调用语句,您可以使用指针表达式
参数。
实例13:
有趣的(char *)的;
诠释一;
字符海峡[] =“ABCDEFGHIJKLMN”;的
=乐趣(STR);
...
...
有趣的(字符*)
{
NUM = 0;
为(int i = 0;
{
NUM + = * S,S + +;
}
返回num;

在这种情况下,函数fun统计一个字符串中的单个字符的ASCII值。正如所述,该数组的名称是一个指针。函数调用时,str作为一个参数传递给正式的参数s,str的实际价值传递给S,S点到相同的地址,指向的地址,将str,str和s各自占用各自的存储空间。在函数体内的自我加1操作,并不意味着运营商的自我强加给乙方。

第八章。指针的类型转换

当我们初始化一个指针,指向一个指针赋值,赋值是一个指针向左,右侧的一个指针表达式中的分配。在我们以前的例子,在绝大多数情况下,指针和指针类型的表达式的类型是一样的,指针所指向的类型和指针表达式的类型是一样的。
例十四:
1。浮动f = 12.3;
2。浮* fptr,实施的代码如下= &f;
3。 * p;
在上面的例子中,如果我们想让指针p指向的实数f,怎么搞的?用下面的语句吗?
P = &f;
这是错误的。由于类型的指针p是对int *,它指向的类型是int。表达式&f的结果是一个
一个指针,指针的类型是float *,它指向float类型。两者之间的差别,直接分配。至少在我的MSVC + +6.0指针赋值语句要求的类型,赋值号两侧的线,点,线的类型,我还没有尝试过其他的编译器,大家可以试试。为了实现我们的目标,“中投”:
P =(*)&f;如果有一个指针p,我们需要的类型,其类型,并指出,而不是TYEP * TYPE
语法格式是:
(TYPE *)P;
这样的结果蒙上了新的指针,指针类型TYPE *,它指向的类型TYPE,它指向的地址是原来的指针的地址。原始指针p的所有属性都没有被。

如果您使用一个函数指针作为参数,然后指针类型的转换也发生在结合过程中的参数和参数的函数调用语句。
例五:
无效的乐趣(char *)的;
A = 125,B;
有趣的((CHAR *)&A);
...
...
无效乐趣(字符* S)
{
字符c;
C = *(3)*(+3)= *(+0)*(+0)= C;
= *(2)*(2)= *(1)*(1)= C;
}
}
请注意,这是一个32位程序,故int类型占四个字节的char类型占一个字节。的功能的乐趣的作用是一个反相的整数的四个字节的顺序。注意到了吗?函数调用语句的参数,结果和a是一个指针,它的类型是int *,它指向的类型是int。参数指针的类型是char *,它指向的类型是char。实时参和形参的结合过程中,一定要进行一次从int *类型转换为char *类型。结合这个例子,我们可以想像,编译器将其转换的过程:编译器先构造一个临时指针的char *温度,然后做TEMP =(CHAR *),最后的温度值传递到S。因此,最后的结果是:s类型是char *,它指向的类型是char,它指向的地址的第一个地址是一个。

我们已经知道,在32位程序的值是一个指向指针的地址的指针的值其实是一个32位的整数。整数指针的指针的值直接吗?下面的语句:
unsigned int类型;
TYPE * ;/ / TYPE类型为int,char或结构类型,等等。
...
...
A = 20345686;
PTR = 20345686 ;/ /我们的目标是使指针ptr指向地址20345686(十进制

PTR = ;/ /我们的目标是使指针ptr指向地址20345686(十进制)
编译它。结果表明,后者的两个语句都是错误的。不能达到我们的目的?不,有办法:
unsigned int类型;
TYPE * ;/ / TYPE类型为int,char或结构类型,等等。
...
...
=一个数字,这个数字必须代表一个合法的地址;
PTR =(TYPE *);/ /这个可以。
严格来说,是不一样的(TYPE *)指针类型转换(类型*)。 (TYPE *)的意思是无符号整数的值作为地址以寻找。
上文所强调的,必须代表一个合法的地址,或当您使用指针的值,会有一个非法操作错误。

想到的就可以了,反过来,以指针的地址的指针值作为整数。完全。下面的例子演示了作为一个整数的指针的值,那么这个整数作为地址分配给一个指针:
例十六:
A = 123,B;
诠释* = &A;
字符*海峡;
B =(int)的指针;/ /指针的指针的值作为整数。
海峡=(CHAR *)B ;/ /这个整数的值作为地址指针海峡。

好了,我们已经知道,值的指针作为一个整数取出来,也可以被分配到一个指针,指向的地址的整数值。

第九章。指针的安全问题

请看下面的例子:
实施例17:
个char ='A';
诠释*;
PTR =(*)&S
* PTR = 1298;
指针ptr是一个int *类型的指针,它指向的类型是int。它指向的地址的地址。 S共享一个32位的程序中的一个字节,int类型占4个字节。的最后一条语句不但改变字节的份额也高地址方向和S相邻的三个字节改变。三个字节都在干什么?只有编译器知道,而写程序,就不大可能知道。一个很重要的数据可以存储在三个字节,可能是三个字节只是程序代码指针的马虎应用的三个字节的值被改变!这将导致错误的崩溃。
让我们看一个案例:
实施例18:
1。字符;
2。诠释* = &A;
...
...
3。指针+ +;
4。 * PTR = 115;
这个例子完全可以通过编译,并可以执行。但是看到的不是吗? 3句,因为加1操作,ptr指向的存储区域相邻的地址和整型变量的指针的指针的方向。这家商店是什么呢?我们不知道。可能是它是一个非常重要的数据,甚至可能是一个代码。甚至数据写入到这家店!这是一个严重的错误。指针,程序员心里必须非常清楚:我的指针指向哪里。
访问数组指针,我们必须小心,不要超出边界的数组的低端和高端否则会造成类似的错误。
指针类型的强制转换:PTR1 =(TYPE *)PTR2,的大小(PTR2为类型)
SIZEOF(ptr1的类型),那么它是安全的,,在使用指针PTR1,访问指向的存储区时的PTR2。如果小于sizeof(ptr1和类型)的大小(PTR2类型)时,在使用指针PTR1,访问指向的存储区,PTR2是不安全的。至于为什么,读者结合例17去想它,它应该被理解。

(1)main函数中的 char*informationDatee[40]表示的是字符串指针数组,根据上下文,你应该改成char*informationDatee。
(2)horadatage函数中的变量buf不应该被返回,因为它是局部变量,return后内存被释放,这样在main中它就不能被访问了你应该把它声明为:int horadatage(char*infoADater,char*infoDatee, char *buf); 返回0表示函数执行成功,-1表示失败。buf参数用以保存函数执行结果。

根据代码的意思是想给一个输入语句加上UTC时标是吧?
那 改成这样
void main()
{
void horadatage(char*infoADater,char*infoDatee);
char*information="La chaine d`information";
char informationDatee[40] = “”;

horadatage(information,informationDatee);

printf("L\'info datee est %s\n", informationDatee);
}
void horadatage(char*infoADater,char*infoDatee)
{
time_t t;

t=time(NULL);
infoDatee=ctime(&t);
//printf("%s\n",infoDatee);
sprintf(&infoDatee[strlen(infoDatee)], ":%s\n", infoADater);

return ;
}

这样就行

lxm2322回答得很好了,另外 sprintf函数的作用仅是把字符串格式化好以后放入一个缓冲区,没啥恐惧不懂的

弄得整齐一些,你这样弄这么乱谁看的清楚


C语言求教。一个小小的编程问题,在线等
数控车床编程100例图 编程是解决问题的吗 手机编程 plc编程 其他类似问题2015-06-05 求问C语言编程问题,在线等!!! 2 2015-04-27 C语言编程题求教!!在线等,谢谢大家了。 2014-06-02 c语言编程问题,在线等。 1 2015-02-14 C语言小程序的一个小问题,在线等 ··· 2016-01-23 C语言编程问题,...

C语言编程问题 急!判断上三角矩阵 求帮助看哪一步出错就好
首先说下你错在哪里:从上图可以看出来是每一次循环计算一次结果,所我的想法是使用数组去记录每次结果,后再打印,代码如下:include <stdio.h>#include <math.h>#include <stdlib.h>int main(void){int ri, repeat;int n, i, j;int flag[2] = {0};int a[6][6];scanf_s("%d", &repeat...

c语言编程,哪错了?下面有题目
include<stdio.h>int main(){int i,e,m,n;char b[40];scanf("%c",&b[i]);\/\/ i 是乱码。没有赋初始值。且b[i]是一个char类型,获取的值一直被丢在同一个位置\/\/应该用\/*for(i = 0;scanf("%c",&b[i])&& i < 40;i++){ if(b[i] == '#') break;}*\/for(e...

一个关于c语言的编程问题?
include <stdio.h> include <stdlib.h> struct student { int num;char name[20];float score[4];};void input(struct student a[], int);void aver(struct student a[], int,struct student b[]);void order(struct student a[], int);void output(struct student a[], int,struct ...

这道题C语言编程题我有一个测试点总是通不过,请问我错在哪?
程序没问题啊,能正常输出:你说的通不过,是编译器报的错吗?附了一个代码,是一次性输入之后,然后一次性依次每行输出:include<stdio.h> include<stdlib.h> int main(){ int N;int height, weight;int i;double standard;scanf("%d", &N);int *data = (int*)malloc(2 * N * sizeof...

大学学习编程最容易遇到的误区
自学编程学习编程容易遇到的六大致命误区 1.追求热门 所谓基础不牢,地动山摇啊。可很多小伙伴压根就没注意过这个问题,市面上出什么新鲜的技术就想去尝试,结果把自己学的乱七八糟,心灰意冷。 学习是个漫长的过程,小伙伴们在学习一门语言的初期,一定要从基础开始,不要着急,时髦的东西咱把基础夯实以后再来吃,不然...

学习编程语言时需要考虑哪些因素?
3、软件执行的环境 良好的编程环境不但能有效提高软件生产率,同时能减少错误,有效提高软件质量。4、算法和数据结构的复杂性 科学计算、实时处理和人工智能领域中的问题算法较复杂,而数据处理、数据库应用、系统软件领域的问题,数据结构.比较复杂,因此选择语言时可考虑是否有完成复杂算法的能力,或者有...

C语言编程问题,求两数之和、差、积;调用,指针(帮忙看看我的程序哪错...
int process(int *a,int *b){ char i;int j;printf("请输入您想要的计算(+\/-\/*):");getchar(); \/\/要把之前输入两个数时按的回车给过滤掉 scanf("%c",&i);if(i=='+') \/\/字符比较用不着strcmp { j=add(a,b);return j;} if(i=='-'){ j=sub(a,b);return j;} if(i...

求大神C语言编程,题目要求在下面
问题一:关键在输入字符和字符串要避开回车及空格分隔符。这里可以用getchar解决。问题二:就是让你函数调用。问题三:依然是函数调用,但需要函数1返回值或传递地址。至于数字字符转整型,大小写转换,都利用ascii码的差值来转换。下面是我的代码,三个函数分别对应三个问题。include<stdio.h> define ...

c语言问题 图中编程哪错了
请在poi代码的时候,顺手贴上编译器的错误提示,这样会提高纠错效率~~~目测的错误有:1: main函数定义的返回值是int,但是在实现中却木有return;2: s[81]木有初始化,最开始的时候,S【81】中的字符全是乱码的,会导致第13行的*p的判断无效;3: 14行的逻辑有些问题,应该是if( '*...

睢宁县17837325633: c语言指针编程的问题,不知道哪里错了,求解答!
柏别派林: #include voidmain() { intx[10],*px,y,*py=&y; for(px=x;px*px) 1?(*(px+1)=*px,px--):(*(px+1)=*px--);//出这道题的是白痴么,求值顺序,副作用都不懂么,要是写成*(px+1)=*px--那还了得!!! *(px+1)=*py; for(px=x;pxprintf("%3d",*px); printf(" "); }

睢宁县17837325633: 一道C语言指结构指针的问题,不知哪错了,有三个错误,请高手帮忙修?
柏别派林: 编译是没有问题,但你代码有错误.1.void output (SCORE*p,int n) { int i; printf("\n%s%5s%5s%5s","Number","Engl","Math"); 上句少一个参数.格式符有4...

睢宁县17837325633: 帮我看下这个C语言程序 哪里出错了 -
柏别派林: 指针p的用法,全程很多错误.指针在使用之前,要先赋值,并指向正确的位置. #define N 3#include "stdio.h"typedef struct { int num; char name[10]; char sex; in...

睢宁县17837325633: C语言指针刚刚学,请大佬帮忙看看这个问题出在哪里了,然后麻烦给解释一下.感谢感谢 -
柏别派林: 倒数第三行函数调用错了不能*m,而是m;上图这样写是让函数指向了一个m的地址值,而不是m的值;

睢宁县17837325633: C语言 指针返回值问题 我的程序哪儿出错了 望高手解决下 谢谢 -
柏别派林: 你是想修改max和min的值吧.你程序没什么大问题.不过有一点需要注意一下.int fun(int a[3][4],int *min,int *max)函数声明要求返回一个int型的值.fun...

睢宁县17837325633: C语言指针的小问题, 出现段错误,求分析,感激不尽,代码如下 -
柏别派林: static char *i,*ant; //定义字符指针,*i,*ant指针,指向常量,也就是里面的内容不容许再次修改了i="asdf"; //赋值,...

睢宁县17837325633: c语言应该是指针出问题了但找不到具体原因,在vc下运行编译没问题但运行就出错, -
柏别派林: while(*p!='\0'){*q=*p;q++;i++; //没看出来这句代码有什么用} 你最后是要输出q, q的类型是指向字符的指针而不是指向字符串的指针, 你每次都把p的值赋值给q而前一个值会被覆盖, 最后的结果应该会是输出'k'吧 while(*p!='\0'){*q=*p;q++;printf("复制后的字符%s\n",q);} 解决的办法就是每将一个值赋给q就将其输出, 因为这个循环会在p所指向的值为空字符的时候结束, 所以也就会输出以p所指向的位置开头的字符串 没问题的话请采纳谢谢w

睢宁县17837325633: c语言,链表,内存出错 -
柏别派林: 这是使用C语言指针编程时经常会遇到的一个问题..原因是你的指针变量指向了代码区或者其它程序的内存区域..仔细检查自己的程序看哪个指针操作写错了.

睢宁县17837325633: C语言指针问题,看看我写的程序错哪了? -
柏别派林: 简单帮你看一下有两个大问题,第一个主函数的scanf,由于p自增,循环永远不止,第二个就是remove中pa没有自增,所以一直再换相同的数,你自己看着改吧 ,还有一个大问题,你用浮点数,确输入整形,结果总是0,基本上就是这些问题,祝你进步

睢宁县17837325633: C语言 数组指针赋值出错 -
柏别派林: char *string[20];这样声明的是一个名为string的数组,这个数组有20个元素,每一个元素都是一个char *型指针.所以数组里存放的是“指针”,只是个4字节变量,它还没有指向,就不能用string[i][j]='\0';这种办法给它的指向目标赋值.要么直接把char *string[20];改成char string[20][100];(可以存放20个长99的字符串),要么在char *string[20];后用malloc等函数分别为20个指针分配空间.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网