-2

So I am trying to create my first program, and I got stuck. Basically, what I am trying to do is to create an array which includes strings/chars and integers, and from that I would like the program to randomly print any of its liking out.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {    
    srand(time(NULL));

    int *test[] = { 1, 2, 3, 444, 5, 'Hi', 7 };

    int i;
    int j;

    for (j = 0; j < 7; j++) {
        printf("%d\n", rand(*test));
    }
    return(0);
}

For some reason this isn't working properly, because I get the output of 22997, 17678, etc.

My second problem is the other part of my code. I'm trying to print the whole array, and I want it to be printed out as both characters and integers.

for (i = 0; i < 7; i++) {
    printf("\n%d\n", test[i]);
}

Here I get all the integers, but the string "Hi" I get in ASCII value. Is there some way that you can include both integers and characters in an array and print it out in the same loop? Also, how is it that I can just use a short string in this array, but I can't use something like "HelloTherefriend"?

Would appreciate some clarity here as it would help me a lot!

tryingsohard
  • 59
  • 1
  • 3
  • `int *test[] = { 1, 2, 3, 444, 5, 'Hi', 7 };` - this is not a valid C at all. – artm Dec 12 '15 at 23:20
  • 1
    Compare http://stackoverflow.com/questions/3960954/c-multicharacter-literal. `'Hi'` is a multi character literal. Its type is `int` and the value is implementation defined. – Martin R Dec 12 '15 at 23:27
  • What does `rand` return? What argument does it take? Use C99 or C11 mode; Your compiler should warn. – too honest for this site Dec 12 '15 at 23:30
  • 1
    @MartinR: the OP stumbled upon multicharacter literals by chance. These are indeed non portable. They should have been removed from the standard 2 decades ago. Hardly anyone uses them. One more landmine for newbie programmers... – chqrlie Dec 12 '15 at 23:32
  • 2
    You initialise an array of pointer with integers. Doesn't that already sound odd? – too honest for this site Dec 12 '15 at 23:33
  • 4
    Please consult a C book. You have some fundamental fault in you code which show basic missunderstanding. No offence. – too honest for this site Dec 12 '15 at 23:36
  • 1
    @artm Yes, it is valid C, just not necessarily great C. just like `char x = 'H'` or `int x = 'H'`. You can have `short x = 'Hi'` and `int x = 'High'`. The compiler will warn about it a multichar literal but it will compile. The results may be considered UB because you don't know the arch endianness. With 'Hi' on little endian, %c will give 'i' and big endian would give 'H' – Craig Estey Dec 12 '15 at 23:36
  • @CraigEstey: `int` is not guaranteed to have 32 bits, nor are both guaranteed to hold more than one character. While the latter is not vry common today, the first still is. – too honest for this site Dec 12 '15 at 23:38
  • @Olaf you'll still get the same results even if int were 16 on little endian--you get 'h'. The scanning is just like for numbers: you get the value modulo the containing size. And int has been 16+ bits on any arch in existence. And, even if you could find one where it's 8 bits, `int x = 'abcd'` yields 'd' [LE] – Craig Estey Dec 12 '15 at 23:52
  • @CraigEstey: Yes, but `char` does not necessarily have 8 bits. So `sizeof(int) == 1` is very well possible (and used). And `int` cannot have less than 16 bits by the standard. However, the mapping is implementation defined, so it could also shuffle the bits. It just has to define the algorithm. – too honest for this site Dec 12 '15 at 23:55
  • @CraigEstey: The value is not necessarily determined by the endianess. The last time that I tested it, `'1234'` evaluated to `0x31323334` with gcc on both PPC and Intel platform. (But that is some years ago and there is no PPC anymore.) – Martin R Dec 13 '15 at 00:01
  • 2
    @Olaf posix mandates char at 8 bits. So, no printf et. al. if not [and no posix OS]. Seriously, it's time to drop support for [and consideration of] silly arches like some TI DSPs [just like it's silly to continue to talk about 50's era 6 bit byte arches]. – Craig Estey Dec 13 '15 at 00:02
  • @CraigEstey: The standard requires a `char` to have 8 bits at least anyway. However, as C is meant to be used for variaous platforms and especially for embedded, it would be a very bad idea to drop DSPs (there is not only TI, btw.), MCUs and other targets, for instance specialised sequencing processors, just as you might not use them anymore. I'm quite happy the need to programm those all-assembler is diminishing. – too honest for this site Dec 13 '15 at 00:12
  • @MartinR I do believe I covered that with LE. But, that's interesting news. If 'abcdefghi' always generates `int x = 'fghi'`, regardless of endian, then a multichar isn't UB at all--just not terribly useful in most cases [but in some rare ones]. Now that I think about it, I did say that it works modulo the size, so that would be the same. just like `int x = 0x01020204050607` is `int x = 0x04050607`. That means that 'Hi' always prints 'i' with %c – Craig Estey Dec 13 '15 at 00:12
  • @CraigEstey: I forgot to add that I also got `'1234' == 0x34333231` on other platforms... – Martin R Dec 13 '15 at 00:20
  • @Olaf On another forum a few years, I once said char was at least 8 bits and the other guy was going on about the 6 bit thing [and citing that the standard made no such claim about 8 bit minimum]. As to TI, yes, you can probably have a C port, just no posix support. So, that's fine. But, IMO, something like that is more easily programmed in asm. And if you need absolute _control_ of speed (e.g. one outer loop must take exactly X cpu cycles--not 1 cycle more nor 1 cycle less) as you do for certain R/T apps (e.g. R/T video compression), you can only use asm – Craig Estey Dec 13 '15 at 00:23
  • @MartinR What about '12345678' [which gets trunc'ed to 4 bytes]? I don't have [easy] access to a BE environment – Craig Estey Dec 13 '15 at 00:25
  • @CraigEstey: As an embedded systems engineer, I do not really care about POSIX (on Linux I use Python, as I do not have speed problems there). And I'm also open to some gcc extensions (but not of proprietary compilers). But the guy should have read the standard: The required limits for `char` simply leave no room for less than 8 bits. ... – too honest for this site Dec 13 '15 at 00:32
  • @CraigEstey: ... But a clear NO to "programming in Assembler is easier". Did you ever write more than trivial code (e.g. blink an LED) for a MCU or DSP? Try and we come back to this. Even for PIC, etc. C is most times the better choice - at least for middleware and upwards, very often for drivers, too. And for realtime: if you start counting CPU cycles you did something wrong. Use interrupts and timers, etc. Or a dedicated hardware codec. Even iff you need to write some assembler, you forget about the `>>95%` rest of the code. – too honest for this site Dec 13 '15 at 00:34
  • @Olaf I'm a computer engineer [H/W and S/W], and yes, I've worked on multiuser OSes written 100% in asm. I also do embedded. And, by PIC, do you mean PIC18F et. al.? If you find asm _that_ difficult, IMO, you just never did enough of it to reach expert skill level. (e.g.) how do you create a stack for an arch that has none, but has regs? well, create your own with macros. with macros, you can create a very productive asm environment. You being an embedded guy, I'm surprised you're taking up an LL position here--you of all people should know that sometimes the dirty way is the clean way – Craig Estey Dec 13 '15 at 00:51
  • @CraigEstey: In the 80ies/90ies, I also wrote RT applications in assembler for 68k, 6502, Z80, HC11, HC08, PIC, ARM, some own CPU cores (FPGAs), etc. I just stopped joining p**ing contests some decades ago. But tempora mutantur, ... ; I'm quite sure I know both worlds very well and on many platforms. And my clear statement is: everybody still only using Assembler on such devices - without actual need should rethink her priorities. Mine - and my customer's - are maintainability, development time (including debugging) and reliability. Performance comes with a good C compiler -get one. – too honest for this site Dec 13 '15 at 01:06
  • @CraigEstey: Please point me at where the C standard requires a stack (or a heap). – too honest for this site Dec 13 '15 at 01:06
  • About the dirty way: Tell that customers from automotive, medical and aerospace. I don't work for garage companies anymore. Hard enough to make my customers clear I work faster without UML, C++ and their so favoured full-size IDEs and stick with editor, gcc, gdb, etc. Until they see what they get. – too honest for this site Dec 13 '15 at 01:08
  • regarding this expression: `rand(*test)` the `rand()` function does not take a parameter, it returns a positive integer in the range 0...MAX_RAND. To get a value in a limited range, need a expression similar to: `rand() % maxDesiredValue` which will return 0...(maxDesiredValue-1) so to get a value from 1...maxDesiredValue, use: `1+ rand() % maxDesiredValue` – user3629249 Dec 13 '15 at 02:32
  • @Olaf I never said C std requires a stack. I just said that if an arch had none (e.g. no push/pop insts), you could create them with asm macros. But, C does require a stack indirectly [5.2.4.1] requires 127+ function arguments--which implies stack on most arches. And, by dirty, I mean you may need a line or two here and there [with copious comments]. Consider the float sqrt function developed by John Carmack that uses no floating point--that's "dirty" but it's _fast_, which it was used and is _still_ used today. And, I also avoid C++/IDE/etc. fufu ... – Craig Estey Dec 13 '15 at 04:20
  • @Olaf I program mostly in C [since '81] [and perl] and only use [frags of] asm where necessary. But, some arches like the cell [processor] SPE don't map well to C. And, even if you could, the asm version would probably be better. And, the early stages of boot roms. And, some x86 XMM sequences [the intel intrinsic fncs don't cut it in all cases]. Or, microcode. Or MIMD arches. Right tool for the right job. And the "X cycles" example [not mine] used perl to generate asm insts [metaprogramming] because cycle count had to be exact because it had to work against special H/W. – Craig Estey Dec 13 '15 at 04:33
  • @CraigEstey: A proper build toolchain can very well allocate automatic variables in the global space. I had that e.g. optional on a HC08. Restriction was not to use recursion, of course, but it worked perfectly (it did a static call-tree analysis to optimize the layout). And you can very well use other approaches, e.g. heap-style allocated blocks. But that goes too far. Your example of a `float` function is not relevant for this discussion, as you are not required to provide any of the standard libraries for a valid implementation of the standard. Just provide a _freestanding environment. – too honest for this site Dec 13 '15 at 15:56
  • @CraigEstey: C and the compilers have evolved very much the last years. Just have a look at the generated code and you might see this cannot be done better by hand - in acceptable time (yes, I also know compilers which are counter-examples; mostly commercial embedded). I'll leave it at that, but just one thing: You should be careful who you tell he does not know Assembler or machine language. I've written enough code at **all** levels, including VHDL and adding hardware-design in general. – too honest for this site Dec 13 '15 at 16:01

1 Answers1

4

You cannot mix different types in a C array the way you did it. Arrays can only hold values of the same type. You could try a solution with unions, but it is probably beyond your skill level. Better change your approach. Try this:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {    
    const char *test[] = { "1", "2", "3", "444", "5", "Hi", "7" };
    int i, j;

    srand(time(NULL));

    for (j = 0; j < 7; j++) {
        if (isdigit((unsigned char)*test[i]))
            printf("%d\n", rand() % atoi(test[j]));
        else
            printf("%s\n", test[i]);
    }
    return 0;  // no need for parentheses here
}

Be aware than rand does not actually take any arguments.

chqrlie
  • 131,814
  • 10
  • 121
  • 189