⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c++错误.txt

📁 次文档收集列出了平时在编写c++程序时出现的一些编译错误
💻 TXT
📖 第 1 页 / 共 5 页
字号:
x = 5;
y1 = x++ * x++;
y2 = ++x * ++x; 

此时y1的值为25,y2的值为49

7.        printf
l        考法1
x = 11, y = 10;
printf(“%d, %d”, (x++, y), y++); 

输出结果:11,10
解析:
1)        printf函数按参数从右到左顺序进行分析
y++ -> x++ -> y 
|               |
        10,后y变11     11
2)        分析结束,输出顺序是从左到右;即:11, 10
l        考法2
printf(“%4s”, “abc”);   // 输出结果  (空格)abc
printf(“%-4s”, “abc”);  // 输出结果   abc(空格)
printf(“%4s”, “abcde”); // 输出结果   abcde
printf(“%9.3f”, 12.3456); // 输出结果  1.234e+01

8.        scanf
scanf(“%7.2f”, &a);  // 错,不能规定精度
scanf(“%3d”, &a);   // 正确
scanf(“%d:%d”, &a, &b);  // 输入格式:(整数):(整数)   例  12:34
scanf(“%3c”, &ch);       // 正确。但是ch只取输入字符中的第一个字符
                                            // 例:输入abc,则ch值为’a’

9.        注意switch中的break

10.    while (a = 1) { … } // 注意这里是赋值号

11.    for( x = 0, y = 3, i = 0; (y > 3)&&(x < 4); x++, y++ )  i++;
运行结果 i = 0
解析:for循环运行过程 表达式1->表达式2-> 循环体->表达式3

12.    数组
int a[10] = {0, 1, 2, 3}  // 正确。前四个元素赋值,后6个元素全为0

int a[2][2] = {1,2,3,4}  // 正确 
int a[ ][2] = {1,2,3,4}   // 正确。第一维可以省略
int a[2][ ] = {1,2,3,4}   // 错误。非第一维不能省略

13.    预处理
定义宏:#define s(x) x*x
表达式 s(a+b) 宏展开为: a + b*a + b 

定义宏:#define s(x) (x)*(x)
表达式 s(a+b) 宏展开为: (a + b)*(a + b)

14.    指针
l        若定义: int a[10], *p;  p = a;
则: a + i  是地址
*(a+i)  是地址a + i的内容
l        数组是指针
*(a+i) 和 *(p+i) 是等价的
a[i] 和 p[i]是等价的
l        字符串也是指针
若定义: char *sp = “bug”;
                char s[] = {‘b’,’u’,’g’};
则: s与sp是等价的

15.    函数
l        值传递:
Void swap1(int a, int b)
{
int c = a;
a = b;
b = c;
}
void main()
{
int x = 1, y = 2;
swap1(x, y);
printf(“%d, %d”, x, y);
} 

程序运行输出结果:1,2   
可见x与y变量的值没有交换
l        地址传递:
Void swap2(int *a, int *b)
{
int *c = a;
*a = *b;
*b = *c;
}
void main()
{
int x = 1, y = 2;
swap1(&x, &y);
printf(“%d, %d”, x, y);
} 

程序运行输出结果:2,1   
可见x与y变量的值实现了交换

 

 

http://www.topice.net/Html/c/2006-6/9/145210397.html

水滴石穿C语言之指针、数组和函数
作者:佚名    来源:网络    日期:2006-3-30 

 
  基本解释

  1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。

  2、数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。

  3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。 

  问题:指针与数组

  听说char a[]与char *a是一致的,是不是这样呢?

  答案与分析:

  指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。请看以下的例子:
char a[] = "Hi, pig!";
char *p = "Hi, pig!";


  上述两个变量的内存布局分别如下:

  数组a需要在内存中占用8个字节的空间,这段内存区通过名字a来标志。指针p则需要4个字节的空间来存放地址,这4个字节用名字p来标志。其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。目前这个p指向某地连续的8个字节,即字符串“Hi, pig!”。

  另外,例如:对于a[2]和p[2],二者都返回字符‘i’,但是编译器产生的执行代码却不一样。对于a[2],执行代码是从a的位置开始,向后移动2两个字节,然后取出其中的字符。对于p[2],执行代码是从p的位置取出一个地址,在其上加2,然后取出对应内存中的字符。

  问题:数组指针

  为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?如何定义?

  答案与分析:

  使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的优点,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在高维需要动态生成情况下的多维数组。

  定义例子如下: int (*pElement)[2]。

  下面是一个例子: 
int array[2][3] = {{1,2,3},{4,5,6}};
int (*pa)[3]; //定义一个指向数组的指针 
pa = &array[0]; // '&'符号能够体现pa的含义,表示是指向数组的指针
printf ("%d", (*pa)[0]); //将打印array[0][0],即1 
pa++; // 猜一猜,它指向谁?array[1]?对了!
printf ("%d", (*pa)[0]); // 将打印array[1][0],即4


  上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。

  需要说明的是,按照我们在第四篇讨论过的,指针的步进是参照其所指对象的大小的,因此,pa++将整个向后移动一个数组的尺寸,而不是仅仅向后移动一个数组元素的尺寸。

  问题:指针数组

  有如下定义:
struct UT_TEST_STRUCT *pTo[2][MAX_NUM];

 

  请分析这个定义的意义,并尝试说明这样的定义可能有哪些好处?

  答案与分析:

  前面我们谈了数组指针,现在又提到了指针数组,两者形式很相似,那么,如何区分两者的定义呢?分析如下:

  数组指针是:指向数组的指针,比如 int (*pA)[5]。

  指针数组是:指针构成的数组,比如int *pA[5]。

  至于上述指针数组的好处,大致有如下两个很普遍的原因:

  a)、各个指针内容可以按需要动态生成,避免了空间浪费。

  b)、各个指针呈数组形式排列,索引起来非常方便。

  在实际编程中,选择使用指针数组大多都是想要获得如上两个好处。

问题:指向指针的指针

  在做一个文本处理程序的时候,有这样一个问题:什么样的数据结构适合于按行存储文本?

  答案与分析:

  首先,我们来分析文本的特点,文本的主要特征是具有很强的动态性,一行文本的字符个数或多或少不确定,整个文本所拥有的文本行数也是不确定的。这样的特征决定了用固定的二维数组存放文本行必然限制多多,缺乏灵活性。这种场合,使用指向指针的指针有很大的优越性。

  现实中我们尝试用动态二维数组(本质就是指向指针的指针)来解决此问题:

  图示是一个指针数组。所谓动态性指横向(对应每行文本的字符个数)和纵向(对应整个文本的行数)两个方向都可以变化。

  就横向而言,因为指针的灵活性,它可以指向随意大小的字符数组,实现了横向动态性。

  就竖向而言,可以动态生成及扩展需要的指针数组的大小。

  下面的代码演示了这种动态数组的用途:
// 用于从文件中读取以 '\0'结尾的字符串的函数
extern char *getline(FILE *pFile);
FILE *pFile;
char **ppText = NULL; // 二维动态数组指针 
char *pCurrText = NULL; // 指向当前输入字符串的指针
ULONG ulCurrLines = 0;
ULONG ulAllocedLines = 0;

while (p = getline(pFile))
{
 if (ulCurrLines >= ulAllocedLines)
 {
  // * 当前竖向空间已经不够了,通过realloc对其进行扩展。
  ulAllocedLines += 50; // 每次扩展50行。 
  ppText = realloc (ppText, ulAllocedLines * (char *));
  if (NULL == ppText)
  {
   return; // 内存分配失败,返回 
  }
 }
 ppText[ulCurrLines++] = p; // 横向“扩展”,指向不定长字符串 
}


  问题:指针数组与数组指针与指向指针的指针

  指针和数组分别有如下的特征:

  指针:动态分配,初始空间小

  数组:索引方便,初始空间大

  下面使用高维数组来说明指针数组、数组指针、指向指针的指针各自的适合场合。

   多维静态数组:各维均确定,适用于整体空间需求不大的场合,此结构可方便索引,例a[10][40]。

   数组指针:低维确定,高维需要动态生成的场合,例a[x][40]。

   指针数组:高维确定,低维需要动态生成的场合,例a[10][y]。

   指向指针的指针:高、低维均需要动态生成的场合,例a[x][y]。

  问题:数组名相关问题

  假设有一个整数数组a,a和&a的区别是什么?

  答案与分析:

  a == &a == &a[0],数组名a不占用存储空间。需要引用数组(非字符串)首地址的地方,我一般使用&a[0],使用a容易和指针混淆,使用&a容易和非指针变量混淆。

  区别在于二者的类型。对数组a的直接引用将产生一个指向数组第一个元素的指针,而&a的结果则产生一个指向全部数组的指针。例如:
int a[2] = {1, 2};
int *p = 0;
p = a; /* p指向a[0]所在的地方 */
x = *p; /* x = a[0] = 1*/
p = &a; /* 编译器会提示你错误,*/
/*显示整数指针与整数数组指针不一样 */


  问题:函数指针与指针函数
 
  请问:如下定义是什么意思:
int *pF1();
int (*pF2)(); 


  答案与分析:

  首先清楚它们的定义:

   指针函数,返回一个指针的函数。

   函数指针,指向一个函数的指针。

  可知:

   pF1是一个指针函数,它返回一个指向int型数据的指针。

   pF2是一个函数指针,它指向一个参数为空的函数,这个函数返回一个整数。

 

 

http://www.jys.cdut.edu.cn/clanguage/clanguagegeneral/ziy/fudaozl/Cerr.htm

C源程序常见错误分析
 

一、C语言出错有两种情况:

1、语法错误。指编程时违背了C语法的规定,对这类错误,编译程序一般都能够给出“出错信息”,并且告诉在哪一行出错及出错的类型。只要仔细检查,是可以很快发现错误并排除的。

2、逻辑错误。程序并无违背语法规则,但程序执行结果与原意不符。这是由于程序设计人员写出的源程序与设计人员的本意不相同,即出现了逻辑上的混乱。

例如:

unsigned char i=1;

unsigned int sum=0;

while (i<=100)

    sum=sum+i;

    i++;

在上例中,设计者本意是想求从1到100的整数和,但是由于循环语句中漏掉了大括号,使循环变为死循环而不是求累加。对于这种错误,C编译通常都不会有出错信息(因为符合C语法,但有部分编译系统会提示有一个死循环)。对于这类逻辑错误,比语法错误更难查找,要求程序设计者有丰富的设计经验(不会有类似的错误)和有丰富的排错经验(通过仿真能够很快发现问题)。

二、初学者在编写C源程序时常见错误及分析

1、忘记定义变量就使用

例如:

main ()

{

x=3;

y=x;

}

在上式中看似正确,实际上却没有定义变量x和y的类型。C语言规定,所有的变量必须先定义,后使用。因此在函数开头必须有定义变量x和y的语句,应改为:

main ()

{

int x,y;

x=3;

y=x;

}

2、变量没有赋值初就直接使用。(似乎编译时不会自动初始化,没有赋值时会是产生一个不确定的值,全局变量除会自动初始化)

例如:

unsigned int addition (unsigned int n)

{

unsigned int i;

unsigned int sum;

for (i=0;i<n;i++)

sum+=i;

return (sum);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -