[笔记]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;amp;n1,128);
	m = strlen(n1);
	printf("请输入加数:\n");
	scanf_s("%s",&amp;amp;n2,128);
	n = strlen(n2);
	for (i = 0, j = m - 1; i &amp;lt; m; i++, j--) {
		a[i] = n1[j]-'0' ;
	}
	for (i = 0, j = n - 1; i &amp;lt; n; i++, j--) { b[i] = n2[j]-'0' ; } if (m &amp;gt; n) { o = m; }
	else { o = n; }
	for (i = 0; i &amp;lt; o;i++) {
			c[i] = c[i]+(a[i] + b[i]);
	}
	for (i = 0; i &amp;lt; o; i++) { if (c[i] &amp;gt;= 10) {
			c[i + 1] =c[i+1]+( c[i] / 10);
			c[i] = c[i] % 10;
		}
}
	for (i = o-1; i &amp;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;amp;n1, 128);
	m = strlen(n1);
	printf("请输入减数:\n");
	scanf_s("%s", &amp;amp;n2, 128);
	n = strlen(n2);
	for (i = 0, j = m - 1; i &amp;lt; m; i++, j--) {
		a[i] = n1[j] - '0';
	}
	for (i = 0, j = n - 1; i &amp;lt; n; i++, j--) { b[i] = n2[j] - '0'; } if (m &amp;gt; n) { o = m; }
	else { o = n; }
	for (i = 0; i &amp;lt; o; i++) {
		c[i] = c[i] + (a[i] - b[i]);
	}
	for (i = 0; i &amp;lt; o; i++) {
		if (c[i] &amp;lt; 0 &amp;amp;&amp;amp; flag != 1) { flag = 1; }//记录正负号
		if (c[i] &amp;lt; 0 &amp;amp;&amp;amp; a[i] == 0) { c[i + 1] = c[i + 1] - 1; c[i] = 10 - b[i]; } if (b[i] == 0 &amp;amp;&amp;amp; c[i] &amp;gt; 0) {
			c[i] = 10 - a[i];
			if (c[i + 1] &amp;gt; 0) { c[i + 1] = c[i + 1] - 1; }
			else {
				c[i + 1] = c[i + 1] + 1;
			}
		}
		if (c[i] &amp;lt; 0) { c[i] = -1 * c[i]; } } if (flag == 1) { printf("-"); } for (i = o-1; i &amp;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;amp;n1, 128);
	m = strlen(n1);
	printf("请输入除数:\n");
	scanf_s("%d", &amp;amp;amp;n2, 128);
	if (n2 == 0) { printf("除数不可为0\n"); system("pause"); exit(0); }
	for (i = 0, j = m - 1; i &amp;amp;lt; m; i++, j--) {
		a[i] = n1[j] - '0';
	}
	for (i = 0,j=0; i &amp;amp;lt; m;i++,j++) { b[i] = b[i] + (a[i] / n2); for (o=j; o&amp;amp;gt;0; o--) {
			b[i] = b[i] * 10;
		}
	}
	for (i = 0; i&amp;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:第三参数指的是最多可读取的字符数