分类: C语言
[笔记]VS2017 char *p=“”不可用的解决办法
起因:
今天在做c语言的功课时,发现旧的教材(基于vc++6.0)使用了如下的代码,对字符串指针进行赋值.
char *p="Hello World";
但是编写到VS2017上时报了下面的一个错误.
直接导致编译失败,经过了baidu的查找后,知晓了具体原因.
解决办法:
应把源代码修改成如下的代码.
//原代码 char *p="Hello world"; //修改后的代码 const char *p="Hello world";
主要原因是因为在新版本中增强了对字符串指针的安全性,通过使用静态声明,来防止越界
[笔记][C语言]指针学习小结[20181206]
C语言学习小结:
指针的初始化
指针变量可以初始化为0,NULL或一个地址[16进制]
0和NULL等价,相当于一个空地址
//使用(变量类型 *变量名)这样一个组合就可以声明一个指定类型的指针变量 int *a;
- 指针变量就是用来存储变量地址的一种变量
- 指针的存储的地址指的是该变量的起始位置
指针运算符
- *指针运算符,用于把指针指向变量,可用于获取变量的值
- &取址运算符,用于获取变量的地址
- *(&a)和&(*a)的效果相同,都是获取变量的地址,只是处理的次序不同
例子:
#include <iostream> int main(){ int *a,i=100; printf("a的位置%p,i的值:%d\n",a,i); a=&i; printf("a的位置%p,a的值是%d\n",&a,*a); }
运行结果:
为什么要指定指针变量的类型?
指针变量不仅仅是要存储变量的地址,同时也要记录变量的空间大小。
因为C语言传递变量时需要把数据传入已确定的内存地址及其所占的空间,
所以一个char类型的指针不可以直接指向一个int型的变量,如果强制操作将会导致越界的bug。
指针偏移:
#include <iostream> void main() { int *a[3];//初始化整型指针 int b[3] = { 1,2,3 }; a[0] = &b[0];//将b[0]的地址赋值给a[0]存储 a[1] = &b[1]; a[2] = &b[2]; printf("a的原来指向的值%d\n", **a);//*a仅仅是获取到b的地址,**a才是获取到b的值 printf("a的变化后指向的值%d\n", **(a+1));//a+1指的是a[1]然后再重复上一行的操作 }
指针指向多维数组
#include <iostream> void main(){ int a[3][3]={1,2,3,4,5,6,7,8,9}; int *b[3]; b[0]=a[0];//在多维数组中,b[0]=a[0]会自动指向a[0]的地址,不用像一维数组,使用取址符指向a[0] b[1]=a[1]; b[2]=a[2]; printf("a[1][2]的值%d\n",*(*(b+1)+2));//现将b指向b[1],然后将b[1]指向b[1][2] }
为啥指针指向一维数组时,需要使用取址符,但是指向多维数组时的第一维时不用取址符?
因为指针指向一维数组时,b[0]代表的是一个值,而不是一个地址,所以需要使用取址符来获取这个值得地址,
但是当指针指向二维数组时,b[0]的身份是一个地址,所以就不用使用取址符就可以直接获取到地址了。
One More Thing
数组p[i]是c语言中的一种语法糖
即使函数被设计成void fun(int array[5], int n),array依然被看成是指针。也就是说即使数组带了长度,该长度也会被编译器忽略掉。(即:a[i]=>*(a+i))
一句话:形参中的数组统统看成指针。
既然如此,还不如直接写成void fun(int *array, int n)。指针的形式,更能表达本意。
array和&array都是指针,但类型不同。array的类型是int*,而&array的类型是int(*)[2]。array是指向普通int类型的指针;&array是数组指针,该数组元素是int类型的,且数组大小是2。
[笔记][C语言]解决VS 2017下“*”乘法符号变成指针标识符的解决方法
问题描述:
今天在Coding的时候,编写到了如下的一段代码
#include <stdio.h> #define PI 3.14 int CircleRing(int r){ return PI*r*r; }
然后VS的语法检测器就抽风了,硬是把PI*r这个线性运算的公式,误认成PI和指针变量r了。在通过上网查阅资料后,暂无比较官方的解决办法后,发现了可以暂时解决这个问题的写法。
解决办法:
int CircleRing(int r){ return r*r*PI; }
即可完美解决误认的错误,继续编译操作。
小结:
目前已知该bug仅仅是会出现在VS 2017上。在Devc++上,按照原写法是可以正常编译并且运行的。目测可能是vs的语法检测器出现了玄学bug。若有dalao看见这篇文章,知道应该怎么更好的解决这个bug,欢迎留言,我也会及时更新到这篇博文中,方便大家的。
C语言高精度计算
高精度乘法
#include "pch.h" #include <iostream> #include <stdlib.h> int main() { char n1[1500], n2[1500]; int a[1500] = {'\0'}; int b[1500] = {'\0'}; int c[3000] = {0}; int m, n, i, j, o; printf("请输入被乘数:\n"); scanf_s("%s",&n1,128); m = strlen(n1); printf("请输入乘数:\n"); scanf_s("%s",&n2,128); n = strlen(n2); if(m>n){o = m;}else{o = n;} //将char类型的元素转换成int类型 for (i = 0, j = m - 1; i < m; i++, j--) { a[i] = n1[j] - '0'; } //将char类型的元素转换成int类型 for (i = 0, j = n - 1; i < n; i++, j--) { b[i] = n2[j] - '0'; } //用数组a的每一位跟数组b进行乘法操作 for (i = 0; i < m;i++) { for (j = 0; j < n; j++) { c[i + j] = c[i+j]+(a[i] * b[j]); } } //处理进位 for (i = 0; i < m + n; i++) { if (c[i] >= 10) {//若该位大于10则向前进该处元素的十位数 c[i + 1] = c[i+1] + c[i] / 10;//20=>2,10=>1 c[i] = c[i] % 10;//取个位数 } } //由于存储c时是逆序存储,所以要再次逆序输出 for (i = o-1; i >=0;i--) { printf("%d",c[i]); } printf("\n"); system("pause"); }
高精度加法
#include "pch.h" #include <iostream> #include <stdlib.h> int main() { char n1[1500], n2[1500]; int a[1500] = {'\0'}; int b[1500] = {'\0'}; int c[3000] = {0}; int m, n, i, j,o; printf("请输入被加数:\n"); scanf_s("%s",&amp;n1,128); m = strlen(n1); printf("请输入加数:\n"); scanf_s("%s",&amp;n2,128); n = strlen(n2); for (i = 0, j = m - 1; i &lt; m; i++, j--) { a[i] = n1[j]-'0' ; } for (i = 0, j = n - 1; i &lt; n; i++, j--) { b[i] = n2[j]-'0' ; } if (m &gt; n) { o = m; } else { o = n; } for (i = 0; i &lt; o;i++) { c[i] = c[i]+(a[i] + b[i]); } for (i = 0; i &lt; o; i++) { if (c[i] &gt;= 10) { c[i + 1] =c[i+1]+( c[i] / 10); c[i] = c[i] % 10; } } for (i = o-1; i &gt;=0;i--) { printf("%d",c[i]); } printf("\n"); system("pause"); }
高精度减法
#include "pch.h" #include <iostream> #include <stdlib.h> int main() { char n1[1500], n2[1500]; int a[1500] = { '\0' }; int b[1500] = { '\0' }; int c[3000] = { 0 }; int m, n, i, j, o,flag=0; printf("请输入被减数:\n"); scanf_s("%s", &amp;n1, 128); m = strlen(n1); printf("请输入减数:\n"); scanf_s("%s", &amp;n2, 128); n = strlen(n2); for (i = 0, j = m - 1; i &lt; m; i++, j--) { a[i] = n1[j] - '0'; } for (i = 0, j = n - 1; i &lt; n; i++, j--) { b[i] = n2[j] - '0'; } if (m &gt; n) { o = m; } else { o = n; } for (i = 0; i &lt; o; i++) { c[i] = c[i] + (a[i] - b[i]); } for (i = 0; i &lt; o; i++) { if (c[i] &lt; 0 &amp;&amp; flag != 1) { flag = 1; }//记录正负号 if (c[i] &lt; 0 &amp;&amp; a[i] == 0) { c[i + 1] = c[i + 1] - 1; c[i] = 10 - b[i]; } if (b[i] == 0 &amp;&amp; c[i] &gt; 0) { c[i] = 10 - a[i]; if (c[i + 1] &gt; 0) { c[i + 1] = c[i + 1] - 1; } else { c[i + 1] = c[i + 1] + 1; } } if (c[i] &lt; 0) { c[i] = -1 * c[i]; } } if (flag == 1) { printf("-"); } for (i = o-1; i &gt;=0;i--) { printf("%d",c[i]); } printf("\n"); system("pause"); }
高精度除低精度
#include "pch.h" #include <iostream> #include <stdlib.h> int main() { char n1[1500]; int n2; double a[3000] = { '\0' }, b[3000] = { 0 }, c = 0; int m, n, i, j, o,flag=0; printf("请输入被除数:\n"); scanf_s("%s", &amp;amp;n1, 128); m = strlen(n1); printf("请输入除数:\n"); scanf_s("%d", &amp;amp;n2, 128); if (n2 == 0) { printf("除数不可为0\n"); system("pause"); exit(0); } for (i = 0, j = m - 1; i &amp;lt; m; i++, j--) { a[i] = n1[j] - '0'; } for (i = 0,j=0; i &amp;lt; m;i++,j++) { b[i] = b[i] + (a[i] / n2); for (o=j; o&amp;gt;0; o--) { b[i] = b[i] * 10; } } for (i = 0; i&amp;lt;m; i++) { c = c + b[i]; } printf("%lf",c); printf("\n"); system("pause"); }
原理:使用被除数的每一位进行除法运算,并将最终结果sum起来
记0x0FDFE224 (ucrtbased.dll)处(位于.exe 中)引发的异常BUG的解决办法
0x0FDFE224 (ucrtbased.dll)处(位于.exe 中)引发的异常: 0xC0000005: 写入位置 0x01100000 时发生访问冲突。
原代码:
scanf_s("%s",&a)
出现该报错时,是因为启用了scanf_s时没有填写第三参数
解决该bug的办法:
scanf_s("%s",&a,128)
PS:第三参数指的是最多可读取的字符数