LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-03-2016, 03:12 PM   #1
Kausinator
LQ Newbie
 
Registered: Aug 2016
Posts: 5

Rep: Reputation: Disabled
A question about C


Hello,

First of all, I'm not sure if this is the right section (Or even forum) to post this question. But since you guys look pretty helpful and good people I decided to try my luck here. I assume it's a simple question so the answer should be pretty straight forward too.

I've recently started learning C using as a reference a book called "The C Programming Language" by Ritchie and Kernighan. This book has some exercises at the end of each chapter and to help myself and practice, I coded a simple program that gives me the integer value of each character on a table. Here is the code:

Code:
#include <stdio.h>

main(){

	int c, d;
	
	#define START 32
	#define END 128
	#define COLNUM 5


	c = START;
	d = 1;
	while ( (c) <= END){
		while ( d <= COLNUM && c <= END){
			printf("%d\t", putchar(c));
			++d;
			++c;
		}
		printf("\n");
		d = 1;
	}
}

Now here is the question: When I run the code on the command line the character appears before the number why is that? Why does it appear before and not after? I understand this might sound like a dumb question but I would really like to understand

Thanks in advance
 
Old 08-03-2016, 03:53 PM   #2
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
It's been a long time since I coded c, but your printf is what is doing what you told it to do.

printf('%d\t%s', d, putchar(c));

Is probably more along the lines of what you're after? Really rusty on my %* meanings so I could be way off.
 
Old 08-03-2016, 04:12 PM   #3
Michael Uplawski
Senior Member
 
Registered: Dec 2015
Posts: 1,621
Blog Entries: 40

Rep: Reputation: Disabled
Quote:
Originally Posted by Kausinator View Post
Now here is the question: When I run the code on the command line the character appears before the number why is that?
In the call to printf() you use as second argument the return value from another function-call, to putchar(). That is about the whole answer... Because: To have the value returned by putchar(), putchar() must have been executed first. So what happens is this:

1. putchar() does what it is best at and prints out the given value as unsigned char. In the end, it returns the int-value of the same character.
2. printf() prints this return-value formatted as you asked for.

Quote:
I understand this might sound like a dumb question but I would really like to understand
Not a dumb question at all. But the man-pages could help you understand both functions better. These phenomena appear to be typical for the first few attempts with printf() or other functions from that category, maybe all those which use format-strings. I would not call this a “side-effect”, but maybe others do.

Last edited by Michael Uplawski; 08-03-2016 at 04:16 PM.
 
1 members found this post helpful.
Old 08-03-2016, 07:25 PM   #4
Kausinator
LQ Newbie
 
Registered: Aug 2016
Posts: 5

Original Poster
Rep: Reputation: Disabled
Thank you guys for your time answering my question. A special thanks to Michael Uplawski because the explanation really made me understand what goes behind the function printf()

Now it all makes sense in my head : D
The %d is asking for a value to the argument, which in this case is a function, so it will run the function first before giving it a value... And since the function putchar() also prints a char to the screen it will appear before the integer,

Man, this is fun : D
 
Old 08-03-2016, 10:56 PM   #5
Shadow_7
Senior Member
 
Registered: Feb 2003
Distribution: debian
Posts: 4,137
Blog Entries: 1

Rep: Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874Reputation: 874
Like I said, rusty.

Code:
#include <stdio.h>

int main(){
  int c, d;
  #define START 32
  #define END 128
  #define COLNUM 5
  c = START;
  d = 1;
  while ( (c) <= END ) {
    while ( d <= COLNUM && c <= END ) {
//      printf("%d\t", putchar(c));
      printf("%d\t", c);
      putchar(c);
      printf("\t");
      d++;
      c++;
    }
    printf("\n");
    d = 1;
  }
  return 0;
}
Probably more along the lines of what you wanted. Although probably not the most efficient way.
 
Old 08-04-2016, 06:14 AM   #6
Michael Uplawski
Senior Member
 
Registered: Dec 2015
Posts: 1,621
Blog Entries: 40

Rep: Reputation: Disabled
Edit: Works now.
Code:
#include <stdio.h>

int main(int argc, char** argv) {
	unsigned col = 0;
	for(int i = 32; i < 128; ++i) {
		if (++col < 5) {
			printf("%3i - %c\t", i, i);	
		}	
		else { 
                        col = 0;
			printf("\n");
		}
	}
	return 0;
}
Improvements:
* Constants are superfluous.
* Format-string imposes a right-aligned field of fixed width for the integer.
* Incrementation is defined in the head of the loop.
(* discipline is bad, automatisms are rarely bad, int main(int argc, argv** char) is always right)

Last edited by Michael Uplawski; 08-04-2016 at 10:10 AM. Reason: You shall try the code that you wish to publish, before you do.
 
Old 08-04-2016, 08:20 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
Perhaps range 32..126 would be even better as 0..31 and 127 aren't printable.
 
Old 08-04-2016, 08:58 AM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939Reputation: 3939
Quote:
Originally Posted by Kausinator View Post
Thank you guys for your time answering my question. A special thanks to Michael Uplawski because the explanation really made me understand what goes behind the function printf()

Now it all makes sense in my head
The %d is asking for a value to the argument, which in this case is a function, so it will run the function first before giving it a value... And since the function putchar() also prints a char to the screen it will appear before the integer,

Man, this is fun
It sure is!

Now, just to be clear, the printf() function takes a variable number of arguments, the first of which is a "format string" that, among other things, tells printf() how many arguments to expect and what sort of data they must be. (The function is utterly trusting on this point, and the program will crash if the format-string and the arguments don't agree.

Before any function can be executed, all of its arguments must be evaluated. If any of these are functions, they are called, and their result is used. If those functions happen to do something ("side effects"), as putchar() does, then those side-effects will take place as a result of the function being called. And they will necessarily occur before the function for which they are a parameter is called, because they're being called in order to obtain their result.

The programming language simply assumes that you know what you are intending to do.

Last edited by sundialsvcs; 08-04-2016 at 09:00 AM.
 
Old 08-04-2016, 10:07 AM   #9
Michael Uplawski
Senior Member
 
Registered: Dec 2015
Posts: 1,621
Blog Entries: 40

Rep: Reputation: Disabled
Quote:
Originally Posted by NevemTeve View Post
Perhaps range 32..126 would be even better as 0..31 and 127 aren't printable.
You are right, but if you want a reminder together with the other values, the best is to include them in the output.
 
Old 08-04-2016, 10:37 AM   #10
Michael Uplawski
Senior Member
 
Registered: Dec 2015
Posts: 1,621
Blog Entries: 40

Rep: Reputation: Disabled
Why I like Ruby.
Code:
col = 0;
(32..128).each do |c|
	print "%3i - %s\t" %[c, c.chr]
	col < 5 ? col += 1 : col = 0;
	puts if col == 0
end
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] GPL question (Version 2, June 1991) - physical media availability question LicenseQuestions Linux - Newbie 1 12-01-2012 06:34 PM
basic html question - download link to files on my webpage question Davno Linux - Server 5 12-25-2009 07:24 AM
linux distro question & mysql install question natalie.aloi Linux - Newbie 5 07-19-2009 08:28 PM
Question, Apples Contribution to Open Source + MacOs file structure question Higgy3k Other *NIX 5 07-25-2005 04:23 AM
login prompt question & kde scheme question JustinCoyan Slackware 2 06-09-2004 02:02 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration